From 47ec22a50975d6f616043fc12424ae1e12e584bd Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 14 Oct 2014 16:55:17 +0200 Subject: [PATCH 01/69] Allow panels outside of availableGeometry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Panels windows are usually outside QScreen::availableGeometry, because they will usually set extended struts to reserve the screen area for themselves, but their own screen() must remain the one in which they are. This cause one downstream behavior to KDE https://bugs.kde.org/show_bug.cgi?id=339846 in which a panel got by mistake few pixels on another screen, and was immediately reassigned to that screen, because its geometry was intersecting the new screen availableGeometry() but not the geometry of its own screen, because itself reserved its own geometry away from availableGeometry() Change-Id: If6c9defdef62732473687dd336dbcec582bd0ea2 Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 586068d8d9..a99a5cfab5 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1687,9 +1687,9 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); - if (!m_screen->availableGeometry().intersects(rect)) { + if (!m_screen->geometry().intersects(rect)) { Q_FOREACH (QPlatformScreen* screen, m_screen->virtualSiblings()) { - if (screen->availableGeometry().intersects(rect)) { + if (screen->geometry().intersects(rect)) { m_screen = static_cast(screen); QWindowSystemInterface::handleWindowScreenChanged(window(), m_screen->QPlatformScreen::screen()); break; From 2b9a793dcd7a4abcad29c817eb92443a325e789b Mon Sep 17 00:00:00 2001 From: Raphael Kubo da Costa Date: Sat, 1 Nov 2014 22:27:56 +0200 Subject: [PATCH 02/69] Set the _C variants of QMAKE_LINK and QMAKE_LINK_SHLIB in clang.conf. While it does not look like the clang-based mkspecs had any problems so far with not having QMAKE_LINK_C and QMAKE_LINK_C_SHLIB defined, it makes sense to set them to $$QMAKE_CC just like the GCC-based ones so CONFIG=use_c_linker works as expected. Change-Id: Ib660d12b001dd7a877b6f03e79715db08a272968 Reviewed-by: Gabriel de Dietrich Reviewed-by: Oswald Buddenhagen --- mkspecs/common/clang.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index d58b44b295..d6418b54b3 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -7,6 +7,9 @@ QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc QMAKE_CC = clang QMAKE_CXX = clang++ +QMAKE_LINK_C = $$QMAKE_CC +QMAKE_LINK_C_SHLIB = $$QMAKE_CC + QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX From cfa73537cc6a3687566094442cf15771f01ef431 Mon Sep 17 00:00:00 2001 From: Raphael Kubo da Costa Date: Sat, 1 Nov 2014 17:57:41 +0200 Subject: [PATCH 03/69] Stop including g++-unix.conf in the freebsd-clang mkspec. Most of the settings there end up overwritten by the clang.conf include that comes afterwards, except for a few things such as QMAKE_LINK_C, which remains set to "gcc" and breaks things when one uses CONFIG=use_c_linker. QMAKE_LFLAGS_NOUNDEF was coming from g++-unix.conf, though, so we now manually set it in freebsd-clang's qmake.conf. Change-Id: Ibd16f59d43eb19e72adf4919da9ce3007100b60f Reviewed-by: Gabriel de Dietrich Reviewed-by: Oswald Buddenhagen --- mkspecs/unsupported/freebsd-clang/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/unsupported/freebsd-clang/qmake.conf b/mkspecs/unsupported/freebsd-clang/qmake.conf index ad4fa3487e..2cfd763688 100644 --- a/mkspecs/unsupported/freebsd-clang/qmake.conf +++ b/mkspecs/unsupported/freebsd-clang/qmake.conf @@ -13,6 +13,7 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = /usr/local/include QMAKE_LIBDIR = /usr/local/lib +QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined QMAKE_LFLAGS_THREAD = -pthread QMAKE_LIBS = @@ -28,6 +29,5 @@ QMAKE_RANLIB = include(../../common/unix.conf) include(../../common/gcc-base-unix.conf) -include(../../common/g++-unix.conf) include(../../common/clang.conf) load(qt_config) From b7d36614e9f00a3376dd19493eaf3ffc4ec431da Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 30 Oct 2014 20:18:48 +0100 Subject: [PATCH 04/69] Remove incorrect execute file permissions from source files Amends commit 9c3a58a913a7e59359146264ee59d40d703d4db2. Change-Id: I292eb9df480a642a65f9065e4fe36bd52c093dc7 Reviewed-by: Oswald Buddenhagen --- tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro | 0 tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro mode change 100755 => 100644 tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp diff --git a/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro b/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro old mode 100755 new mode 100644 diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp old mode 100755 new mode 100644 From 54d4fb4f500dfb45d86b2046b90becd55783e48e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 30 Sep 2014 09:52:51 +0200 Subject: [PATCH 05/69] Fix QString::sprintf documentation QString::sprintf does actually support all length modifiers, including %lld. The format string is also parsed as UTF-8. What's worthwile to mention, though, is that %lc and %ls is at odds with the standard, since wchar_t isn't necessarily 16 bits wide. Change-Id: I30cd22ec5b42035824dd98e3cdcc79d7adcc953a Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira --- src/corelib/doc/snippets/qstring/main.cpp | 8 -------- src/corelib/tools/qstring.cpp | 25 ++++++++++------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp index bf45a31c29..f49c4dd359 100644 --- a/src/corelib/doc/snippets/qstring/main.cpp +++ b/src/corelib/doc/snippets/qstring/main.cpp @@ -760,14 +760,6 @@ void Widget::splitCaseSensitiveFunction() void Widget::sprintfFunction() { - //! [63] - size_t BufSize; - char buf[BufSize]; - - ::snprintf(buf, BufSize, "%lld", 123456789LL); - QString str = QString::fromUtf8(buf); - //! [63] - //! [64] QString result; QTextStream(&result) << "pi = " << 3.14; diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 3b18d31547..7d0607a2f7 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5692,21 +5692,18 @@ QString QString::toUpper() const Safely builds a formatted string from the format string \a cformat and an arbitrary list of arguments. - The %lc escape sequence expects a unicode character of type ushort - (as returned by QChar::unicode()). The %ls escape sequence expects - a pointer to a zero-terminated array of unicode characters of type - ushort (as returned by QString::utf16()). + The format string supports the conversion specifiers, length modifiers, + and flags provided by printf() in the standard C++ library. The \a cformat + string and \c{%s} arguments must be UTF-8 encoded. - \note This function expects a UTF-8 string for %s and Latin-1 for - the format string. - - The format string supports most of the conversion specifiers - provided by printf() in the standard C++ library. It doesn't - honor the length modifiers (e.g. \c h for \c short, \c ll for - \c{long long}). If you need those, use the standard snprintf() - function instead: - - \snippet qstring/main.cpp 63 + \note The \c{%lc} escape sequence expects a unicode character of type + \c char16_t, or \c ushort (as returned by QChar::unicode()). + The \c{%ls} escape sequence expects a pointer to a zero-terminated array + of unicode characters of type \c char16_t, or ushort (as returned by + QString::utf16()). This is at odds with the printf() in the standard C++ + library, which defines \c {%lc} to print a wchar_t and \c{%ls} to print + a \c{wchar_t*}, and might also produce compiler warnings on platforms + where the size of \c {wchar_t} is not 16 bits. \warning We do not recommend using QString::sprintf() in new Qt code. Instead, consider using QTextStream or arg(), both of From 6a2bdc4ee2dc49b5d89d09a1f255a7a0e2f18acf Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Oct 2014 17:23:09 -0700 Subject: [PATCH 06/69] Always lock the DBus dispatcher before dbus_connection_send* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We lock it before dbus_connection_send_with_reply (the async version) in QDBusConnectionPrivate::sendWithReplyAsync. We weren't locking it before send_with_reply_and_block and we apparently should. The locking around the dbus_connection_send function might not be necessary, but let's do it to be safe. The lock now needs to be recursive because we may be inside QDBusConnectionPrivate::doDispatch. Task-number: QTBUG-42189 Change-Id: I7b6b350909359817ea8b3f9c693bced042c9779a Reviewed-by: Jędrzej Nowacki Reviewed-by: Frederik Gladhorn --- src/dbus/qdbusintegrator.cpp | 19 +++++++++++++++---- src/dbus/qdbusthreaddebug_p.h | 3 +++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 499e9dbd82..b2f6635d1b 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1017,7 +1017,7 @@ extern bool qDBusInitThreads(); QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) : QObject(p), ref(1), capabilities(0), mode(InvalidMode), connection(0), server(0), busService(0), - watchAndTimeoutLock(QMutex::Recursive), + watchAndTimeoutLock(QMutex::Recursive), dispatchLock(QMutex::Recursive), rootNode(QString(QLatin1Char('/'))), anonymousAuthenticationAllowed(false) { @@ -1266,7 +1266,10 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in //qDBusDebug() << "Emitting signal" << message; //qDBusDebug() << "for paths:"; q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything - huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor); + { + QDBusDispatchLocker locker(HuntAndEmitAction, this); + huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor); + } q_dbus_message_unref(msg); } @@ -1923,7 +1926,11 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message) qDBusDebug() << this << "sending message (no reply):" << message; checkThread(); - bool isOk = q_dbus_connection_send(connection, msg, 0); + bool isOk; + { + QDBusDispatchLocker locker(SendMessageAction, this); + isOk = q_dbus_connection_send(connection, msg, 0); + } int serial = 0; if (isOk) serial = q_dbus_message_get_serial(msg); @@ -1955,7 +1962,11 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, qDBusDebug() << this << "sending message (blocking):" << message; QDBusErrorInternal error; - DBusMessage *reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error); + DBusMessage *reply; + { + QDBusDispatchLocker locker(SendWithReplyAndBlockAction, this); + reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error); + } q_dbus_message_unref(msg); diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h index f9039ef3cd..dcde99169c 100644 --- a/src/dbus/qdbusthreaddebug_p.h +++ b/src/dbus/qdbusthreaddebug_p.h @@ -94,6 +94,9 @@ enum ThreadAction { MessageResultReceivedAction = 26, ActivateSignalAction = 27, PendingCallBlockAction = 28, + SendMessageAction = 29, + SendWithReplyAndBlockAction = 30, + HuntAndEmitAction = 31, AddTimeoutAction = 50, RealAddTimeoutAction = 51, From eb99c28861f5e841f306cfe8689627fe0e9bf2e8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Oct 2014 19:26:17 -0700 Subject: [PATCH 07/69] QDBusConnection: Merge the dispatch and the watch-and-timeout locks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need two anymore because they now protect the same thing: the state of the DBusConnection. The difference existed when it was possible for two threads to access the DBusConnection at the same time: one doing dispatching and one doing something else. Unfortunately, even though DBusConnection supports this, QtDBus doesn't. From d47c05b1889bb4f06203bbc65f4660b8d0128954 (2008-10-08): Details: if we're removing a timer or a watcher from our list, there's a race condition: one thread (not the QDBusConnection thread) could be asking for the removal (which causes an event to be sent), then deletes the pointer. In the meantime, QDBusConnection will process the timers and socket notifiers and could end up calling lidbus-1 with deleted pointers. That commit fixed the race condition but introduced a deadlock. Task-number: QTBUG-42189 Change-Id: I034038f763cbad3a67398909defd31a23c27c965 Reviewed-by: Jędrzej Nowacki Reviewed-by: Albert Astals Cid Reviewed-by: Frederik Gladhorn --- src/dbus/qdbusconnection_p.h | 18 ++++++------------ src/dbus/qdbusintegrator.cpp | 22 +++++++++++----------- src/dbus/qdbusthreaddebug_p.h | 7 ------- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index fd4ced078d..a75dabeeee 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -290,24 +290,18 @@ public: QStringList serverConnectionNames; ConnectionMode mode; - - // members accessed in unlocked mode (except for deletion) - // connection and server provide their own locking mechanisms - // busService doesn't have state to be changed - DBusConnection *connection; - DBusServer *server; QDBusConnectionInterface *busService; - // watchers and timeouts are accessed from any thread - // but the corresponding timer and QSocketNotifier must be handled - // only in the object's thread - QMutex watchAndTimeoutLock; + // the dispatch lock protects everything related to the DBusConnection or DBusServer + // including the timeouts and watches + QMutex dispatchLock; + DBusConnection *connection; + DBusServer *server; WatcherHash watchers; TimeoutHash timeouts; PendingTimeoutList timeoutsPendingAdd; - // members accessed through a lock - QMutex dispatchLock; + // the master lock protects our own internal state QReadWriteLock lock; QDBusError lastError; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index b2f6635d1b..39ab797426 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -155,7 +155,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) if (!q_dbus_timeout_get_enabled(timeout)) return true; - QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d); + QDBusDispatchLocker locker(AddTimeoutAction, d); if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) { // correct thread return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout)); @@ -190,7 +190,7 @@ static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data) QDBusConnectionPrivate *d = static_cast(data); - QDBusWatchAndTimeoutLocker locker(RemoveTimeoutAction, d); + QDBusDispatchLocker locker(RemoveTimeoutAction, d); // is it pending addition? QDBusConnectionPrivate::PendingTimeoutList::iterator pit = d->timeoutsPendingAdd.begin(); @@ -263,7 +263,7 @@ static bool qDBusRealAddWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int f { QDBusConnectionPrivate::Watcher watcher; - QDBusWatchAndTimeoutLocker locker(AddWatchAction, d); + QDBusDispatchLocker locker(AddWatchAction, d); if (flags & DBUS_WATCH_READABLE) { //qDebug("addReadWatch %d", fd); watcher.watch = watch; @@ -297,7 +297,7 @@ static void qDBusRemoveWatch(DBusWatch *watch, void *data) QDBusConnectionPrivate *d = static_cast(data); int fd = q_dbus_watch_get_unix_fd(watch); - QDBusWatchAndTimeoutLocker locker(RemoveWatchAction, d); + QDBusDispatchLocker locker(RemoveWatchAction, d); QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd); while (i != d->watchers.end() && i.key() == fd) { if (i.value().watch == watch) { @@ -341,7 +341,7 @@ static void qDBusToggleWatch(DBusWatch *watch, void *data) static void qDBusRealToggleWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int fd) { - QDBusWatchAndTimeoutLocker locker(ToggleWatchAction, d); + QDBusDispatchLocker locker(ToggleWatchAction, d); QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd); while (i != d->watchers.end() && i.key() == fd) { @@ -1016,8 +1016,8 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q extern bool qDBusInitThreads(); QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) - : QObject(p), ref(1), capabilities(0), mode(InvalidMode), connection(0), server(0), busService(0), - watchAndTimeoutLock(QMutex::Recursive), dispatchLock(QMutex::Recursive), + : QObject(p), ref(1), capabilities(0), mode(InvalidMode), busService(0), + dispatchLock(QMutex::Recursive), connection(0), server(0), rootNode(QString(QLatin1Char('/'))), anonymousAuthenticationAllowed(false) { @@ -1127,7 +1127,7 @@ bool QDBusConnectionPrivate::handleError(const QDBusErrorInternal &error) void QDBusConnectionPrivate::timerEvent(QTimerEvent *e) { { - QDBusWatchAndTimeoutLocker locker(TimerEventAction, this); + QDBusDispatchLocker locker(TimerEventAction, this); DBusTimeout *timeout = timeouts.value(e->timerId(), 0); if (timeout) q_dbus_timeout_handle(timeout); @@ -1146,7 +1146,7 @@ void QDBusConnectionPrivate::customEvent(QEvent *e) switch (ev->subtype) { case QDBusConnectionCallbackEvent::AddTimeout: { - QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this); + QDBusDispatchLocker locker(RealAddTimeoutAction, this); while (!timeoutsPendingAdd.isEmpty()) { QPair entry = timeoutsPendingAdd.takeFirst(); qDBusRealAddTimeout(this, entry.first, entry.second); @@ -1182,7 +1182,7 @@ void QDBusConnectionPrivate::socketRead(int fd) QVarLengthArray pendingWatches; { - QDBusWatchAndTimeoutLocker locker(SocketReadAction, this); + QDBusDispatchLocker locker(SocketReadAction, this); WatcherHash::ConstIterator it = watchers.constFind(fd); while (it != watchers.constEnd() && it.key() == fd) { if (it->watch && it->read && it->read->isEnabled()) @@ -1202,7 +1202,7 @@ void QDBusConnectionPrivate::socketWrite(int fd) QVarLengthArray pendingWatches; { - QDBusWatchAndTimeoutLocker locker(SocketWriteAction, this); + QDBusDispatchLocker locker(SocketWriteAction, this); WatcherHash::ConstIterator it = watchers.constFind(fd); while (it != watchers.constEnd() && it.key() == fd) { if (it->watch && it->write && it->write->isEnabled()) diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h index dcde99169c..726ab051d0 100644 --- a/src/dbus/qdbusthreaddebug_p.h +++ b/src/dbus/qdbusthreaddebug_p.h @@ -207,13 +207,6 @@ struct QDBusDispatchLocker: QDBusMutexLocker { } }; -struct QDBusWatchAndTimeoutLocker: QDBusMutexLocker -{ - inline QDBusWatchAndTimeoutLocker(ThreadAction a, QDBusConnectionPrivate *s) - : QDBusMutexLocker(a, s, &s->watchAndTimeoutLock) - { } -}; - #if QDBUS_THREAD_DEBUG # define SEM_ACQUIRE(action, sem) \ do { \ From 73a1e8c60d894701f34806cc4b847aa2814bf389 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Oct 2014 19:34:01 -0700 Subject: [PATCH 08/69] Partially revert "Fix a deadlock introduced by the race condition fix" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit was 9361be58f47ec256bf920c378479a02501219c1f (2008-11-17), referring to the race condition fix that was applied in commit d47c05b1889bb4f06203bbc65f4660b8d0128954 (2008-10-08). The fix for the deadlock reintroduced the race condition and the commit message noted it. The workaround is no longer necessary since we've fixed the original race condition differently now (see the previous two commits). Task-number: QTBUG-42189 Change-Id: I5a83249597a83c4d4caa2ae57964ad3cc61c1d70 Reviewed-by: Jędrzej Nowacki Reviewed-by: Albert Astals Cid Reviewed-by: Frederik Gladhorn --- src/dbus/qdbusintegrator.cpp | 40 +++++++++++++----------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 39ab797426..ab0aee355d 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1179,41 +1179,29 @@ void QDBusConnectionPrivate::doDispatch() void QDBusConnectionPrivate::socketRead(int fd) { - QVarLengthArray pendingWatches; - - { - QDBusDispatchLocker locker(SocketReadAction, this); - WatcherHash::ConstIterator it = watchers.constFind(fd); - while (it != watchers.constEnd() && it.key() == fd) { - if (it->watch && it->read && it->read->isEnabled()) - pendingWatches.append(it.value().watch); - ++it; + QDBusDispatchLocker locker(SocketReadAction, this); + WatcherHash::ConstIterator it = watchers.constFind(fd); + while (it != watchers.constEnd() && it.key() == fd) { + if (it->watch && it->read && it->read->isEnabled()) { + if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE)) + qDebug("OUT OF MEM"); } + ++it; } - - for (int i = 0; i < pendingWatches.size(); ++i) - if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_READABLE)) - qDebug("OUT OF MEM"); doDispatch(); } void QDBusConnectionPrivate::socketWrite(int fd) { - QVarLengthArray pendingWatches; - - { - QDBusDispatchLocker locker(SocketWriteAction, this); - WatcherHash::ConstIterator it = watchers.constFind(fd); - while (it != watchers.constEnd() && it.key() == fd) { - if (it->watch && it->write && it->write->isEnabled()) - pendingWatches.append(it.value().watch); - ++it; + QDBusDispatchLocker locker(SocketWriteAction, this); + WatcherHash::ConstIterator it = watchers.constFind(fd); + while (it != watchers.constEnd() && it.key() == fd) { + if (it->watch && it->write && it->write->isEnabled()) { + if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE)) + qDebug("OUT OF MEM"); } + ++it; } - - for (int i = 0; i < pendingWatches.size(); ++i) - if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_WRITABLE)) - qDebug("OUT OF MEM"); } void QDBusConnectionPrivate::objectDestroyed(QObject *obj) From 3d70925ee54d06e90bea392883d230b8ae2b1782 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 7 Nov 2014 11:04:49 +0200 Subject: [PATCH 09/69] direct2d: Use simple event posting to avoid event queue lock up In rare cases, the Windows event loop can be spinning inside the inner loop and the message hook is never called. This can be triggered on the Direct2D platform by opening 32+ window handles. The issue can be worked around by using the same approach Windows CE uses: don't rely on the message hook to inform the event loop that the post message has been delivered. Instead, uninstall the hook and let it be called directly by the event loop. Task-number: QTBUG-42428 Change-Id: I10280126dd50729bc260aa5f7029549e2e061c01 Reviewed-by: Louai Al-Khanji Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qeventdispatcher_win.cpp | 57 ++++++++++++------- src/corelib/kernel/qeventdispatcher_win_p.h | 2 + .../direct2d/qwindowsdirect2dintegration.cpp | 16 ++++++ .../direct2d/qwindowsdirect2dintegration.h | 1 + 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index a3d00faf31..62e6e9f051 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -434,9 +434,10 @@ static inline UINT inputTimerMask() LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) { + QEventDispatcherWin32 *q = qobject_cast(QAbstractEventDispatcher::instance()); + Q_ASSERT(q != 0); + if (wp == PM_REMOVE) { - QEventDispatcherWin32 *q = qobject_cast(QAbstractEventDispatcher::instance()); - Q_ASSERT(q != 0); if (q) { MSG *msg = (MSG *) lp; QEventDispatcherWin32Private *d = q->d_func(); @@ -472,7 +473,7 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) #ifdef Q_OS_WINCE return 0; #else - return CallNextHookEx(0, code, wp, lp); + return q->d_func()->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0; #endif } @@ -643,15 +644,7 @@ void QEventDispatcherWin32::createInternalHwnd() return; d->internalHwnd = qt_create_internal_window(this); -#ifndef Q_OS_WINCE - // setup GetMessage hook needed to drive our posted events - d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId()); - if (!d->getMessageHook) { - int errorCode = GetLastError(); - qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s", - errorCode, qPrintable(qt_error_string(errorCode))); - } -#endif + installMessageHook(); // register all socket notifiers QList sockets = (d->sn_read.keys().toSet() @@ -665,6 +658,35 @@ void QEventDispatcherWin32::createInternalHwnd() d->registerTimer(d->timerVec.at(i)); } +void QEventDispatcherWin32::installMessageHook() +{ + Q_D(QEventDispatcherWin32); + + if (d->getMessageHook) + return; + +#ifndef Q_OS_WINCE + // setup GetMessage hook needed to drive our posted events + d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId()); + if (!d->getMessageHook) { + int errorCode = GetLastError(); + qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s", + errorCode, qPrintable(qt_error_string(errorCode))); + } +#endif +} + +void QEventDispatcherWin32::uninstallMessageHook() +{ + Q_D(QEventDispatcherWin32); + +#ifndef Q_OS_WINCE + if (d->getMessageHook) + UnhookWindowsHookEx(d->getMessageHook); +#endif + d->getMessageHook = 0; +} + QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent) : QAbstractEventDispatcher(*new QEventDispatcherWin32Private, parent) { @@ -750,10 +772,9 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } } if (haveMessage) { -#ifdef Q_OS_WINCE // WinCE doesn't support hooks at all, so we have to call this by hand :( - (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg); -#endif + if (!d->getMessageHook) + (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg); if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) { if (seenWM_QT_SENDPOSTEDEVENTS) { @@ -1134,11 +1155,7 @@ void QEventDispatcherWin32::closingDown() d->timerVec.clear(); d->timerDict.clear(); -#ifndef Q_OS_WINCE - if (d->getMessageHook) - UnhookWindowsHookEx(d->getMessageHook); - d->getMessageHook = 0; -#endif + uninstallMessageHook(); } bool QEventDispatcherWin32::event(QEvent *e) diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 369c276615..a68f6cfa28 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -67,6 +67,8 @@ class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher protected: void createInternalHwnd(); + void installMessageHook(); + void uninstallMessageHook(); public: explicit QEventDispatcherWin32(QObject *parent = 0); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index 142362a065..351f94be2b 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -39,6 +39,7 @@ #include "qwindowsdirect2dwindow.h" #include "qwindowscontext.h" +#include "qwindowsguieventdispatcher.h" #include #include @@ -47,6 +48,16 @@ QT_BEGIN_NAMESPACE +class QWindowsDirect2DEventDispatcher : public QWindowsGuiEventDispatcher +{ +public: + QWindowsDirect2DEventDispatcher(QObject *parent = 0) + : QWindowsGuiEventDispatcher(parent) + { + uninstallMessageHook(); // ### Workaround for QTBUG-42428 + } +}; + class QWindowsDirect2DIntegrationPrivate { public: @@ -237,6 +248,11 @@ QPlatformBackingStore *QWindowsDirect2DIntegration::createPlatformBackingStore(Q return new QWindowsDirect2DBackingStore(window); } +QAbstractEventDispatcher *QWindowsDirect2DIntegration::createEventDispatcher() const +{ + return new QWindowsDirect2DEventDispatcher; +} + QWindowsDirect2DContext *QWindowsDirect2DIntegration::direct2DContext() const { return &d->m_d2dContext; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h index b410464372..c72b22a6e8 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h @@ -56,6 +56,7 @@ public: QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; QWindowsDirect2DContext *direct2DContext() const; From d9715108c1bf46d3a2b0482d1c9a0f61215a5e0e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 9 Nov 2014 13:01:35 +0100 Subject: [PATCH 10/69] Android 5.0: extract new Switch style attributes Switch_showText specifies whether the on/off text is shown in the thumb and Switch_splitTrack specifies whether the track is clipped underneath the thumb. Change-Id: I03fc6b799fe714e7b6e604328901c8c5a418ca6e Reviewed-by: BogDan Vatra --- .../jar/src/org/qtproject/qt5/android/ExtractStyle.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index b75dbac4b8..1e30e4a580 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -1544,6 +1544,11 @@ public class ExtractStyle { json.put("Switch_switchPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchPadding"), 0)); json.put("Switch_thumbTextPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_thumbTextPadding"), 0)); + if (Build.VERSION.SDK_INT >= 21) { + json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true)); + json.put("Switch_splitTrack", a.getBoolean(getField(styleableClass, "Switch_splitTrack"), false)); + } + a.recycle(); jsonWriter.name(styleName).value(json); } catch (Exception e) { From 132650e4e0a02786978663b463966054a3fb412d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Sun, 9 Nov 2014 15:51:40 +0100 Subject: [PATCH 11/69] Android: extract BitmapDrawable attributes Task-number: QTBUG-42488 Change-Id: Idd70e6300f78d96b044928885e71957daad1f5af Reviewed-by: BogDan Vatra --- .../qtproject/qt5/android/ExtractStyle.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index 1e30e4a580..2aeb89d5d5 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -67,6 +67,7 @@ import android.graphics.NinePatch; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; +import android.graphics.PorterDuff; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ClipDrawable; @@ -820,8 +821,27 @@ public class ExtractStyle { bmp = (Bitmap) drawable; else { - if (drawable instanceof BitmapDrawable) - bmp = ((BitmapDrawable)drawable).getBitmap(); + if (drawable instanceof BitmapDrawable) { + BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable; + bmp = bitmapDrawable.getBitmap(); + try { + json.put("gravity", bitmapDrawable.getGravity()); + json.put("tileModeX", bitmapDrawable.getTileModeX()); + json.put("tileModeY", bitmapDrawable.getTileModeY()); + if (Build.VERSION.SDK_INT >= 18) { + json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable)); + json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable)); + } + if (Build.VERSION.SDK_INT >= 21) { + json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable)); + ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable); + if (tintList != null) + json.put("tintList", getColorStateList(tintList)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } else { if (drawable instanceof ScaleDrawable) From ade8e0fc9b216190328b6fd3375796e82e34c323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 14 Oct 2014 15:05:23 +0200 Subject: [PATCH 12/69] Add CFBundleIdentifier to the bundle Info.plist's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor the current app CFBundleIdentifier support: handle frameworks as well. Add @BUNDLEIDENTIFIER@ placeholder to the OS X info.plist.lib templates. This means the Qt frameworks will now get a valid CFBundleIdentifier entry the same way as app bundles: by extracting the identifier prefix from Xcode settings and appending framework name. Task-number: QTBUG-32896 Change-Id: Ica8f28332a88e37a823c46fca7a2c373157af020 Reviewed-by: Tor Arne Vestbø Reviewed-by: Oswald Buddenhagen --- mkspecs/macx-clang-32/Info.plist.lib | 2 ++ mkspecs/macx-clang/Info.plist.lib | 2 ++ mkspecs/macx-g++-32/Info.plist.lib | 2 ++ mkspecs/macx-g++/Info.plist.lib | 2 ++ mkspecs/macx-g++40/Info.plist.lib | 2 ++ mkspecs/macx-g++42/Info.plist.lib | 2 ++ mkspecs/macx-icc/Info.plist.lib | 2 ++ mkspecs/macx-llvm/Info.plist.lib | 2 ++ qmake/generators/unix/unixmake2.cpp | 22 +++++++++++++--------- 9 files changed, 29 insertions(+), 9 deletions(-) diff --git a/mkspecs/macx-clang-32/Info.plist.lib b/mkspecs/macx-clang-32/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-clang-32/Info.plist.lib +++ b/mkspecs/macx-clang-32/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/mkspecs/macx-clang/Info.plist.lib b/mkspecs/macx-clang/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-clang/Info.plist.lib +++ b/mkspecs/macx-clang/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/mkspecs/macx-g++-32/Info.plist.lib b/mkspecs/macx-g++-32/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-g++-32/Info.plist.lib +++ b/mkspecs/macx-g++-32/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/mkspecs/macx-g++/Info.plist.lib b/mkspecs/macx-g++/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-g++/Info.plist.lib +++ b/mkspecs/macx-g++/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/mkspecs/macx-g++40/Info.plist.lib b/mkspecs/macx-g++40/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-g++40/Info.plist.lib +++ b/mkspecs/macx-g++40/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/mkspecs/macx-g++42/Info.plist.lib b/mkspecs/macx-g++42/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-g++42/Info.plist.lib +++ b/mkspecs/macx-g++42/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/mkspecs/macx-icc/Info.plist.lib b/mkspecs/macx-icc/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-icc/Info.plist.lib +++ b/mkspecs/macx-icc/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/mkspecs/macx-llvm/Info.plist.lib b/mkspecs/macx-llvm/Info.plist.lib index 2a44d1721e..7cbdb9af12 100644 --- a/mkspecs/macx-llvm/Info.plist.lib +++ b/mkspecs/macx-llvm/Info.plist.lib @@ -14,6 +14,8 @@ @TYPEINFO@ CFBundleExecutable @LIBRARY@ + CFBundleIdentifier + @BUNDLEIDENTIFIER@ NOTE Please, do NOT change this file -- It was generated by Qt/QMake. diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index d9b0e10057..8270f02feb 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -814,22 +814,26 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } commonSedArgs << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "; + + QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString(); + if (bundlePrefix.isEmpty()) + bundlePrefix = "com.yourcompany"; + if (bundlePrefix.endsWith(".")) + bundlePrefix.chop(1); + QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE"); + if (bundleIdentifier.endsWith(".app")) + bundleIdentifier.chop(4); + if (bundleIdentifier.endsWith(".framework")) + bundleIdentifier.chop(10); + commonSedArgs << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" "; + if (isApp) { QString icon = fileFixify(var("ICON")); - QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString(); - if (bundlePrefix.isEmpty()) - bundlePrefix = "com.yourcompany"; - if (bundlePrefix.endsWith(".")) - bundlePrefix.chop(1); - QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE"); - if (bundleIdentifier.endsWith(".app")) - bundleIdentifier.chop(4); t << "@$(DEL_FILE) " << info_plist_out << "\n\t" << "@sed "; foreach (const ProString &arg, commonSedArgs) t << arg; t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" " - << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" " << "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" " << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" " From 9b7bdd455fefc2df78eb540e9f570877aa8cd827 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 7 Nov 2014 14:42:06 +0100 Subject: [PATCH 13/69] rcc: Replace all occurrences of the marker in two-pass mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The marker can occur legitimately twice e.g. on iOS with universal binaries. Change-Id: Ie334bcd104d45140ff969f44230e6de2212e8e25 Reviewed-by: Tor Arne Vestbø Reviewed-by: Fawzi Mohamed --- src/tools/rcc/rcc.cpp | 52 +++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 9d8a7b7051..d7f8e47213 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -730,33 +730,37 @@ bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIO { m_errorDevice = &errorDevice; - const char pattern[] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' }; if (m_format == Pass2) { - char c; - for (int i = 0; i < 8; ) { - if (!tempDevice.getChar(&c)) { - m_errorDevice->write("No data signature found\n"); - return false; - } - if (c == pattern[i]) { - ++i; - } else { - for (int k = 0; k < i; ++k) - outDevice.putChar(pattern[k]); - outDevice.putChar(c); - i = 0; + const char pattern[] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' }; + bool foundSignature = false; + + while (true) { + char c; + for (int i = 0; i < 8; ) { + if (!tempDevice.getChar(&c)) { + if (foundSignature) + return true; + m_errorDevice->write("No data signature found\n"); + return false; + } + if (c == pattern[i]) { + ++i; + } else { + for (int k = 0; k < i; ++k) + outDevice.putChar(pattern[k]); + outDevice.putChar(c); + i = 0; + } } + + m_outDevice = &outDevice; + quint64 start = outDevice.pos(); + writeDataBlobs(); + quint64 len = outDevice.pos() - start; + + tempDevice.seek(tempDevice.pos() + len - 8); + foundSignature = true; } - - m_outDevice = &outDevice; - quint64 start = outDevice.pos(); - writeDataBlobs(); - quint64 len = outDevice.pos() - start; - - tempDevice.seek(tempDevice.pos() + len - 8); - outDevice.write(tempDevice.readAll()); - - return true; } //write out From 1ad78f5f29ef00abae4f718265fa4bc0c35b60f9 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 21 Oct 2014 10:22:45 +0200 Subject: [PATCH 14/69] qdoc: Prepare QDoc for the new style on qt.io The new template and CSS have some requirements that need changes in the generated .html: - Generate a new div 'sidebar' and place the TOC (if one exists) inside it, allowing the template to extend the sidebar contents dynamically. Do this for all pages except index.html. - Change the DOCTYPE declaration to be html5-compliant - Replace tags with to be html5-compliant - Add a new config variable HTML.prologue - this allows the template to insert custom html into beginning of the page, before the page title but after any navigation or table-of-contents items. - Wrap tables inside
elements. This allows for better-working CSS design for small-screen devices. - Write out extra parameters first when outputting function synopsis to have better styling. - Inject zero-width-space characters into function names to allow the browser break up long function signatures in a nice manner. - Edit the CSS for the offline style to adapt to above changes. Task-number: QTBUG-42086 Change-Id: I3075cdc11bcb07a66150388519263fd721c8002b Reviewed-by: Martin Smith --- doc/global/template/style/offline.css | 19 ++++- src/tools/qdoc/cppcodemarker.cpp | 12 +-- src/tools/qdoc/htmlgenerator.cpp | 109 +++++++++++++++----------- src/tools/qdoc/htmlgenerator.h | 3 + 4 files changed, 90 insertions(+), 53 deletions(-) diff --git a/doc/global/template/style/offline.css b/doc/global/template/style/offline.css index 126df9d806..dc0a6d1ec9 100644 --- a/doc/global/template/style/offline.css +++ b/doc/global/template/style/offline.css @@ -359,7 +359,9 @@ h3.fn, span.fn { margin: 0px; margin-top: 45px; } - +h3.fn code { + float: right; +} h3.fn:target { background-color: #F6F6D6; } @@ -705,8 +707,21 @@ Landing page float: left; } -.icons1of3 h2 { +.icons1of3 h2, .doc-column h2 { font-size: 15px; margin: 0px; padding: 0px; } + +div.multi-column { + position: relative; +} + +div.multi-column div { + display: -moz-inline-box; + display: inline-block; + vertical-align: top; + margin-top: 1em; + margin-right: 4em; + width: 24em; +} diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp index 48218da513..92b6ccca6a 100644 --- a/src/tools/qdoc/cppcodemarker.cpp +++ b/src/tools/qdoc/cppcodemarker.cpp @@ -136,7 +136,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, if ((style == Detailed) && !node->parent()->name().isEmpty() && (node->type() != Node::Property) && !node->isQmlNode()) - name.prepend(taggedNode(node->parent()) + "::"); + name.prepend(taggedNode(node->parent()) + "::​"); switch (node->type()) { case Node::Namespace: @@ -212,7 +212,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, bracketed += "slot"; } if (!bracketed.isEmpty()) - extra += " [" + bracketed.join(' ') + QLatin1Char(']'); + extra += QLatin1Char('[') + bracketed.join(' ') + QStringLiteral("] "); } break; case Node::Enum: @@ -283,13 +283,13 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, if (style == Summary) { if (node->status() == Node::Preliminary) { - extra += " (preliminary)"; + extra += "(preliminary) "; } else if (node->status() == Node::Deprecated) { - extra += " (deprecated)"; + extra += "(deprecated) "; } else if (node->status() == Node::Obsolete) { - extra += " (obsolete)"; + extra += "(obsolete) "; } } @@ -297,7 +297,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, extra.prepend("<@extra>"); extra.append(""); } - return synopsis + extra; + return extra + synopsis; } /*! diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 5b8ccd9902..bd8d45ab53 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -121,7 +121,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) { ATOM_FORMATTING_PARAMETER, "", "" }, { ATOM_FORMATTING_SUBSCRIPT, "", "" }, { ATOM_FORMATTING_SUPERSCRIPT, "", "" }, - { ATOM_FORMATTING_TELETYPE, "", "" }, + { ATOM_FORMATTING_TELETYPE, "", "" }, // tag is not supported in HTML5 { ATOM_FORMATTING_UICONTROL, "", "" }, { ATOM_FORMATTING_UNDERLINE, "", "" }, { 0, 0, 0 } @@ -149,6 +149,10 @@ void HtmlGenerator::initializeGenerator(const Config &config) postPostHeader = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTPOSTHEADER); + prologue = config.getString(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_PROLOGUE); + footer = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_FOOTER); @@ -845,7 +849,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark out() << "
\n"; } else if (atom->string() == ATOM_LIST_VALUE) { - out() << ""; + out() << "
"; threeColumnEnumValueTable_ = isThreeColumnEnumValueTable(atom); if (threeColumnEnumValueTable_) { if (++numTableRows_ % 2 == 1) @@ -897,7 +901,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark // ### Trenton QString t= protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),relative))); - out() << "
" << t << ""; + out() << "
" << t << ""; if (relative->type() == Node::Enum) { out() << ""; @@ -907,7 +911,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark if (itemValue.isEmpty()) out() << '?'; else - out() << "" << protectEnc(itemValue) << ""; + out() << "" << protectEnc(itemValue) << ""; } skipAhead = 1; } @@ -952,7 +956,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark out() << "\n"; } else if (atom->string() == ATOM_LIST_VALUE) { - out() << "
\n"; + out() << "
\n"; } else { out() << "\n"; @@ -1040,7 +1044,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark else if (p2.contains("%")) width = p2; } - out() << "
\n "; @@ -1048,7 +1052,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark } break; case Atom::TableRight: - out() << "
\n"; + out() << "\n"; break; case Atom::TableHeaderLeft: out() << ""; @@ -1456,8 +1460,7 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) Generate the TOC for the new doc format. Don't generate a TOC for the home page. */ - if ((dn->name() != QString("index.html")) && - (dn->name() != QString("qtexamplesandtutorials.html"))) + if ((dn->name() != QStringLiteral("index.html"))) generateTableOfContents(dn,marker,0); generateTitle(fullTitle, @@ -1707,8 +1710,8 @@ void HtmlGenerator::generateHeader(const QString& title, #else out() << QString("\n"); #endif - out() << "\n"; - out() << QString("\n").arg(naturalLanguage); + out() << "\n"; + out() << QString("\n").arg(naturalLanguage); out() << "\n"; out() << " \n"; if (node && !node->doc().location().isEmpty()) @@ -1775,7 +1778,8 @@ void HtmlGenerator::generateHeader(const QString& title, out() << QString(postHeader).replace("\\" + COMMAND_VERSION, qdb_->version()); generateNavigationBar(title,node,marker); - out() << "
  • \n" << buildversion << "
  • \n"; + if (!buildversion.isEmpty()) + out() << "
  • " << buildversion << "
  • \n"; out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, qdb_->version()); navigationLinks.clear(); @@ -1849,6 +1853,7 @@ void HtmlGenerator::generateTitle(const QString& title, const Node *relative, CodeMarker *marker) { + out() << QString(prologue).replace("\\" + COMMAND_VERSION, qdb_->version()); if (!title.isEmpty()) out() << "

    " << protectEnc(title) << "

    \n"; if (!subTitle.isEmpty()) { @@ -1993,7 +1998,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) if (!requisites.isEmpty()) { //generate the table - out() << "\n"; + out() << "
    \n"; QStringList::ConstIterator i; for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) { @@ -2011,7 +2016,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) out() << ""; } } - out() << "
    "; + out() << ""; } } @@ -2112,7 +2117,7 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker) if (!requisites.isEmpty()) { //generate the table - out() << "\n"; + out() << "
    \n"; QStringList::ConstIterator i; for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) { @@ -2130,7 +2135,7 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker) out() << ""; } } - out() << "
    "; + out() << ""; } } @@ -2176,12 +2181,10 @@ void HtmlGenerator::generateTableOfContents(const Node *node, QList toc; if (node->doc().hasTableOfContents()) toc = node->doc().tableOfContents(); - if (toc.isEmpty() && !sections && !node->isModule()) - return; - - //turn off table of contents if HTML.tocdepth is set to 0 - if (tocDepth == 0) + if (tocDepth == 0 || (toc.isEmpty() && !sections && !node->isModule())) { + generateSidebar(); return; + } QStringList sectionNumber; int detailsBase = 0; @@ -2190,6 +2193,7 @@ void HtmlGenerator::generateTableOfContents(const Node *node, inContents_ = true; inLink_ = true; + out() << "
    \n"; out() << "
    \n"; out() << "

    Contents

    \n"; sectionNumber.append("1"); @@ -2287,10 +2291,21 @@ void HtmlGenerator::generateTableOfContents(const Node *node, } out() << "\n"; out() << "
    \n"; + out() << "
    "; + out() << "
    \n"; inContents_ = false; inLink_ = false; } +/*! + Outputs a placeholder div where the style can add customized sidebar content. + */ +void HtmlGenerator::generateSidebar() { + out() << "
    "; + out() << "
    "; + out() << "
    \n"; +} + QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, CodeMarker *marker) { @@ -2307,6 +2322,7 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, beginSubPage(inner, fileName); QString title = "List of All Members for " + inner->name(); generateHeader(title, inner, marker); + generateSidebar(); generateTitle(title, Text(), SmallSubTitle, inner, marker); out() << "

    This is the complete list of members for "; generateFullName(inner, 0); @@ -2338,6 +2354,7 @@ QString HtmlGenerator::generateAllQmlMembersFile(QmlClassNode* qml_cn, CodeMarke beginSubPage(qml_cn, fileName); QString title = "List of All Members for " + qml_cn->name(); generateHeader(title, qml_cn, marker); + generateSidebar(); generateTitle(title, Text(), SmallSubTitle, qml_cn, marker); out() << "

    This is the complete list of members for "; generateFullName(qml_cn, 0); @@ -2422,6 +2439,7 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner, beginSubPage(inner, fileName); generateHeader(title, inner, marker); + generateSidebar(); generateTitle(title, Text(), SmallSubTitle, inner, marker); if (status == CodeMarker::Compat) { @@ -2498,6 +2516,7 @@ QString HtmlGenerator::generateQmlMemberFile(QmlClassNode* qcn, beginSubPage(qcn, fileName); generateHeader(title, qcn, marker); + generateSidebar(); generateTitle(title, Text(), SmallSubTitle, qcn, marker); out() << "

    The following members of QML type " @@ -2615,7 +2634,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, } if (allInternal) return; - out() << "\n"; + out() << "
    \n"; int row = 0; NodeList nodes = nm.values(); foreach (const Node* node, nodes) { @@ -2651,7 +2670,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, } out() << "\n"; } - out() << "
    \n"; + out() << "\n"; } /*! @@ -2902,8 +2921,8 @@ void HtmlGenerator::generateQmlItem(const Node *node, if (summary) marked.replace("@name>", "b>"); - marked.replace("<@extra>", ""); - marked.replace("", ""); + marked.replace("<@extra>", ""); + marked.replace("", ""); if (summary) { marked.remove("<@type>"); @@ -3027,11 +3046,11 @@ void HtmlGenerator::generateSection(const NodeList& nl, alignNames = false; } if (alignNames) { - out() << "\n"; + out() << "
    \n"; } else { if (twoColumn) - out() << "
    \n" + out() << "
    \n" << "
    "; out() << "
      \n"; } @@ -3062,11 +3081,11 @@ void HtmlGenerator::generateSection(const NodeList& nl, ++m; } if (alignNames) - out() << "
    \n"; + out() << "\n"; else { out() << "\n"; if (twoColumn) - out() << "\n\n"; + out() << "\n\n"; } } } @@ -3088,11 +3107,11 @@ void HtmlGenerator::generateSectionList(const Section& section, alignNames = false; } if (alignNames) { - out() << "\n"; + out() << "
    \n"; } else { if (twoColumn) - out() << "
    \n" + out() << "
    \n" << "
    "; out() << "
      \n"; } @@ -3128,11 +3147,11 @@ void HtmlGenerator::generateSectionList(const Section& section, ++m; } if (alignNames) - out() << "
    \n"; + out() << "\n"; else { out() << "\n"; if (twoColumn) - out() << "\n\n"; + out() << "\n\n"; } } @@ -3196,8 +3215,8 @@ void HtmlGenerator::generateSynopsis(const Node *node, extraRegExp.setMinimal(true); marked.remove(extraRegExp); } else { - marked.replace("<@extra>", ""); - marked.replace("", ""); + marked.replace("<@extra>", ""); + marked.replace("", ""); } if (style != CodeMarker::Detailed) { @@ -4058,7 +4077,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, const QmlPropertyGroupNode* qpgn = static_cast(node); NodeList::ConstIterator p = qpgn->childNodes().constBegin(); out() << "

    "; - out() << ""; + out() << "
    "; QString heading = qpgn->name() + " group"; out() << ""; @@ -4083,13 +4102,13 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, } ++p; } - out() << "
    "; + out() << "
    "; out() << ""; } else if (node->type() == Node::QmlProperty) { qpn = static_cast(node); out() << "
    "; - out() << ""; + out() << "
    "; out() << ""; out() << ""; - out() << "

    "; out() << ""; @@ -4103,43 +4122,43 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node, out() << "default"; generateQmlItem(qpn, relative, marker, false); out() << "

    "; + out() << "
    "; out() << ""; } else if (node->type() == Node::QmlSignal) { const FunctionNode* qsn = static_cast(node); out() << "
    "; - out() << ""; + out() << "
    "; out() << ""; out() << ""; - out() << "

    "; out() << ""; generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false); out() << "

    "; + out() << "
    "; out() << ""; } else if (node->type() == Node::QmlSignalHandler) { const FunctionNode* qshn = static_cast(node); out() << "
    "; - out() << ""; + out() << "
    "; out() << ""; out() << ""; - out() << "

    "; out() << ""; generateSynopsis(qshn,relative,marker,CodeMarker::Detailed,false); out() << "

    "; + out() << "
    "; out() << ""; } else if (node->type() == Node::QmlMethod) { const FunctionNode* qmn = static_cast(node); out() << "
    "; - out() << ""; + out() << "
    "; out() << ""; out() << ""; - out() << "

    "; out() << ""; generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false); out() << "

    "; + out() << "
    "; out() << ""; } out() << "
    "; diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h index 616a989361..40360da02e 100644 --- a/src/tools/qdoc/htmlgenerator.h +++ b/src/tools/qdoc/htmlgenerator.h @@ -144,6 +144,7 @@ private: void generateTableOfContents(const Node *node, CodeMarker *marker, QList
    * sections = 0); + void generateSidebar(); QString generateListOfAllMemberFile(const InnerNode *inner, CodeMarker *marker); QString generateAllQmlMembersFile(QmlClassNode* qml_cn, CodeMarker* marker); @@ -238,6 +239,7 @@ private: QString endHeader; QString postHeader; QString postPostHeader; + QString prologue; QString footer; QString address; bool pleaseGenerateMacRef; @@ -272,6 +274,7 @@ public: #define HTMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me #define HTMLGENERATOR_POSTHEADER "postheader" #define HTMLGENERATOR_POSTPOSTHEADER "postpostheader" +#define HTMLGENERATOR_PROLOGUE "prologue" #define HTMLGENERATOR_NONAVIGATIONBAR "nonavigationbar" #define HTMLGENERATOR_NOSUBDIRS "nosubdirs" #define HTMLGENERATOR_TOCDEPTH "tocdepth" From 0c2f7388a89a9d8ae24379cdbee11a9f85304d19 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 11 Nov 2014 10:25:14 +0100 Subject: [PATCH 15/69] Windows: Remove font size hack This hack was reintroduced in a4478b28966c5f630ba3d93b97bc91a3cec2fdbe, and hides scaling artifacts in fonts where there is heavy hinting, such as Arial, but introduces new bugs in other fonts, such as Vijaya. The bottom line is that we shouldn't arbitrarily override the pixel size of the font with the character height that we get from GDI. Due to hinting, there will be some artifacts when printing with screen resolution on Windows. The only way to make this look correct is to use high resolution printing, like the documentation says, or perhaps to force design metrics on the text layout. Task-number: QTBUG-40770 Change-Id: Id151eb0ede5f73efb2a401924ce379d4414ca2b1 Reviewed-by: Lars Knoll --- src/gui/painting/qpdf.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 1da0c6b65f..9082f98205 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -2524,10 +2524,6 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti) qreal size = ti.fontEngine->fontDef.pixelSize; -#if defined(Q_OS_WIN) - size = (ti.fontEngine->ascent() + ti.fontEngine->descent()).toReal(); -#endif - QVarLengthArray glyphs; QVarLengthArray positions; QTransform m = QTransform::fromTranslate(p.x(), p.y()); From d4fcf2ca40e635cc0f198afe6e17e88ba098835b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 3 Nov 2014 11:23:05 +0100 Subject: [PATCH 16/69] iOS: let qmake generate default LaunchScreen.xib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iOS8 will check if the app has a LaunchScreen.xib to determine if it supports iPhone6/6+ (scale factor and resolution). So we follow the same pattern as we do with the launch image for iPhone5, and generate a default LaunchScreen.xib. The xib file in this patch is a copy of a default file generated by a native Xcode project (with quotes escaped), but with the text label set to be $$TARGET. Change-Id: I163ab48b6f4edea4cc1f6840a1f3d8b3cc0326db Reviewed-by: Tor Arne Vestbø --- mkspecs/macx-ios-clang/Info.plist.app | 2 + mkspecs/macx-ios-clang/LaunchScreen.xib | 45 +++++++++++++++++++ .../macx-ios-clang/features/default_post.prf | 8 ++++ 3 files changed, 55 insertions(+) create mode 100644 mkspecs/macx-ios-clang/LaunchScreen.xib diff --git a/mkspecs/macx-ios-clang/Info.plist.app b/mkspecs/macx-ios-clang/Info.plist.app index 2987804e33..623ed496c5 100755 --- a/mkspecs/macx-ios-clang/Info.plist.app +++ b/mkspecs/macx-ios-clang/Info.plist.app @@ -24,6 +24,8 @@ 1.0 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UISupportedInterfaceOrientations UIInterfaceOrientationPortrait diff --git a/mkspecs/macx-ios-clang/LaunchScreen.xib b/mkspecs/macx-ios-clang/LaunchScreen.xib new file mode 100644 index 0000000000..d28c06b375 --- /dev/null +++ b/mkspecs/macx-ios-clang/LaunchScreen.xib @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 2001f53ec4..51a87e3eab 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -184,6 +184,14 @@ macx-xcode { QMAKE_SUBSTITUTES += copy_image launch_images.files = $$copy_image.output QMAKE_BUNDLE_DATA += launch_images + + # Set up default LaunchScreen to support iPhone6/6+ + launch_screen = LaunchScreen.xib + copy_launch_screen.input = $$QMAKESPEC/$$launch_screen + copy_launch_screen.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$launch_screen + QMAKE_SUBSTITUTES += copy_launch_screen + launch_screens.files = $$copy_launch_screen.output + QMAKE_BUNDLE_DATA += launch_screens } macx-xcode { From 91e53a7b9cb30e330c86c8bc460159fe14945042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Nov 2014 16:11:01 +0100 Subject: [PATCH 17/69] Xcode: Make sure QMAKE_PRE_LINK dependencies are complete for multi-arch builds With multi-architecture builds and ONLY_ACTIVE_ARCH set to NO, Xcode will build the final target for multiple architectures at the same time, but CURRENT_ARCH will only match one of them, so we failed to set up the right dependencies for our pre-link step, causing the step to happen after linking in some cases. We now build an exhaustive dependency list based on QMAKE_XCODE_ARCHS, so that ONLY_ACTIVE_ARCH=NO can be used for release builds targeted at the App Store. Change-Id: I6702f020a6970807adc624779f6dde09be62beb9 Reviewed-by: Andy Shaw --- qmake/generators/mac/pbuilder_pbx.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 4624496e99..0ff42500de 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1029,6 +1029,21 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if (!project->isEmpty("QMAKE_PRE_LINK")) { QString phase_key = keyFor("QMAKE_PBX_PRELINK_BUILDPHASE"); project->values("QMAKE_PBX_BUILDPHASES").append(phase_key); + + ProStringList inputPaths; + ProStringList outputPaths; + const ProStringList &archs = project->values("QMAKE_XCODE_ARCHS"); + if (!archs.isEmpty()) { + for (int i = 0; i < archs.size(); ++i) { + const ProString &arch = archs.at(i); + inputPaths << "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/" + arch + "/"; + outputPaths << "$(LINK_FILE_LIST_$(CURRENT_VARIANT)_" + arch + ")"; + } + } else { + inputPaths << "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/"; + outputPaths << "$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))"; + } + t << "\t\t" << phase_key << " = {\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n" @@ -1036,8 +1051,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) // resolved dependenices, so we have to ensure that this phase is run after the // compilation phase, and before the link phase. Making the phase depend on the // object file directory, and "write" to the list of files to link achieves that. - << "\t\t\t" << writeSettings("inputPaths", ProStringList("$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/"), SettingsAsList, 4) << ";\n" - << "\t\t\t" << writeSettings("outputPaths", ProStringList("$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))"), SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("inputPaths", inputPaths, SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("outputPaths", outputPaths, SettingsAsList, 4) << ";\n" << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" << "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n" From 8ea5b2852e36c93195987a588d893cc8e5b185ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 5 Nov 2014 16:37:59 +0100 Subject: [PATCH 18/69] iOS: Remove assert when transferring or clearing first-responder We'd transfer or clear first-responder in a lot more cases than just when transferring to a new Qt window, such as when presenting a new view-controller on top to send an e-mail or take a picture using the camera. Change-Id: I6b2a8a6d9fd99910b96a86cf9847b7ff0128f20a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiostextresponder.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index e3c73f5222..6bd1e711d0 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -268,8 +268,11 @@ qImDebug() << "keyboard was closed, clearing focus object"; m_inputContext->clearCurrentFocusObject(); } else { - // We've lost responder status because another window was made active - Q_ASSERT(FirstResponderCandidate::currentCandidate()); + // We've lost responder status because another Qt window was made active, + // another QIOSTextResponder was made first-responder, another UIView was + // made first-responder, or the first-responder was cleared globally. In + // either of these cases we don't have to do anything. + qImDebug() << "lost first responder, but not clearing focus object"; } return YES; From 3e161dcb3dcee13a942bb7f0aca1a1920808acd3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 12 Nov 2014 12:14:57 +0100 Subject: [PATCH 19/69] iOS: QtFirstResponderEvent needs to release firstResponder to avoid leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without setting firstResponder to 0 upon destruction, the current retain count would never reach zero after the event was used. The result being that QIOSTextResponder was seldom destroyed, which would also affect its inputView etc which would also be kept alive. Change-Id: Ia88e6a9d8764e7e9532487153e5e81a7ad0f9741 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 9f10c3e287..3ecd0ca61f 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -141,6 +141,11 @@ int infoPlistValue(NSString* key, int defaultValue) @end @implementation QtFirstResponderEvent +- (void) dealloc +{ + self.firstResponder = 0; + [super dealloc]; +} @end From eca0668a8c76cc5ea273f614500e91de7e706541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Nov 2014 16:14:32 +0100 Subject: [PATCH 20/69] iOS: Ensure that the rename-main logic works for multi-arch builds We need to tell Xcode which architectures it should set up pre-link dependencies for, as well as run the rename script in the root object file directory. We pass it the current architectures so that we only rename main() for simulator or device, not both. Change-Id: I095d7c8a22ff0cb2ce872c9a86c93a070c1fcc65 Reviewed-by: Oswald Buddenhagen Reviewed-by: Richard Moe Gustavsen --- mkspecs/macx-ios-clang/features/default_post.prf | 2 +- mkspecs/macx-ios-clang/features/qt.prf | 6 ++++-- mkspecs/macx-ios-clang/rename_main.sh | 10 +++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 51a87e3eab..5da95f16bf 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -201,7 +201,7 @@ macx-xcode { arch_iphonesimulator.value = $$QMAKE_IOS_SIMULATOR_ARCHS QMAKE_MAC_XCODE_SETTINGS += arch_iphoneos arch_iphonesimulator - unset(QMAKE_XCODE_ARCHS) + QMAKE_XCODE_ARCHS = $$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS } else { # Be more specific about which architecture we're targeting contains(QT_ARCH, arm.*): \ diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf index a5b00377ee..7ca3198dbe 100644 --- a/mkspecs/macx-ios-clang/features/qt.prf +++ b/mkspecs/macx-ios-clang/features/qt.prf @@ -32,17 +32,19 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) { # called 'qt_main' now. macx-xcode { - objects_dir = "${OBJECT_FILE_DIR}-${CURRENT_VARIANT}/${CURRENT_ARCH}" + objects_dir = "${OBJECT_FILE_DIR}-${CURRENT_VARIANT}" + archs = "${ARCHS}" } else { objects_dir = $$OBJECTS_DIR isEmpty(objects_dir): \ objects_dir = . + archs = "$$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS" } !isEmpty(QMAKE_PRE_LINK): \ QMAKE_PRE_LINK += ";" - QMAKE_PRE_LINK += $$QMAKESPEC/rename_main.sh $${objects_dir} + QMAKE_PRE_LINK += $$QMAKESPEC/rename_main.sh $${objects_dir} \"$${archs}\" } } diff --git a/mkspecs/macx-ios-clang/rename_main.sh b/mkspecs/macx-ios-clang/rename_main.sh index b1321e855e..040140b7ee 100755 --- a/mkspecs/macx-ios-clang/rename_main.sh +++ b/mkspecs/macx-ios-clang/rename_main.sh @@ -41,10 +41,14 @@ ## ############################################################################# -if [ $# -eq 0 ]; then - echo "usage: $0 " +if [ $# -ne 2 ]; then + echo "$0: wrong number of arguments for internal tool used by iOS mkspec" else - for f in $(find $1 -name '*.o'); do + arch_paths="" + for a in $2; do + arch_paths="$arch_paths $1/$a" + done + for f in $(find $arch_paths -name '*.o'); do # Skip object files without the _main symbol nm $f 2>/dev/null | grep -q 'T _main$' || continue From 88b2f5e8686ee7b1b7f49012c964f2ec20d6c61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 4 Nov 2014 19:41:48 +0100 Subject: [PATCH 21/69] iOS: Allow ARCHS to be specified at build time for multi-arch builds Building all architectures of a multi-arch build during Qt development is in most cases not needed, so we expose a way to limit the archs we build by passing ARCHS="subset of archs" to make, similar to how you can pass ARCHS to xcodebuild. If the subset doesn't match any of the valid architectures for the target, it will fall back to the default architectures, so it's safe to pass eg. ARCHS="armv7 i386" to make, even if building for both simulator and device. The variable may also be exported to the environment for more persistent limits on which architectures to build. Change-Id: I47b10bc9d743f0301efff4181d6881ae140d557f Reviewed-by: Richard Moe Gustavsen --- mkspecs/macx-ios-clang/features/default_post.prf | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 5da95f16bf..34fbac56d0 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -205,18 +205,21 @@ macx-xcode { } else { # Be more specific about which architecture we're targeting contains(QT_ARCH, arm.*): \ - actual_archs = $$QMAKE_IOS_DEVICE_ARCHS + VALID_ARCHS = $$QMAKE_IOS_DEVICE_ARCHS else: \ - actual_archs = $$QMAKE_IOS_SIMULATOR_ARCHS + VALID_ARCHS = $$QMAKE_IOS_SIMULATOR_ARCHS - for(arch, actual_archs): \ - arch_flags += -arch $$arch + ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS)) + ARCH_ARGS = $(foreach arch, $(if $(EXPORT_ACTIVE_ARCHS), $(EXPORT_ACTIVE_ARCHS), $(EXPORT_VALID_ARCHS)), -arch $(arch)) + + QMAKE_EXTRA_VARIABLES += VALID_ARCHS ACTIVE_ARCHS ARCH_ARGS + + arch_flags = $(EXPORT_ARCH_ARGS) QMAKE_CFLAGS += $$arch_flags QMAKE_CXXFLAGS += $$arch_flags QMAKE_OBJECTIVE_CFLAGS += $$arch_flags QMAKE_LFLAGS += $$arch_flags } -unset(actual_archs) load(default_post) From 70ea4e2b294eeac51fc497191990842f48d1aff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 28 Oct 2014 13:27:25 +0100 Subject: [PATCH 22/69] iOS: Enable fat builds containing both armv7 and arm64 slices Apple will from February 1, 2015, require all applications uploaded to the App Store to be built for both 32-bit (armv7/s) and 64-bit (arm64). https://developer.apple.com/news/?id=10202014a We enable fat Qt binaries by passing both -arch armv7 and -arch arm64 to clang, which takes care of lipoing together the two slices for each object file. This unfortunately means twice the build time and twice the binary size for our libraries. Since precompiled headers are architecture specific, and the -Xarch option can't be used with -include-pch, we need to disable precompiled headers globally. This can be improved in the future by switching to pretokenized headers (http://clang.llvm.org/docs/PTHInternals.html). Since we're enabling 64-bit ARM builds, we're also switching the simulator builds from i386 to fat i386 and x86_64 builds, so that we are able to test 64-bit builds using the simulator, but we're keeping i386 as the architecture Qt is aware of when it's building for simulator, as we need the CPU features to match the lowest common denominator. Change-Id: I277e60bddae549d24ca3c6301d842405180aded6 Reviewed-by: Simon Hausmann --- configure | 1 + mkspecs/macx-ios-clang/features/default_post.prf | 2 ++ mkspecs/macx-ios-clang/features/qt_config.prf | 4 ++++ mkspecs/macx-ios-clang/qmake.conf | 4 ++-- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 1bd7db88b3..979e32e050 100755 --- a/configure +++ b/configure @@ -3152,6 +3152,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples" CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qtwebkit qtwebkit-examples" + CFG_PRECOMPILE="no" # Precompiled headers not supported with multiple -arch arguments # If the user passes -sdk on the command line we build a SDK-specific Qt build. # Otherwise we build a joined simulator and device build, which is the default. diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 34fbac56d0..0245c948d9 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -209,6 +209,8 @@ macx-xcode { else: \ VALID_ARCHS = $$QMAKE_IOS_SIMULATOR_ARCHS + single_arch: VALID_ARCHS = $$first(VALID_ARCHS) + ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS)) ARCH_ARGS = $(foreach arch, $(if $(EXPORT_ACTIVE_ARCHS), $(EXPORT_ACTIVE_ARCHS), $(EXPORT_VALID_ARCHS)), -arch $(arch)) diff --git a/mkspecs/macx-ios-clang/features/qt_config.prf b/mkspecs/macx-ios-clang/features/qt_config.prf index d9a13f65eb..d1a1a36933 100644 --- a/mkspecs/macx-ios-clang/features/qt_config.prf +++ b/mkspecs/macx-ios-clang/features/qt_config.prf @@ -9,4 +9,8 @@ isEmpty(QT_ARCH) { QT_ARCH = arm else: \ # Simulator QT_ARCH = i386 + + # Prevent the arch/config tests from building as multi-arch binaries, + # as we only want the lowest common denominator features. + CONFIG += single_arch } diff --git a/mkspecs/macx-ios-clang/qmake.conf b/mkspecs/macx-ios-clang/qmake.conf index 7b2e7a17e7..0c083edf80 100644 --- a/mkspecs/macx-ios-clang/qmake.conf +++ b/mkspecs/macx-ios-clang/qmake.conf @@ -15,8 +15,8 @@ DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG # Universal target (iPhone and iPad) QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2 -QMAKE_IOS_DEVICE_ARCHS = armv7 -QMAKE_IOS_SIMULATOR_ARCHS = i386 +QMAKE_IOS_DEVICE_ARCHS = armv7 arm64 +QMAKE_IOS_SIMULATOR_ARCHS = i386 x86_64 include(../common/ios.conf) include(../common/gcc-base-mac.conf) From 9afb02412eadc567e82a0aca10c6401937d213e9 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 13 Nov 2014 13:00:11 +0100 Subject: [PATCH 23/69] Revert "Fix fallbacks for adapted common script" This reverts 1dd9a0af4f577ccb5578cea562a98686c8e290e6. It was a band-aid for a change in the unicode itemizing algorithm which caused the script of a script item to become unreliable. This change has since been reverted, so the band-aid is no longer needed, and it also causes problems for WebKit on Windows when it ends up preferring Arial Unicode MS as the font for Uchen script, even though the font does not support this script. The autotest from the reverted commit is kept in place and still passes. [ChangeLog][Text] Fixed regression when rendering Uchen text in WebKit on Windows. Change-Id: I488c84703bb55a050d90092c6bf9e5c70a9e31c2 Task-number: QTBUG-41372 Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qfontdatabase.cpp | 10 +++++----- src/gui/text/qfontdatabase.h | 2 +- src/gui/text/qfontengine.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 1322a088e0..645d86c0fe 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -593,7 +593,7 @@ struct QtFontDesc static int match(int script, const QFontDef &request, const QString &family_name, const QString &foundry_name, int force_encoding_id, - QtFontDesc *desc, const QList &blacklisted, bool fallback); + QtFontDesc *desc, const QList &blacklisted); static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi) { @@ -1083,7 +1083,7 @@ static bool matchFamilyName(const QString &familyName, QtFontFamily *f) */ static int match(int script, const QFontDef &request, const QString &family_name, const QString &foundry_name, int force_encoding_id, - QtFontDesc *desc, const QList &blacklistedFamilies, bool fallback = false) + QtFontDesc *desc, const QList &blacklistedFamilies) { Q_UNUSED(force_encoding_id); int result = -1; @@ -1136,7 +1136,7 @@ static int match(int script, const QFontDef &request, load(test.family->name, script); // Check if family is supported in the script we want - if (!fallback && script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported)) + if (script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported)) continue; // as we know the script is supported, we can be sure @@ -2454,7 +2454,7 @@ bool QFontDatabase::supportsThreadedFontRendering() */ QFontEngine * QFontDatabase::findFont(int script, const QFontPrivate *fp, - const QFontDef &request, bool multi, bool fallback) + const QFontDef &request, bool multi) { QMutexLocker locker(fontDatabaseMutex()); @@ -2482,7 +2482,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, QtFontDesc desc; QList blackListed; - int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed, fallback); + int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed); if (index >= 0) { engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size); if (!engine) diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index f1c479d0bb..d7d8745f12 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -152,7 +152,7 @@ private: static void createDatabase(); static void parseFontName(const QString &name, QString &foundry, QString &family); static QString resolveFontFamilyAlias(const QString &family); - static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false, bool fallback = false); + static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false); static void load(const QFontPrivate *d, int script); friend struct QFontDef; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 6a34a4c117..52e10bd717 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -2037,7 +2037,7 @@ void QFontEngineMultiBasicImpl::loadEngine(int at) request.family = fallbackFamilies.at(at-1); engines[at] = QFontDatabase::findFont(script, /*fontprivate = */0, - request, /*multi = */false, true); + request, /*multi = */false); Q_ASSERT(engines[at]); engines[at]->ref.ref(); engines[at]->fontDef = request; From be64d905a01ec364cfc630d86b6118f20e9df30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Tue, 11 Nov 2014 16:28:43 +0200 Subject: [PATCH 24/69] Set correct QSurfaceFormat also for raster surfacetype Change-Id: Idd37942842dc59ae391b6b34308d4c01e7a25bc5 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/eglfs/qeglfswindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index c83b894089..f5839e086d 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -103,7 +103,7 @@ void QEglFSWindow::create() if (isRaster()) { QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); - context->setFormat(window()->requestedFormat()); + context->setFormat(m_format); context->setScreen(window()->screen()); if (!context->create()) qFatal("EGLFS: Failed to create compositing context"); From 4b717026d3e6b891ba14ae90394bc81e2514ffda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Wed, 8 Oct 2014 15:11:57 +0300 Subject: [PATCH 25/69] eglfs: ifdef linux specific functionality from convenience functions Because change a093204f07f276bc8e7b4fedf4af0e1369f55734 qeglfshooks_stub.cpp don't compile anymore on any other *nix platform than linux as those functions have been set linux specific only. Change-Id: I339672b1bf2745511076030cc1fe13dc7f2356ff Reviewed-by: Laszlo Agocs --- .../eglconvenience/qeglconvenience.cpp | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index 1fdeec3adb..c1a491c80b 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -37,8 +37,8 @@ #ifdef Q_OS_LINUX #include #include -#include #endif +#include #include "qeglconvenience_p.h" @@ -448,10 +448,13 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config) } } -#ifdef Q_OS_LINUX +#ifdef Q_OS_UNIX QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize) { +#ifndef Q_OS_LINUX + Q_UNUSED(framebufferDevice) +#endif const int defaultPhysicalDpi = 100; static QSizeF size; @@ -466,10 +469,11 @@ QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize return size; } - struct fb_var_screeninfo vinfo; int w = -1; int h = -1; QSize screenResolution; +#ifdef Q_OS_LINUX + struct fb_var_screeninfo vinfo; if (framebufferDevice != -1) { if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) { @@ -479,7 +483,9 @@ QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize h = vinfo.height; screenResolution = QSize(vinfo.xres, vinfo.yres); } - } else { + } else +#endif + { // Use the provided screen size, when available, since some platforms may have their own // specific way to query it. Otherwise try querying it from the framebuffer. screenResolution = screenSize.isEmpty() ? q_screenSizeFromFb(framebufferDevice) : screenSize; @@ -499,6 +505,9 @@ QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize QSize q_screenSizeFromFb(int framebufferDevice) { +#ifndef Q_OS_LINUX + Q_UNUSED(framebufferDevice) +#endif const int defaultWidth = 800; const int defaultHeight = 600; static QSize size; @@ -513,6 +522,7 @@ QSize q_screenSizeFromFb(int framebufferDevice) return size; } +#ifdef Q_OS_LINUX struct fb_var_screeninfo vinfo; int xres = -1; int yres = -1; @@ -528,6 +538,10 @@ QSize q_screenSizeFromFb(int framebufferDevice) size.setWidth(xres <= 0 ? defaultWidth : xres); size.setHeight(yres <= 0 ? defaultHeight : yres); +#else + size.setWidth(defaultWidth); + size.setHeight(defaultHeight); +#endif } return size; @@ -535,10 +549,14 @@ QSize q_screenSizeFromFb(int framebufferDevice) int q_screenDepthFromFb(int framebufferDevice) { +#ifndef Q_OS_LINUX + Q_UNUSED(framebufferDevice) +#endif const int defaultDepth = 32; static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt(); if (depth == 0) { +#ifdef Q_OS_LINUX struct fb_var_screeninfo vinfo; if (framebufferDevice != -1) { @@ -550,11 +568,14 @@ int q_screenDepthFromFb(int framebufferDevice) if (depth <= 0) depth = defaultDepth; +#else + depth = defaultDepth; +#endif } return depth; } -#endif // Q_OS_LINUX +#endif // Q_OS_UNIX QT_END_NAMESPACE From eb05bda4f2fc1b9abe0c91d0b9e52c9633f5fff5 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 13 Nov 2014 10:56:02 +0100 Subject: [PATCH 26/69] QJsonArray::(const_)iterator: add the typedef for the pointer type Mandatory as per the standard iterator requirements, was causing compilation errors in the STL algorithms. Task-number: QTBUG-41628 Change-Id: Iee12a3b822383f63c07e270244fd0e145a486b95 Reviewed-by: Lars Knoll --- src/corelib/json/qjsonarray.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h index 87d14a7703..a8307ae5aa 100644 --- a/src/corelib/json/qjsonarray.h +++ b/src/corelib/json/qjsonarray.h @@ -105,6 +105,7 @@ public: typedef int difference_type; typedef QJsonValue value_type; typedef QJsonValueRef reference; + typedef QJsonValueRefPtr pointer; inline iterator() : a(0), i(0) { } explicit inline iterator(QJsonArray *array, int index) : a(array), i(index) { } @@ -149,6 +150,7 @@ public: typedef qptrdiff difference_type; typedef QJsonValue value_type; typedef QJsonValue reference; + typedef QJsonValuePtr pointer; inline const_iterator() : a(0), i(0) { } explicit inline const_iterator(const QJsonArray *array, int index) : a(array), i(index) { } From f3b93a7724929408a9b673674ffa73c164e0a771 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 12 Nov 2014 18:41:52 +0200 Subject: [PATCH 27/69] Android: Introduce getAccessibleField This method simplifies a lot the code. Change-Id: I7fe775d671ae89e112f313c21f61923133785785 Reviewed-by: J-P Nurmi --- .../qtproject/qt5/android/ExtractStyle.java | 73 +++++++------------ 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index 2aeb89d5d5..cf05b674d2 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -96,7 +96,7 @@ public class ExtractStyle { native static int[] extractNativeChunkInfo20(long nativeChunk); - Class styleableClass = getStylableClass(); + Class styleableClass = getClass("android.R$styleable"); final int[] EMPTY_STATE_SET = {}; final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled}; final int[] FOCUSED_STATE_SET = {android.R.attr.state_focused}; @@ -387,15 +387,26 @@ public class ExtractStyle { return null; } - private Class getStylableClass() { + private Class getClass(String className) { try { - return Class.forName("android.R$styleable"); + return Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } + Field getAccessibleField(Class clazz, String fieldName) { + try { + Field f = clazz.getDeclaredField(fieldName); + f.setAccessible(true); + return f; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + int getField(Class clazz, String fieldName) { try { @@ -683,27 +694,13 @@ public class ExtractStyle { json.put("type", "rotate"); Object obj = drawable.getConstantState(); Class rotateStateClass = obj.getClass(); - Field f = rotateStateClass.getDeclaredField("mDrawable"); - f.setAccessible(true); - json.put("drawable", getDrawable(f.get(obj), filename, null)); - f = rotateStateClass.getDeclaredField("mPivotX"); - f.setAccessible(true); - json.put("pivotX", f.getFloat(obj)); - f = rotateStateClass.getDeclaredField("mPivotXRel"); - f.setAccessible(true); - json.put("pivotXRel", f.getBoolean(obj)); - f = rotateStateClass.getDeclaredField("mPivotY"); - f.setAccessible(true); - json.put("pivotY", f.getFloat(obj)); - f = rotateStateClass.getDeclaredField("mPivotYRel"); - f.setAccessible(true); - json.put("pivotYRel", f.getBoolean(obj)); - f = rotateStateClass.getDeclaredField("mFromDegrees"); - f.setAccessible(true); - json.put("fromDegrees", f.getFloat(obj)); - f = rotateStateClass.getDeclaredField("mToDegrees"); - f.setAccessible(true); - json.put("toDegrees", f.getFloat(obj)); + json.put("drawable", getDrawable(getAccessibleField(rotateStateClass, "mDrawable").get(obj), filename, null)); + json.put("pivotX", getAccessibleField(rotateStateClass, "mPivotX").getFloat(obj)); + json.put("pivotXRel", getAccessibleField(rotateStateClass, "mPivotXRel").getBoolean(obj)); + json.put("pivotY", getAccessibleField(rotateStateClass, "mPivotY").getFloat(obj)); + json.put("pivotYRel", getAccessibleField(rotateStateClass, "mPivotYRel").getBoolean(obj)); + json.put("fromDegrees", getAccessibleField(rotateStateClass, "mFromDegrees").getFloat(obj)); + json.put("toDegrees", getAccessibleField(rotateStateClass, "mToDegrees").getFloat(obj)); } catch (Exception e) { e.printStackTrace(); } @@ -774,22 +771,14 @@ public class ExtractStyle { private JSONObject findPatchesMarings(Drawable d) throws JSONException, NoSuchFieldException, IllegalAccessException { - Field mNinePatch = ((NinePatchDrawable)d).getClass().getDeclaredField("mNinePatch"); - mNinePatch.setAccessible(true); - NinePatch np = (NinePatch) mNinePatch.get(d); + NinePatch np = (NinePatch) getAccessibleField(NinePatchDrawable.class, "mNinePatch").get(d); if (Build.VERSION.SDK_INT < 19) - { - Field mChunk = np.getClass().getDeclaredField("mChunk"); - mChunk.setAccessible(true); - return getJsonChunkInfo(extractChunkInfo((byte[]) mChunk.get(np))); - } + return getJsonChunkInfo(extractChunkInfo((byte[]) getAccessibleField(np.getClass(), "mChunk").get(np))); else { - Field mNativeChunk = np.getClass().getDeclaredField("mNativeChunk"); - mNativeChunk.setAccessible(true); if (Build.VERSION.SDK_INT > 19) - return getJsonChunkInfo(extractNativeChunkInfo20(mNativeChunk.getLong(np))); - return getJsonChunkInfo(extractNativeChunkInfo(mNativeChunk.getInt(np))); + return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(np.getClass(), "mNativeChunk").getLong(np))); + return getJsonChunkInfo(extractNativeChunkInfo(getAccessibleField(np.getClass(), "mNativeChunk").getInt(np))); } } @@ -873,9 +862,7 @@ public class ExtractStyle { try { json.put("type", "clipDrawable"); Drawable.ConstantState dcs = ((ClipDrawable)drawable).getConstantState(); - Field f = dcs.getClass().getDeclaredField("mDrawable"); - f.setAccessible(true); - json.put("drawable", getDrawable(f.get(dcs), filename, null)); + json.put("drawable", getDrawable(getAccessibleField(dcs.getClass(), "mDrawable").get(dcs), filename, null)); if (null != padding) json.put("padding", getJsonRect(padding)); else { @@ -913,14 +900,10 @@ public class ExtractStyle { { try { InsetDrawable d = (InsetDrawable)drawable; - Field mInsetState = d.getClass().getDeclaredField("mInsetState"); - mInsetState.setAccessible(true); - Object mInsetStateObject = mInsetState.get(drawable); - Field mDrawable = mInsetStateObject.getClass().getDeclaredField("mDrawable"); - mDrawable.setAccessible(true); + Object mInsetStateObject = getAccessibleField(InsetDrawable.class, "mInsetState").get(d); Rect _padding = new Rect(); boolean hasPadding = d.getPadding(_padding); - return getDrawable(mDrawable.get(mInsetStateObject), filename, hasPadding ? _padding : null); + return getDrawable(getAccessibleField(mInsetStateObject.getClass(), "mDrawable").get(mInsetStateObject), filename, hasPadding ? _padding : null); } catch (Exception e) { e.printStackTrace(); } From f12d4ee3fb6e647a0407c058ca76847ed3854a5e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Nov 2014 23:52:20 +0100 Subject: [PATCH 28/69] iOS: close keyboard by resigning first responder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current approach of reloading input views assumes that the first responder is not a QIOSTextResponder, but a QUIView. This is not always the case, e.g if someone calls update after setting IM enabled on current focus object to false. In that case we'll try to close the keyboard by reloading input views on a quitextresponder which can fail if the text responder has an external input view attached. This patch will instead hide the keyboard by resigning first responder when it is a QIOSTextResponder. If it is not a QIOSTextResponder it means that the keyboard is already closed, or a third-party UIVIew that supports key input is first responder. In either case we then leave it as-is. Task-number: QTBUG-42523 Change-Id: I4dab648af9029941a8d5d3b00011fbd169be5482 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 3 --- src/plugins/platforms/ios/qiosinputcontext.mm | 27 +++---------------- .../platforms/ios/qiostextresponder.mm | 15 ----------- 3 files changed, 4 insertions(+), 41 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 1f1130f932..d2a9c261ba 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -85,15 +85,12 @@ public: const ImeState &imeState() { return m_imeState; }; bool inputMethodAccepted() const; - bool isReloadingInputViewsFromUpdate() const { return m_isReloadingInputViewsFromUpdate; } - static QIOSInputContext *instance(); private: QIOSKeyboardListener *m_keyboardListener; QIOSTextInputResponder *m_textResponder; ImeState m_imeState; - bool m_isReloadingInputViewsFromUpdate; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 072a49c7c5..e417e9a1fb 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -330,7 +330,6 @@ QIOSInputContext::QIOSInputContext() : QPlatformInputContext() , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) , m_textResponder(0) - , m_isReloadingInputViewsFromUpdate(false) { if (isQtApplication()) connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::cursorRectangleChanged); @@ -540,10 +539,11 @@ void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties) [m_textResponder autorelease]; m_textResponder = [[QIOSTextInputResponder alloc] initWithInputContext:this]; [m_textResponder becomeFirstResponder]; + } else if ([UIResponder currentFirstResponder] == m_textResponder) { + qImDebug() << "IM not enabled, resigning text responder as first responder"; + [m_textResponder resignFirstResponder]; } else { - qImDebug() << "IM not enabled, reloading input views"; - QScopedValueRollback recursionGuard(m_isReloadingInputViewsFromUpdate, true); - [[UIResponder currentFirstResponder] reloadInputViews]; + qImDebug() << "IM not enabled. Text responder not first responder. Nothing to do"; } } else { [m_textResponder notifyInputDelegate:changedProperties]; @@ -594,22 +594,3 @@ void QIOSInputContext::commit() [m_textResponder unmarkText]; [m_textResponder notifyInputDelegate:Qt::ImSurroundingText]; } - -// ------------------------------------------------------------------------- - -@interface QUIView (InputMethods) -- (void)reloadInputViews; -@end - -@implementation QUIView (InputMethods) -- (void)reloadInputViews -{ - if (QIOSInputContext::instance()->isReloadingInputViewsFromUpdate()) { - qImDebug() << "preventing recursion by reloading super"; - [super reloadInputViews]; - } else { - qImDebug() << "reseting input methods"; - qApp->inputMethod()->reset(); - } -} -@end diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 6bd1e711d0..2fcc7258f7 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -285,21 +285,6 @@ reinterpret_cast(qApp->focusWindow()->handle()->winId()) : 0; } -/*! - iOS uses [UIResponder(Internal) _requiresKeyboardWhenFirstResponder] to check if the - current responder should bring up the keyboard, which in turn checks if the responder - supports the UIKeyInput protocol. By dynamically reporting our protocol conformance - we can control the keyboard visibility depending on whether or not we have a focus - object with IME enabled. -*/ -- (BOOL)conformsToProtocol:(Protocol *)protocol -{ - if (protocol == @protocol(UIKeyInput)) - return m_inputContext->inputMethodAccepted(); - - return [super conformsToProtocol:protocol]; -} - // ------------------------------------------------------------------------- - (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties From bed25d8a3a27a439e5a50083be6b7218a8982d3c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Nov 2014 14:08:33 +0100 Subject: [PATCH 29/69] iOS: let focusobject be ImEnabled when a menu is attached MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the picker menu uses IM to set an alternative input view, we also need to specify that we IM is enabled. Task-number: QTBUG-42523 Change-Id: Ia559fbc0ca7e6a1a4499d5eb179baa2d915ecb17 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 005b06547e..f64c1a2f41 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -452,11 +452,11 @@ void QIOSMenu::toggleShowUsingUIPickerView(bool show) Q_ASSERT(!focusObjectWithPickerView); focusObjectWithPickerView = qApp->focusWindow()->focusObject(); focusObjectWithPickerView->installEventFilter(this); - qApp->inputMethod()->update(Qt::ImPlatformData); + qApp->inputMethod()->update(Qt::ImEnabled | Qt::ImPlatformData); } else { Q_ASSERT(focusObjectWithPickerView); focusObjectWithPickerView->removeEventFilter(this); - qApp->inputMethod()->update(Qt::ImPlatformData); + qApp->inputMethod()->update(Qt::ImEnabled | Qt::ImPlatformData); focusObjectWithPickerView = 0; Q_ASSERT(m_pickerView); @@ -477,6 +477,7 @@ bool QIOSMenu::eventFilter(QObject *obj, QEvent *event) imPlatformData.insert(kImePlatformDataInputView, QVariant::fromValue(static_cast(m_pickerView))); imPlatformData.insert(kImePlatformDataInputAccessoryView, QVariant::fromValue(static_cast(m_pickerView.toolbar))); queryEvent->setValue(Qt::ImPlatformData, imPlatformData); + queryEvent->setValue(Qt::ImEnabled, true); return true; } From c506d938a83585d973cbc369e99503cf83db68e2 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 12 Nov 2014 12:28:16 +0100 Subject: [PATCH 30/69] iOS: close menu when keyboard hides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the menu is closed from the keyboard gesture, and the focus object doesn't change, the menu will still be in a visible state, even if the keyboard is hidden. This patch will ensure that this can not be the case by listening for keyboardWillHideNotification. Since we have no guarantee for when the destructor runs, we apply a pessimistic approach and ensure we stop listen when the menu gets closed. Task-number: QTBUG-42523 Change-Id: If734ea32d1823b978c9c1c67ebcc5b6c3c5c338c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.mm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index f64c1a2f41..0f351f785b 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -153,13 +153,29 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; [self setDelegate:self]; [self setDataSource:self]; [self selectRow:m_selectedRow inComponent:0 animated:false]; + [self listenForKeyboardWillHideNotification:YES]; } return self; } +-(void)listenForKeyboardWillHideNotification:(BOOL)listen +{ + if (listen) { + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(cancelMenu) + name:@"UIKeyboardWillHideNotification" object:nil]; + } else { + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIKeyboardWillHideNotification" object:nil]; + } +} + -(void)dealloc { + [self listenForKeyboardWillHideNotification:NO]; self.toolbar = 0; [super dealloc]; } @@ -193,6 +209,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; - (void)closeMenu { + [self listenForKeyboardWillHideNotification:NO]; if (!m_visibleMenuItems.isEmpty()) QIOSMenu::currentMenu()->handleItemSelected(m_visibleMenuItems.at(m_selectedRow)); else @@ -201,6 +218,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; - (void)cancelMenu { + [self listenForKeyboardWillHideNotification:NO]; QIOSMenu::currentMenu()->dismiss(); } From 74ae86a660abfbbdedfad1fe284a79af73fa4b78 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 12 Nov 2014 14:05:10 +0100 Subject: [PATCH 31/69] Doc: corrected autolink issue json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-40362 Change-Id: I851670eea6af80b0bb463f00b147d7a6ef289046 Reviewed-by: Martin Smith Reviewed-by: Topi Reiniö --- src/corelib/json/qjsonarray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index fd407af2cd..73c53ea649 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE removing QJsonValue's from the array. A QJsonArray can be converted to and from a QVariantList. You can query the - number of entries with size(), insert(), and remove() entries from it + number of entries with size(), insert(), and removeAt() entries from it and iterate over its content using the standard C++ iterator pattern. QJsonArray is an implicitly shared class and shares the data with the document From 5c58db516a55d4f6a5e5899617505898ce7bd969 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 12 Nov 2014 13:55:25 +0100 Subject: [PATCH 32/69] Add the custom build step for PCH generated through source This fixes a regression introduced by 04d3a89e20d49a3b5015b071bfdedc81973b090c as it left out the custom build step for the source code file generated for PCH. Task-number: QTBUG-42596 Change-Id: I53d5a36b842dcffbde2657910e6a96dca0e99c7b Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msbuild_objectmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 7effbaa8c4..1f51ff0342 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -1915,10 +1915,10 @@ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, Xml } // Actual XML output ---------------------------------- - if (hasCustomBuildStep || filter.useCompilerTool + if (hasCustomBuildStep || filter.useCustomBuildTool || filter.useCompilerTool || !d->inBuild || filter.Name.startsWith("Deployment Files")) { - if (hasCustomBuildStep) + if (hasCustomBuildStep || filter.useCustomBuildTool) { if (!fileAdded) { fileAdded = true; From 4fc1a100756ee86d96a320490ce747224ba9726a Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 12 Nov 2014 18:44:25 +0200 Subject: [PATCH 33/69] Android: Extract RippleDrawable Task-number: QTBUG-42488 Change-Id: I41fb37adae4664f4a071d794dc4a31a3ee3334aa Reviewed-by: J-P Nurmi --- .../qtproject/qt5/android/ExtractStyle.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index cf05b674d2..c65797a1de 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -95,8 +95,8 @@ public class ExtractStyle { native static int[] extractChunkInfo20(byte[] chunkData); native static int[] extractNativeChunkInfo20(long nativeChunk); - Class styleableClass = getClass("android.R$styleable"); + Class rippleDrawableClass = getClass("android.graphics.drawable.RippleDrawable"); final int[] EMPTY_STATE_SET = {}; final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled}; final int[] FOCUSED_STATE_SET = {android.R.attr.state_focused}; @@ -794,8 +794,27 @@ public class ExtractStyle { } private HashMap m_drawableCache = new HashMap(); + private JSONObject getRippleDrawable(Object drawable, String filename, Rect padding) + { + JSONObject json = getLayerDrawable(drawable, filename); + JSONObject ripple = new JSONObject(); + try { + final Object mState = getAccessibleField(rippleDrawableClass, "mState").get(drawable); + ripple.put("mask", getDrawable((Drawable)getAccessibleField(rippleDrawableClass, "mMask").get(drawable), filename, padding)); + ripple.put("maxRadius", getAccessibleField(mState.getClass(), "mMaxRadius").getInt(mState)); + ripple.put("color", getColorStateList((ColorStateList)getAccessibleField(mState.getClass(), "mColor").get(mState))); + json.put("ripple", ripple); + } catch (Exception e) { + e.printStackTrace(); + } + return json; + } + public JSONObject getDrawable(Object drawable, String filename, Rect padding) { + if (drawable == null) + return null; + DrawableCache dc = m_drawableCache.get(filename); if (dc != null) { @@ -833,6 +852,9 @@ public class ExtractStyle { } else { + + if (rippleDrawableClass != null && rippleDrawableClass.isInstance(drawable)) + return getRippleDrawable(drawable, filename, padding); if (drawable instanceof ScaleDrawable) { return getDrawable(((ScaleDrawable)drawable).getDrawable(), filename, null); From adf1b30934f2b2b92271955e7867a7b2620bc6b9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 10 Nov 2014 18:19:45 -0800 Subject: [PATCH 34/69] Make QVersionNumber private We're not ready. [ChangeLog][EDITORIAL] Remove all mentions of QVersionNumber. Change-Id: I03ad95992982eb3177f982c1eeddb6a6bc29336c Reviewed-by: Keith Gardner Reviewed-by: Lars Knoll --- src/corelib/tools/qversionnumber.cpp | 3 ++- src/corelib/tools/{qversionnumber.h => qversionnumber_p.h} | 0 src/testlib/qtest.h | 6 ------ src/testlib/qtestcase.cpp | 7 ------- tests/auto/corelib/tools/qversionnumber/qversionnumber.pro | 2 +- .../corelib/tools/qversionnumber/tst_qversionnumber.cpp | 2 +- 6 files changed, 4 insertions(+), 16 deletions(-) rename src/corelib/tools/{qversionnumber.h => qversionnumber_p.h} (100%) diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index 4d148249c0..3c8a9db086 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -40,7 +40,7 @@ ** ****************************************************************************/ -#include +#include #include #include #include @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE /*! \class QVersionNumber \inmodule QtCore + \internal \since 5.4 \brief The QVersionNumber class contains a version number with an arbitrary number of segments. diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber_p.h similarity index 100% rename from src/corelib/tools/qversionnumber.h rename to src/corelib/tools/qversionnumber_p.h diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index d3443e7390..6298262958 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -164,11 +163,6 @@ template<> inline char *toString(const QVariant &v) return qstrdup(vstring.constData()); } -template<> inline char *toString(const QVersionNumber &version) -{ - return toString(version.toString()); -} - template<> inline bool qCompare(QString const &t1, QLatin1String const &t2, const char *actual, const char *expected, const char *file, int line) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 2d92b3f6bd..b174913eae 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1027,13 +1027,6 @@ QT_BEGIN_NAMESPACE Returns a textual representation of the given \a variant. */ -/*! - \fn char *QTest::toString(const QVersionNumber &version) - \overload - - Returns a textual representation of the given \a version. -*/ - /*! \fn void QTest::qWait(int ms) Waits for \a ms milliseconds. While waiting, events will be processed and diff --git a/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro b/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro index 08ee0dd3d9..1e74d42bbd 100644 --- a/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro +++ b/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro @@ -1,4 +1,4 @@ CONFIG += testcase parallel_test TARGET = tst_qversionnumber -QT = core testlib +QT = core-private testlib SOURCES = tst_qversionnumber.cpp diff --git a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp index 18bc86620a..f97b8a4df8 100644 --- a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp +++ b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp @@ -33,7 +33,7 @@ ****************************************************************************/ #include -#include +#include class tst_QVersionNumber : public QObject { From 32db2f425a0b85bc03d7de42d7b44337d0aa16f4 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 14 Nov 2014 11:29:30 +0200 Subject: [PATCH 35/69] windows: fix platform compilation after ANGLE upgrade Upstream changed how WARP is meant to interact with EGL, and so the enum names changed. Change-Id: I10d4bcac71b75a1223ea8af4d3fcf584f5685a02 Reviewed-by: Kai Koehne Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowseglcontext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 3b277c0b5a..c0d0c1f77c 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -360,10 +360,10 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create() EGLDisplay display = EGL_NO_DISPLAY; #ifdef EGL_ANGLE_platform_angle_opengl if (libEGL.eglGetPlatformDisplayEXT && qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) { - const EGLint anglePlatformAttributes[][3] = { + const EGLint anglePlatformAttributes[][5] = { { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE }, { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_NONE }, - { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE, EGL_NONE } + { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, EGL_NONE } }; const EGLint *attributes = 0; const QByteArray anglePlatform = qgetenv("QT_ANGLE_PLATFORM"); From c6df5fe3ed0f2a722931be098914978cf17a666f Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 14 Nov 2014 10:52:01 +0200 Subject: [PATCH 36/69] ANGLE: Upgrade to version 1.2.30d6c255d238 The following patches have been changed: 0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch Removed because it is no longer possible to build ANGLE with MSVC2008 0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch Removed because the minimum version of MinGW moved to 4.8.2 0005-Fix-build-when-SSE2-is-not-available.patch Removed because it was fixed upstream 0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch Removed because older versions of MinGW are not supported 0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch Removed because it was fixed upstream Task-number: QTBUG-41903 Change-Id: I976d30802f7f6fee725cf9a9f1325d5e82609835 Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne Reviewed-by: Oliver Wolff --- src/3rdparty/angle/AUTHORS | 2 + src/3rdparty/angle/CONTRIBUTORS | 5 + src/3rdparty/angle/include/EGL/egl.h | 2 +- src/3rdparty/angle/include/EGL/eglext.h | 16 +- src/3rdparty/angle/include/EGL/eglplatform.h | 19 +- .../angle/include/GLSLANG/ShaderLang.h | 210 +- .../angle/include/GLSLANG/ShaderVars.h | 64 +- .../angle/include/angle_windowsstore.h | 37 + src/3rdparty/angle/src/commit.h | 4 +- src/3rdparty/angle/src/common/NativeWindow.h | 77 + src/3rdparty/angle/src/common/angleutils.cpp | 35 +- src/3rdparty/angle/src/common/angleutils.h | 11 + src/3rdparty/angle/src/common/debug.cpp | 246 +- src/3rdparty/angle/src/common/debug.h | 19 +- src/3rdparty/angle/src/common/features.h | 35 + src/3rdparty/angle/src/common/mathutil.h | 4 +- src/3rdparty/angle/src/common/platform.h | 89 +- src/3rdparty/angle/src/common/tls.cpp | 107 +- src/3rdparty/angle/src/common/tls.h | 17 +- src/3rdparty/angle/src/common/utilities.cpp | 89 +- src/3rdparty/angle/src/common/utilities.h | 6 + .../angle/src/common/win32/NativeWindow.cpp | 66 + .../common/winrt/CoreWindowNativeWindow.cpp | 200 ++ .../src/common/winrt/CoreWindowNativeWindow.h | 39 + .../common/winrt/InspectableNativeWindow.cpp | 274 +++ .../common/winrt/InspectableNativeWindow.h | 91 + .../winrt/SwapChainPanelNativeWindow.cpp | 226 ++ .../common/winrt/SwapChainPanelNativeWindow.h | 79 + .../preprocessor/DirectiveHandlerBase.h | 3 +- .../compiler/preprocessor/DirectiveParser.cpp | 35 +- .../compiler/preprocessor/MacroExpander.cpp | 4 +- .../src/compiler/translator/Compiler.cpp | 63 +- .../angle/src/compiler/translator/Compiler.h | 10 +- .../translator/DetectDiscontinuity.cpp | 52 + .../compiler/translator/DetectDiscontinuity.h | 19 + .../compiler/translator/DirectiveHandler.cpp | 79 +- .../compiler/translator/DirectiveHandler.h | 3 +- .../src/compiler/translator/IntermNode.cpp | 76 + .../src/compiler/translator/IntermNode.h | 5 + .../src/compiler/translator/Intermediate.cpp | 1 + .../compiler/translator/OutputGLSLBase.cpp | 18 +- .../src/compiler/translator/OutputHLSL.cpp | 59 +- .../src/compiler/translator/OutputHLSL.h | 1 + .../src/compiler/translator/ParseContext.cpp | 13 +- .../src/compiler/translator/ParseContext.h | 2 +- .../angle/src/compiler/translator/Pragma.h | 12 +- .../src/compiler/translator/ShaderLang.cpp | 371 +-- .../src/compiler/translator/ShaderVars.cpp | 165 ++ .../src/compiler/translator/SymbolTable.h | 41 +- .../compiler/translator/TranslatorESSL.cpp | 11 +- .../compiler/translator/TranslatorGLSL.cpp | 30 +- .../src/compiler/translator/TranslatorGLSL.h | 12 +- .../translator/ValidateLimitations.cpp | 1 + .../src/compiler/translator/VariableInfo.cpp | 81 +- .../src/compiler/translator/VariableInfo.h | 17 +- .../src/compiler/translator/VersionGLSL.cpp | 16 +- .../src/compiler/translator/VersionGLSL.h | 4 +- .../angle/src/compiler/translator/glslang.y | 34 +- .../src/compiler/translator/intermOut.cpp | 6 +- .../angle/src/compiler/translator/util.cpp | 47 +- .../angle/src/compiler/translator/util.h | 12 +- .../angle/src/libEGL/AttributeMap.cpp | 40 + src/3rdparty/angle/src/libEGL/AttributeMap.h | 33 + src/3rdparty/angle/src/libEGL/Display.cpp | 171 +- src/3rdparty/angle/src/libEGL/Display.h | 22 +- src/3rdparty/angle/src/libEGL/Error.cpp | 48 + src/3rdparty/angle/src/libEGL/Error.h | 39 + src/3rdparty/angle/src/libEGL/Surface.cpp | 341 +-- src/3rdparty/angle/src/libEGL/Surface.h | 60 +- src/3rdparty/angle/src/libEGL/libEGL.cpp | 469 ++-- src/3rdparty/angle/src/libEGL/main.cpp | 40 +- src/3rdparty/angle/src/libEGL/main.h | 22 +- .../angle/src/libGLESv2/BinaryStream.h | 12 +- src/3rdparty/angle/src/libGLESv2/Buffer.h | 1 - src/3rdparty/angle/src/libGLESv2/Context.cpp | 865 +------ src/3rdparty/angle/src/libGLESv2/Context.h | 62 +- src/3rdparty/angle/src/libGLESv2/Data.cpp | 51 + src/3rdparty/angle/src/libGLESv2/Data.h | 38 + src/3rdparty/angle/src/libGLESv2/Fence.cpp | 176 +- src/3rdparty/angle/src/libGLESv2/Fence.h | 35 +- .../angle/src/libGLESv2/Framebuffer.cpp | 277 +-- .../angle/src/libGLESv2/Framebuffer.h | 50 +- .../src/libGLESv2/FramebufferAttachment.cpp | 2 +- .../src/libGLESv2/FramebufferAttachment.h | 7 - .../angle/src/libGLESv2/ImageIndex.cpp | 91 + src/3rdparty/angle/src/libGLESv2/ImageIndex.h | 29 +- src/3rdparty/angle/src/libGLESv2/Program.cpp | 24 +- src/3rdparty/angle/src/libGLESv2/Program.h | 5 +- .../angle/src/libGLESv2/ProgramBinary.cpp | 2098 ++--------------- .../angle/src/libGLESv2/ProgramBinary.h | 133 +- .../angle/src/libGLESv2/Renderbuffer.cpp | 235 +- .../angle/src/libGLESv2/Renderbuffer.h | 113 +- .../angle/src/libGLESv2/ResourceManager.cpp | 16 +- .../angle/src/libGLESv2/ResourceManager.h | 7 +- src/3rdparty/angle/src/libGLESv2/Shader.cpp | 10 +- src/3rdparty/angle/src/libGLESv2/Shader.h | 4 +- src/3rdparty/angle/src/libGLESv2/State.cpp | 125 +- src/3rdparty/angle/src/libGLESv2/State.h | 26 +- src/3rdparty/angle/src/libGLESv2/Texture.cpp | 199 +- src/3rdparty/angle/src/libGLESv2/Texture.h | 74 +- .../angle/src/libGLESv2/VertexArray.h | 5 +- .../angle/src/libGLESv2/angletypes.cpp | 21 +- src/3rdparty/angle/src/libGLESv2/angletypes.h | 16 +- .../angle/src/libGLESv2/libGLESv2.cpp | 1045 ++++---- src/3rdparty/angle/src/libGLESv2/main.cpp | 101 +- src/3rdparty/angle/src/libGLESv2/main.h | 21 +- .../angle/src/libGLESv2/renderer/BufferImpl.h | 3 +- .../angle/src/libGLESv2/renderer/FenceImpl.h | 36 +- .../angle/src/libGLESv2/renderer/Image.cpp | 22 +- .../angle/src/libGLESv2/renderer/Image.h | 25 +- .../libGLESv2/renderer/IndexRangeCache.cpp | 4 - .../src/libGLESv2/renderer/ProgramImpl.cpp | 146 ++ .../src/libGLESv2/renderer/ProgramImpl.h | 119 +- .../src/libGLESv2/renderer/RenderTarget.cpp | 36 + .../src/libGLESv2/renderer/RenderTarget.h | 41 +- .../libGLESv2/renderer/RenderbufferImpl.cpp | 21 + .../src/libGLESv2/renderer/RenderbufferImpl.h | 41 + .../angle/src/libGLESv2/renderer/Renderer.cpp | 47 +- .../angle/src/libGLESv2/renderer/Renderer.h | 307 +-- .../src/libGLESv2/renderer/ShaderExecutable.h | 13 +- .../angle/src/libGLESv2/renderer/ShaderImpl.h | 3 +- .../angle/src/libGLESv2/renderer/SwapChain.h | 25 +- .../src/libGLESv2/renderer/TextureImpl.h | 24 +- .../src/libGLESv2/renderer/Workarounds.h | 39 + .../src/libGLESv2/renderer/copyimage.cpp | 2 +- .../src/libGLESv2/renderer/d3d/BufferD3D.cpp | 12 +- .../src/libGLESv2/renderer/d3d/BufferD3D.h | 17 +- .../libGLESv2/renderer/d3d/DynamicHLSL.cpp | 68 +- .../src/libGLESv2/renderer/d3d/DynamicHLSL.h | 35 +- .../libGLESv2/renderer/d3d/HLSLCompiler.cpp | 255 +- .../src/libGLESv2/renderer/d3d/HLSLCompiler.h | 28 +- .../src/libGLESv2/renderer/d3d/ImageD3D.cpp | 4 +- .../src/libGLESv2/renderer/d3d/ImageD3D.h | 15 +- .../libGLESv2/renderer/d3d/IndexBuffer.cpp | 8 +- .../src/libGLESv2/renderer/d3d/IndexBuffer.h | 10 +- .../renderer/d3d/IndexDataManager.cpp | 24 +- .../libGLESv2/renderer/d3d/IndexDataManager.h | 6 +- .../src/libGLESv2/renderer/d3d/ProgramD3D.cpp | 1814 +++++++++++++- .../src/libGLESv2/renderer/d3d/ProgramD3D.h | 180 +- .../renderer/d3d/RenderbufferD3D.cpp | 108 + .../libGLESv2/renderer/d3d/RenderbufferD3D.h | 51 + .../libGLESv2/renderer/d3d/RendererD3D.cpp | 796 +++++++ .../src/libGLESv2/renderer/d3d/RendererD3D.h | 195 ++ .../src/libGLESv2/renderer/d3d/ShaderD3D.cpp | 118 +- .../src/libGLESv2/renderer/d3d/ShaderD3D.h | 22 +- .../src/libGLESv2/renderer/d3d/TextureD3D.cpp | 1723 +++++++++----- .../src/libGLESv2/renderer/d3d/TextureD3D.h | 227 +- .../libGLESv2/renderer/d3d/TextureStorage.cpp | 18 +- .../libGLESv2/renderer/d3d/TextureStorage.h | 21 +- .../libGLESv2/renderer/d3d/VertexBuffer.cpp | 12 +- .../src/libGLESv2/renderer/d3d/VertexBuffer.h | 10 +- .../renderer/d3d/VertexDataManager.cpp | 36 +- .../renderer/d3d/VertexDataManager.h | 13 +- .../libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 110 +- .../src/libGLESv2/renderer/d3d/d3d11/Blit11.h | 38 +- .../libGLESv2/renderer/d3d/d3d11/Buffer11.cpp | 88 +- .../libGLESv2/renderer/d3d/d3d11/Buffer11.h | 8 +- .../libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 19 +- .../libGLESv2/renderer/d3d/d3d11/Clear11.h | 2 +- .../libGLESv2/renderer/d3d/d3d11/Fence11.cpp | 220 +- .../libGLESv2/renderer/d3d/d3d11/Fence11.h | 48 +- .../libGLESv2/renderer/d3d/d3d11/Image11.cpp | 563 +++-- .../libGLESv2/renderer/d3d/d3d11/Image11.h | 40 +- .../renderer/d3d/d3d11/IndexBuffer11.h | 2 +- .../renderer/d3d/d3d11/InputLayoutCache.cpp | 14 +- .../renderer/d3d/d3d11/PixelTransfer11.cpp | 126 +- .../renderer/d3d/d3d11/PixelTransfer11.h | 12 +- .../libGLESv2/renderer/d3d/d3d11/Query11.cpp | 3 +- .../libGLESv2/renderer/d3d/d3d11/Query11.h | 4 +- .../renderer/d3d/d3d11/RenderStateCache.cpp | 15 +- .../renderer/d3d/d3d11/RenderStateCache.h | 3 +- .../renderer/d3d/d3d11/RenderTarget11.cpp | 439 ++-- .../renderer/d3d/d3d11/RenderTarget11.h | 84 +- .../renderer/d3d/d3d11/Renderer11.cpp | 1388 ++++++----- .../libGLESv2/renderer/d3d/d3d11/Renderer11.h | 160 +- .../renderer/d3d/d3d11/SwapChain11.cpp | 169 +- .../renderer/d3d/d3d11/SwapChain11.h | 10 +- .../renderer/d3d/d3d11/TextureStorage11.cpp | 1935 ++++++++------- .../renderer/d3d/d3d11/TextureStorage11.h | 187 +- .../renderer/d3d/d3d11/VertexArray11.h | 4 +- .../renderer/d3d/d3d11/VertexBuffer11.cpp | 13 +- .../renderer/d3d/d3d11/VertexBuffer11.h | 4 +- .../renderer/d3d/d3d11/formatutils11.cpp | 2 +- .../renderer/d3d/d3d11/renderer11_utils.cpp | 94 +- .../renderer/d3d/d3d11/renderer11_utils.h | 6 +- .../src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp | 231 +- .../src/libGLESv2/renderer/d3d/d3d9/Blit9.h | 32 +- .../libGLESv2/renderer/d3d/d3d9/Buffer9.cpp | 13 +- .../src/libGLESv2/renderer/d3d/d3d9/Buffer9.h | 8 +- .../libGLESv2/renderer/d3d/d3d9/Fence9.cpp | 63 +- .../src/libGLESv2/renderer/d3d/d3d9/Fence9.h | 19 +- .../libGLESv2/renderer/d3d/d3d9/Image9.cpp | 706 +++--- .../src/libGLESv2/renderer/d3d/d3d9/Image9.h | 43 +- .../renderer/d3d/d3d9/IndexBuffer9.h | 2 +- .../libGLESv2/renderer/d3d/d3d9/Query9.cpp | 2 +- .../src/libGLESv2/renderer/d3d/d3d9/Query9.h | 4 +- .../renderer/d3d/d3d9/RenderTarget9.cpp | 177 +- .../renderer/d3d/d3d9/RenderTarget9.h | 60 +- .../libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 790 ++++--- .../libGLESv2/renderer/d3d/d3d9/Renderer9.h | 134 +- .../libGLESv2/renderer/d3d/d3d9/ShaderCache.h | 12 +- .../renderer/d3d/d3d9/SwapChain9.cpp | 26 +- .../libGLESv2/renderer/d3d/d3d9/SwapChain9.h | 7 +- .../renderer/d3d/d3d9/TextureStorage9.cpp | 431 ++-- .../renderer/d3d/d3d9/TextureStorage9.h | 46 +- .../renderer/d3d/d3d9/VertexArray9.h | 4 +- .../renderer/d3d/d3d9/VertexBuffer9.cpp | 16 +- .../renderer/d3d/d3d9/VertexBuffer9.h | 4 +- .../renderer/d3d/d3d9/renderer9_utils.cpp | 28 +- .../renderer/d3d/d3d9/renderer9_utils.h | 5 +- .../src/libGLESv2/renderer/loadimageSSE2.cpp | 18 +- .../angle/src/libGLESv2/validationES.cpp | 66 +- .../angle/src/libGLESv2/validationES3.cpp | 23 +- .../src/third_party/systeminfo/SystemInfo.cpp | 5 + .../0000-General-fixes-for-ANGLE-2.1.patch | 1192 +--------- ...pilation-for-MSVC-2008-and-std-tuple.patch | 31 - ...-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch | 33 - ...-to-link-ANGLE-statically-for-single.patch | 31 +- ...Fix-build-when-SSE2-is-not-available.patch | 84 - ...of-libGLESv2-with-older-MinGW-w64-he.patch | 49 - ...-with-Microsoft-Visual-Studio-14-CTP.patch | 28 - ...y-load-D3D-compiler-from-a-list-or-t.patch | 37 +- .../patches/0009-ANGLE-Support-WinRT.patch | 1921 ++++++--------- ...able-D3D11-for-feature-level-9-cards.patch | 268 ++- ...0012-ANGLE-fix-semantic-index-lookup.patch | 16 +- ...support-for-querying-platform-device.patch | 31 +- ...e-multithreaded-devices-if-necessary.patch | 37 +- ...15-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch | 309 ++- ...GLE-Fix-compilation-with-MinGW-D3D11.patch | 322 +-- src/angle/src/libEGL/libEGL.pro | 20 + src/angle/src/libGLESv2/libGLESv2.pro | 26 +- 231 files changed, 16959 insertions(+), 13672 deletions(-) create mode 100644 src/3rdparty/angle/include/angle_windowsstore.h create mode 100644 src/3rdparty/angle/src/common/NativeWindow.h create mode 100644 src/3rdparty/angle/src/common/features.h create mode 100644 src/3rdparty/angle/src/common/win32/NativeWindow.cpp create mode 100644 src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp create mode 100644 src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h create mode 100644 src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp create mode 100644 src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h create mode 100644 src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp create mode 100644 src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h create mode 100644 src/3rdparty/angle/src/libEGL/AttributeMap.cpp create mode 100644 src/3rdparty/angle/src/libEGL/AttributeMap.h create mode 100644 src/3rdparty/angle/src/libEGL/Error.cpp create mode 100644 src/3rdparty/angle/src/libEGL/Error.h create mode 100644 src/3rdparty/angle/src/libGLESv2/Data.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/Data.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h delete mode 100644 src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch delete mode 100644 src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch delete mode 100644 src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch delete mode 100644 src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch delete mode 100644 src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch diff --git a/src/3rdparty/angle/AUTHORS b/src/3rdparty/angle/AUTHORS index b79bb5d161..be114bcf68 100644 --- a/src/3rdparty/angle/AUTHORS +++ b/src/3rdparty/angle/AUTHORS @@ -21,10 +21,12 @@ Mozilla Corporation Turbulenz Klarälvdalens Datakonsult AB Microsoft Open Technologies, Inc. +NVIDIA Corporation Jacek Caban Mark Callow Ginn Chen +Tibor den Ouden James Hauxwell Sam Hocevar Pierre Leveille diff --git a/src/3rdparty/angle/CONTRIBUTORS b/src/3rdparty/angle/CONTRIBUTORS index 0cae10a0f6..94d009f2b3 100644 --- a/src/3rdparty/angle/CONTRIBUTORS +++ b/src/3rdparty/angle/CONTRIBUTORS @@ -78,7 +78,12 @@ Turbulenz Ulrik Persson (ddefrostt) Mark Banner (standard8mbp) David Kilzer +Jacek Caban +Tibor den Ouden Microsoft Open Technologies, Inc. Cooper Partin Austin Kinross + +NVIDIA Corporation + Olli Etuaho diff --git a/src/3rdparty/angle/include/EGL/egl.h b/src/3rdparty/angle/include/EGL/egl.h index ab2f0cdfbe..12590a0e20 100644 --- a/src/3rdparty/angle/include/EGL/egl.h +++ b/src/3rdparty/angle/include/EGL/egl.h @@ -238,7 +238,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); #ifndef EGL_VERSION_1_5 #define EGL_VERSION_1_5 1 typedef void *EGLSync; -typedef khronos_intptr_t EGLAttrib; +typedef intptr_t EGLAttrib; typedef khronos_utime_nanoseconds_t EGLTime; #define EGL_CONTEXT_MAJOR_VERSION 0x3098 #define EGL_CONTEXT_MINOR_VERSION 0x30FB diff --git a/src/3rdparty/angle/include/EGL/eglext.h b/src/3rdparty/angle/include/EGL/eglext.h index 989359b026..0cc5eec293 100644 --- a/src/3rdparty/angle/include/EGL/eglext.h +++ b/src/3rdparty/angle/include/EGL/eglext.h @@ -59,7 +59,7 @@ extern "C" { #ifndef EGL_KHR_cl_event2 #define EGL_KHR_cl_event2 1 typedef void *EGLSyncKHR; -typedef khronos_intptr_t EGLAttribKHR; +typedef intptr_t EGLAttribKHR; typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); @@ -442,20 +442,22 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_ANGLE_platform_angle 1 #define EGL_PLATFORM_ANGLE_ANGLE 0x3201 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202 -#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3203 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3204 +#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3205 #endif /* EGL_ANGLE_platform_angle */ #ifndef EGL_ANGLE_platform_angle_d3d #define EGL_ANGLE_platform_angle_d3d 1 -#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3204 -#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205 -#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206 +#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207 +#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208 #endif /* EGL_ANGLE_platform_angle_d3d */ #ifndef EGL_ANGLE_platform_angle_opengl #define EGL_ANGLE_platform_angle_opengl 1 -#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3207 -#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208 +#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3209 +#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A #endif /* EGL_ANGLE_platform_angle_opengl */ #ifndef EGL_ARM_pixmap_multisample_discard diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h index ea9f5778ee..2eb3674a0b 100644 --- a/src/3rdparty/angle/include/EGL/eglplatform.h +++ b/src/3rdparty/angle/include/EGL/eglplatform.h @@ -67,23 +67,22 @@ * implementations. */ -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */ - -struct IUnknown; - -typedef IUnknown *EGLNativeDisplayType; -typedef void *EGLNativePixmapType; -typedef IUnknown *EGLNativeWindowType; - -#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif #include -typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; + +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */ +#include +typedef IInspectable* EGLNativeDisplayType; +typedef IInspectable* EGLNativeWindowType; +#else +typedef HDC EGLNativeDisplayType; typedef HWND EGLNativeWindowType; +#endif #elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h index b7989f5f7e..647fed6a02 100644 --- a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h +++ b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h @@ -27,6 +27,10 @@ #include "KHR/khrplatform.h" +#include +#include +#include + // // This is the platform independent interface between an OGL driver // and the shading language compiler. @@ -42,18 +46,17 @@ typedef unsigned int GLenum; // Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h #include "ShaderVars.h" -#ifdef __cplusplus -extern "C" { -#endif - // Version number for shader translation API. // It is incremented every time the API changes. -#define ANGLE_SH_VERSION 130 +#define ANGLE_SH_VERSION 132 typedef enum { SH_GLES2_SPEC = 0x8B40, SH_WEBGL_SPEC = 0x8B41, + SH_GLES3_SPEC = 0x8B86, + SH_WEBGL2_SPEC = 0x8B87, + // The CSS Shaders spec is a subset of the WebGL spec. // // In both CSS vertex and fragment shaders, ANGLE: @@ -85,31 +88,6 @@ typedef enum { SH_HLSL11_OUTPUT = 0x8B48 } ShShaderOutput; -typedef enum { - SH_PRECISION_HIGHP = 0x5001, - SH_PRECISION_MEDIUMP = 0x5002, - SH_PRECISION_LOWP = 0x5003, - SH_PRECISION_UNDEFINED = 0 -} ShPrecisionType; - -typedef enum { - SH_INFO_LOG_LENGTH = 0x8B84, - SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH - SH_ACTIVE_UNIFORMS = 0x8B86, - SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, - SH_ACTIVE_ATTRIBUTES = 0x8B89, - SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, - SH_VARYINGS = 0x8BBB, - SH_VARYING_MAX_LENGTH = 0x8BBC, - SH_MAPPED_NAME_MAX_LENGTH = 0x6000, - SH_NAME_MAX_LENGTH = 0x6001, - SH_HASHED_NAME_MAX_LENGTH = 0x6002, - SH_HASHED_NAMES_COUNT = 0x6003, - SH_SHADER_VERSION = 0x6004, - SH_RESOURCES_STRING_LENGTH = 0x6005, - SH_OUTPUT_TYPE = 0x6006 -} ShShaderInfo; - // Compile options. typedef enum { SH_VALIDATE = 0, @@ -208,14 +186,14 @@ typedef enum { // // Driver must call this first, once, before doing any other // compiler operations. -// If the function succeeds, the return value is nonzero, else zero. +// If the function succeeds, the return value is true, else false. // -COMPILER_EXPORT int ShInitialize(); +COMPILER_EXPORT bool ShInitialize(); // // Driver should call this at shutdown. -// If the function succeeds, the return value is nonzero, else zero. +// If the function succeeds, the return value is true, else false. // -COMPILER_EXPORT int ShFinalize(); +COMPILER_EXPORT bool ShFinalize(); // The 64 bits hash function. The first parameter is the input string; the // second parameter is the string length. @@ -246,6 +224,12 @@ typedef struct int EXT_frag_depth; int EXT_shader_texture_lod; + // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives + // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate + // EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers + // function. This applies to Tegra K1 devices. + int NV_draw_buffers; + // Set to 1 if highp precision is supported in the fragment language. // Default is 0. int FragmentPrecisionHigh; @@ -274,8 +258,10 @@ typedef struct // // Initialize built-in resources with minimum expected values. +// Parameters: +// resources: The object to initialize. Will be comparable with memcmp. // -COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources); +COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources); // // ShHandle held by but opaque to the driver. It is allocated, @@ -284,18 +270,15 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources); // // If handle creation fails, 0 will be returned. // -typedef void* ShHandle; +typedef void *ShHandle; // -// Returns the a concatenated list of the items in ShBuiltInResources as a string. +// Returns the a concatenated list of the items in ShBuiltInResources as a +// null-terminated string. // This function must be updated whenever ShBuiltInResources is changed. // Parameters: // handle: Specifies the handle of the compiler to be used. -// outStringLen: Specifies the size of the buffer, in number of characters. The size -// of the buffer required to store the resources string can be obtained -// by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH. -// outStr: Returns a null-terminated string representing all the built-in resources. -COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr); +COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle); // // Driver calls these to create and destroy compiler objects. @@ -313,12 +296,12 @@ COMPILER_EXPORT ShHandle ShConstructCompiler( sh::GLenum type, ShShaderSpec spec, ShShaderOutput output, - const ShBuiltInResources* resources); + const ShBuiltInResources *resources); COMPILER_EXPORT void ShDestruct(ShHandle handle); // // Compiles the given shader source. -// If the function succeeds, the return value is nonzero, else zero. +// If the function succeeds, the return value is true, else false. // Parameters: // handle: Specifies the handle of compiler to be used. // shaderStrings: Specifies an array of pointers to null-terminated strings @@ -340,123 +323,36 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle); // SH_VARIABLES: Extracts attributes, uniforms, and varyings. // Can be queried by calling ShGetVariableInfo(). // -COMPILER_EXPORT int ShCompile( +COMPILER_EXPORT bool ShCompile( const ShHandle handle, - const char* const shaderStrings[], + const char * const shaderStrings[], size_t numStrings, - int compileOptions - ); + int compileOptions); -// Returns a parameter from a compiled shader. +// Return the version of the shader language. +COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle); + +// Return the currently set language output type. +COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType( + const ShHandle handle); + +// Returns null-terminated information log for a compiled shader. // Parameters: // handle: Specifies the compiler -// pname: Specifies the parameter to query. -// The following parameters are defined: -// SH_INFO_LOG_LENGTH: the number of characters in the information log -// including the null termination character. -// SH_OBJECT_CODE_LENGTH: the number of characters in the object code -// including the null termination character. -// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables. -// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute -// variable name including the null -// termination character. -// SH_ACTIVE_UNIFORMS: the number of active uniform variables. -// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform -// variable name including the null -// termination character. -// SH_VARYINGS: the number of varying variables. -// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name -// including the null termination character. -// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including -// the null termination character. -// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the -// null termination character. -// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the -// null termination character. -// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile. -// SH_SHADER_VERSION: the version of the shader language -// SH_OUTPUT_TYPE: the currently set language output type -// -// params: Requested parameter -COMPILER_EXPORT void ShGetInfo(const ShHandle handle, - ShShaderInfo pname, - size_t* params); - -// Returns nul-terminated information log for a compiled shader. -// Parameters: -// handle: Specifies the compiler -// infoLog: Specifies an array of characters that is used to return -// the information log. It is assumed that infoLog has enough memory -// to accomodate the information log. The size of the buffer required -// to store the returned information log can be obtained by calling -// ShGetInfo with SH_INFO_LOG_LENGTH. -COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog); +COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle); // Returns null-terminated object code for a compiled shader. // Parameters: // handle: Specifies the compiler -// infoLog: Specifies an array of characters that is used to return -// the object code. It is assumed that infoLog has enough memory to -// accomodate the object code. The size of the buffer required to -// store the returned object code can be obtained by calling -// ShGetInfo with SH_OBJECT_CODE_LENGTH. -COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode); +COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle); -// Returns information about a shader variable. +// Returns a (original_name, hash) map containing all the user defined +// names in the shader, including variable names, function names, struct +// names, and struct field names. // Parameters: // handle: Specifies the compiler -// variableType: Specifies the variable type; options include -// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS. -// index: Specifies the index of the variable to be queried. -// length: Returns the number of characters actually written in the string -// indicated by name (excluding the null terminator) if a value other -// than NULL is passed. -// size: Returns the size of the variable. -// type: Returns the data type of the variable. -// precision: Returns the precision of the variable. -// staticUse: Returns 1 if the variable is accessed in a statement after -// pre-processing, whether or not run-time flow of control will -// cause that statement to be executed. -// Returns 0 otherwise. -// name: Returns a null terminated string containing the name of the -// variable. It is assumed that name has enough memory to accormodate -// the variable name. The size of the buffer required to store the -// variable name can be obtained by calling ShGetInfo with -// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH, -// SH_VARYING_MAX_LENGTH. -// mappedName: Returns a null terminated string containing the mapped name of -// the variable, It is assumed that mappedName has enough memory -// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the -// mapped name. If the name is not mapped, then name and mappedName -// are the same. -COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle, - ShShaderInfo variableType, - int index, - size_t* length, - int* size, - sh::GLenum* type, - ShPrecisionType* precision, - int* staticUse, - char* name, - char* mappedName); - -// Returns information about a name hashing entry from the latest compile. -// Parameters: -// handle: Specifies the compiler -// index: Specifies the index of the name hashing entry to be queried. -// name: Returns a null terminated string containing the user defined name. -// It is assumed that name has enough memory to accomodate the name. -// The size of the buffer required to store the user defined name can -// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH. -// hashedName: Returns a null terminated string containing the hashed name of -// the uniform variable, It is assumed that hashedName has enough -// memory to accomodate the name. The size of the buffer required -// to store the name can be obtained by calling ShGetInfo with -// SH_HASHED_NAME_MAX_LENGTH. -COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle, - int index, - char* name, - char* hashedName); +COMPILER_EXPORT const std::map *ShGetNameHashingMap( + const ShHandle handle); // Shader variable inspection. // Returns a pointer to a list of variables of the designated type. @@ -476,17 +372,17 @@ typedef struct int size; } ShVariableInfo; -// Returns 1 if the passed in variables pack in maxVectors following +// Returns true if the passed in variables pack in maxVectors following // the packing rules from the GLSL 1.017 spec, Appendix A, section 7. -// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS +// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS // flag above. // Parameters: // maxVectors: the available rows of registers. // varInfoArray: an array of variable info (types and sizes). // varInfoArraySize: the size of the variable array. -COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits( +COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits( int maxVectors, - ShVariableInfo* varInfoArray, + ShVariableInfo *varInfoArray, size_t varInfoArraySize); // Gives the compiler-assigned register for an interface block. @@ -497,7 +393,7 @@ COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits( // interfaceBlockName: Specifies the interface block // indexOut: output variable that stores the assigned register COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle, - const char *interfaceBlockName, + const std::string &interfaceBlockName, unsigned int *indexOut); // Gives the compiler-assigned register for uniforms in the default @@ -509,11 +405,7 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle, // interfaceBlockName: Specifies the uniform // indexOut: output variable that stores the assigned register COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle, - const char *uniformName, + const std::string &uniformName, unsigned int *indexOut); -#ifdef __cplusplus -} -#endif - #endif // _COMPILER_INTERFACE_INCLUDED_ diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h index 9c38647dda..da21c3e76e 100644 --- a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h +++ b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h @@ -52,6 +52,21 @@ struct COMPILER_EXPORT ShaderVariable unsigned int elementCount() const { return std::max(1u, arraySize); } bool isStruct() const { return !fields.empty(); } + // All of the shader's variables are described using nested data + // structures. This is needed in order to disambiguate similar looking + // types, such as two structs containing the same fields, but in + // different orders. "findInfoByMappedName" provides an easy query for + // users to dive into the data structure and fetch the unique variable + // instance corresponding to a dereferencing chain of the top-level + // variable. + // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable + // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]' + // in |originalName|, based on the assumption that |this| defines 'a'. + // If no match is found, return false. + bool findInfoByMappedName(const std::string &mappedFullName, + const ShaderVariable **leafVar, + std::string* originalFullName) const; + GLenum type; GLenum precision; std::string name; @@ -60,6 +75,16 @@ struct COMPILER_EXPORT ShaderVariable bool staticUse; std::vector fields; std::string structName; + + protected: + bool isSameVariableAtLinkTime(const ShaderVariable &other, + bool matchPrecision) const; + + bool operator==(const ShaderVariable &other) const; + bool operator!=(const ShaderVariable &other) const + { + return !operator==(other); + } }; struct COMPILER_EXPORT Uniform : public ShaderVariable @@ -68,6 +93,16 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable ~Uniform(); Uniform(const Uniform &other); Uniform &operator=(const Uniform &other); + bool operator==(const Uniform &other) const; + bool operator!=(const Uniform &other) const + { + return !operator==(other); + } + + // Decide whether two uniforms are the same at shader link time, + // assuming one from vertex shader and the other from fragment shader. + // See GLSL ES Spec 3.00.3, sec 4.3.5. + bool isSameUniformAtLinkTime(const Uniform &other) const; }; struct COMPILER_EXPORT Attribute : public ShaderVariable @@ -76,6 +111,11 @@ struct COMPILER_EXPORT Attribute : public ShaderVariable ~Attribute(); Attribute(const Attribute &other); Attribute &operator=(const Attribute &other); + bool operator==(const Attribute &other) const; + bool operator!=(const Attribute &other) const + { + return !operator==(other); + } int location; }; @@ -86,6 +126,18 @@ struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable ~InterfaceBlockField(); InterfaceBlockField(const InterfaceBlockField &other); InterfaceBlockField &operator=(const InterfaceBlockField &other); + bool operator==(const InterfaceBlockField &other) const; + bool operator!=(const InterfaceBlockField &other) const + { + return !operator==(other); + } + + // Decide whether two InterfaceBlock fields are the same at shader + // link time, assuming one from vertex shader and the other from + // fragment shader. + // See GLSL ES Spec 3.00.3, sec 4.3.7. + bool isSameInterfaceBlockFieldAtLinkTime( + const InterfaceBlockField &other) const; bool isRowMajorLayout; }; @@ -94,8 +146,18 @@ struct COMPILER_EXPORT Varying : public ShaderVariable { Varying(); ~Varying(); - Varying(const Varying &other); + Varying(const Varying &otherg); Varying &operator=(const Varying &other); + bool operator==(const Varying &other) const; + bool operator!=(const Varying &other) const + { + return !operator==(other); + } + + // Decide whether two varyings are the same at shader link time, + // assuming one from vertex shader and the other from fragment shader. + // See GLSL ES Spec 3.00.3, sec 4.3.9. + bool isSameVaryingAtLinkTime(const Varying &other) const; InterpolationType interpolation; bool isInvariant; diff --git a/src/3rdparty/angle/include/angle_windowsstore.h b/src/3rdparty/angle/include/angle_windowsstore.h new file mode 100644 index 0000000000..53ec93e037 --- /dev/null +++ b/src/3rdparty/angle/include/angle_windowsstore.h @@ -0,0 +1,37 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// angle_windowsstore.h: + +#ifndef ANGLE_WINDOWSSTORE_H_ +#define ANGLE_WINDOWSSTORE_H_ + +// The following properties can be set on the CoreApplication to support additional +// ANGLE configuration options. +// +// The Visual Studio sample templates provided with this version of ANGLE have examples +// of how to set these property values. + +// +// Property: EGLNativeWindowTypeProperty +// Type: IInspectable +// Description: Set this property to specify the window type to use for creating a surface. +// If this property is missing, surface creation will fail. +// +const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty"; + +// +// Property: EGLRenderSurfaceSizeProperty +// Type: Size +// Description: Set this property to specify a preferred size in pixels of the render surface. +// The render surface size width and height must be greater than 0. +// If this property is set, then the render surface size is fixed. +// If this property is missing, a default behavior will be provided. +// The default behavior uses the window size if a CoreWindow is specified or +// the size of the SwapChainPanel control if one is specified. +// +const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty"; + +#endif // ANGLE_WINDOWSSTORE_H_ diff --git a/src/3rdparty/angle/src/commit.h b/src/3rdparty/angle/src/commit.h index a2e761b131..08fc893c25 100644 --- a/src/3rdparty/angle/src/commit.h +++ b/src/3rdparty/angle/src/commit.h @@ -7,6 +7,6 @@ // This is a default commit hash header, when git is not available. // -#define ANGLE_COMMIT_HASH "abce76206141" +#define ANGLE_COMMIT_HASH "30d6c255d238" #define ANGLE_COMMIT_HASH_SIZE 12 -#define ANGLE_COMMIT_DATE "2014-09-23 19:37:05 +0000" +#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000" diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h new file mode 100644 index 0000000000..9e93aeacde --- /dev/null +++ b/src/3rdparty/angle/src/common/NativeWindow.h @@ -0,0 +1,77 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow.h: Defines NativeWindow, a class for managing and +// performing operations on an EGLNativeWindowType. +// It is used for HWND (Desktop Windows) and IInspectable objects +//(Windows Store Applications). + +#ifndef COMMON_NATIVEWINDOW_H_ +#define COMMON_NATIVEWINDOW_H_ + +#include +#include "common/debug.h" +#include "common/platform.h" + +// DXGISwapChain and DXGIFactory are typedef'd to specific required +// types. The HWND NativeWindow implementation requires IDXGISwapChain +// and IDXGIFactory and the Windows Store NativeWindow +// implementation requires IDXGISwapChain1 and IDXGIFactory2. +#if defined(ANGLE_ENABLE_WINDOWS_STORE) +typedef IDXGISwapChain1 DXGISwapChain; +typedef IDXGIFactory2 DXGIFactory; + +#include +#include +#include +#include + +namespace rx +{ +class InspectableNativeWindow; +} + +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +#else +typedef IDXGISwapChain DXGISwapChain; +typedef IDXGIFactory DXGIFactory; +#endif + +namespace rx +{ + +class NativeWindow +{ +public: + explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display); + + bool initialize(); + bool getClientRect(LPRECT rect); + bool isIconic(); + + HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, UINT width, UINT height, + DXGISwapChain** swapChain); + + inline EGLNativeWindowType getNativeWindow() const { return mWindow; } + inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; } + + private: + EGLNativeWindowType mWindow; + EGLNativeDisplayType mDisplay; + +#if defined(ANGLE_ENABLE_WINDOWS_STORE) + std::shared_ptr mImpl; +#endif + +}; + +bool IsValidEGLNativeWindowType(EGLNativeWindowType window); +} + +#endif // COMMON_NATIVEWINDOW_H_ diff --git a/src/3rdparty/angle/src/common/angleutils.cpp b/src/3rdparty/angle/src/common/angleutils.cpp index 2673abf30a..c1367c460a 100644 --- a/src/3rdparty/angle/src/common/angleutils.cpp +++ b/src/3rdparty/angle/src/common/angleutils.cpp @@ -5,26 +5,33 @@ // #include "common/angleutils.h" - +#include "debug.h" +#include #include +size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector& outBuffer) +{ + // Attempt to just print to the current buffer + int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg); + if (len < 0 || static_cast(len) >= outBuffer.size()) + { + // Buffer was not large enough, calculate the required size and resize the buffer + len = vsnprintf(NULL, 0, fmt, vararg); + outBuffer.resize(len + 1); + + // Print again + len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg); + } + ASSERT(len >= 0); + return static_cast(len); +} + std::string FormatString(const char *fmt, va_list vararg) { static std::vector buffer(512); - // Attempt to just print to the current buffer - int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg); - if (len < 0 || static_cast(len) >= buffer.size()) - { - // Buffer was not large enough, calculate the required size and resize the buffer - len = vsnprintf(NULL, 0, fmt, vararg); - buffer.resize(len + 1); - - // Print again - vsnprintf(&buffer[0], buffer.size(), fmt, vararg); - } - - return std::string(buffer.data(), len); + size_t len = FormatStringIntoVector(fmt, vararg, buffer); + return std::string(&buffer[0], len); } std::string FormatString(const char *fmt, ...) diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h index ddbbd5f501..b343ece5bc 100644 --- a/src/3rdparty/angle/src/common/angleutils.h +++ b/src/3rdparty/angle/src/common/angleutils.h @@ -17,6 +17,7 @@ #include #include #include +#include // A macro to disallow the copy constructor and operator= functions // This must be used in the private: declarations for a class @@ -95,6 +96,13 @@ inline void StructZero(T *obj) memset(obj, 0, sizeof(T)); } +template +inline bool IsMaskFlagSet(T mask, T flag) +{ + // Handles multibit flags as well + return (mask & flag) == flag; +} + inline const char* MakeStaticString(const std::string &str) { static std::set strings; @@ -132,9 +140,12 @@ inline std::string Str(int i) return strstr.str(); } +size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector& buffer); + std::string FormatString(const char *fmt, va_list vararg); std::string FormatString(const char *fmt, ...); +// snprintf is not defined with MSVC prior to to msvc14 #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf #endif diff --git a/src/3rdparty/angle/src/common/debug.cpp b/src/3rdparty/angle/src/common/debug.cpp index dcad327564..5f55ff1e39 100644 --- a/src/3rdparty/angle/src/common/debug.cpp +++ b/src/3rdparty/angle/src/common/debug.cpp @@ -17,41 +17,211 @@ namespace gl { -#if defined(ANGLE_ENABLE_PERF) -typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR); -#else -typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*); -#endif - -static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg) +#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) +// Wraps the D3D9/D3D11 debug annotation functions. +class DebugAnnotationWrapper { -#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE) - std::string formattedMessage = FormatString(format, vararg); + public: + DebugAnnotationWrapper() { }; + virtual ~DebugAnnotationWrapper() { }; + virtual void beginEvent(const std::wstring &eventName) = 0; + virtual void endEvent() = 0; + virtual void setMarker(const std::wstring &markerName) = 0; + virtual bool getStatus() = 0; +}; + +#if defined(ANGLE_ENABLE_D3D9) +class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper +{ + public: + void beginEvent(const std::wstring &eventName) + { + D3DPERF_BeginEvent(0, eventName.c_str()); + } + + void endEvent() + { + D3DPERF_EndEvent(); + } + + void setMarker(const std::wstring &markerName) + { + D3DPERF_SetMarker(0, markerName.c_str()); + } + + bool getStatus() + { + return !!D3DPERF_GetStatus(); + } +}; +#endif // ANGLE_ENABLE_D3D9 + +#if defined(ANGLE_ENABLE_D3D11) +class D3D11DebugAnnotationWrapper : public DebugAnnotationWrapper +{ + public: + + D3D11DebugAnnotationWrapper() + : mInitialized(false), + mD3d11Module(NULL), + mUserDefinedAnnotation(NULL) + { + // D3D11 devices can't be created during DllMain. + // We defer device creation until the object is actually used. + } + + ~D3D11DebugAnnotationWrapper() + { + if (mInitialized) + { + SafeRelease(mUserDefinedAnnotation); + FreeLibrary(mD3d11Module); + } + } + + virtual void beginEvent(const std::wstring &eventName) + { + initializeDevice(); + + mUserDefinedAnnotation->BeginEvent(eventName.c_str()); + } + + virtual void endEvent() + { + initializeDevice(); + + mUserDefinedAnnotation->EndEvent(); + } + + virtual void setMarker(const std::wstring &markerName) + { + initializeDevice(); + + mUserDefinedAnnotation->SetMarker(markerName.c_str()); + } + + virtual bool getStatus() + { + // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013. + +#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE) + // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture. + // This should only be called in DEBUG mode. + // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks. + IDXGraphicsAnalysis* graphicsAnalysis; + DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis)); + bool underCapture = (graphicsAnalysis != NULL); + SafeRelease(graphicsAnalysis); + return underCapture; #endif -#if defined(ANGLE_ENABLE_PERF) + // Otherwise, we have to return true here. + return true; + } + + protected: + + void initializeDevice() + { + if (!mInitialized) + { +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); + ASSERT(mD3d11Module); + + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); + ASSERT(D3D11CreateDevice != NULL); +#endif // !ANGLE_ENABLE_WINDOWS_STORE + + ID3D11Device* device = NULL; + ID3D11DeviceContext* context = NULL; + + HRESULT hr = E_FAIL; + + // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device. + hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context); + ASSERT(SUCCEEDED(hr)); + + hr = context->QueryInterface(__uuidof(mUserDefinedAnnotation), reinterpret_cast(&mUserDefinedAnnotation)); + ASSERT(SUCCEEDED(hr) && mUserDefinedAnnotation != NULL); + + SafeRelease(device); + SafeRelease(context); + + mInitialized = true; + } + } + + bool mInitialized; + HMODULE mD3d11Module; + ID3DUserDefinedAnnotation* mUserDefinedAnnotation; +}; +#endif // ANGLE_ENABLE_D3D11 + +static DebugAnnotationWrapper* g_DebugAnnotationWrapper = NULL; + +void InitializeDebugAnnotations() +{ +#if defined(ANGLE_ENABLE_D3D9) + g_DebugAnnotationWrapper = new D3D9DebugAnnotationWrapper(); +#elif defined(ANGLE_ENABLE_D3D11) + // If the project uses D3D9 then we can use the D3D9 debug annotations, even with the D3D11 renderer. + // However, if D3D9 is unavailable (e.g. in Windows Store), then we use D3D11 debug annotations. + // The D3D11 debug annotations are methods on ID3DUserDefinedAnnotation, which is implemented by the DeviceContext. + // This doesn't have to be the same DeviceContext that the renderer uses, though. + g_DebugAnnotationWrapper = new D3D11DebugAnnotationWrapper(); +#endif +} + +void UninitializeDebugAnnotations() +{ + if (g_DebugAnnotationWrapper != NULL) + { + SafeDelete(g_DebugAnnotationWrapper); + } +} + +#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS + +enum DebugTraceOutputType +{ + DebugTraceOutputTypeNone, + DebugTraceOutputTypeSetMarker, + DebugTraceOutputTypeBeginEvent +}; + +static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const char *format, va_list vararg) +{ +#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) + static std::vector buffer(512); + if (perfActive()) { - // The perf function only accepts wide strings, widen the ascii message - static std::wstring wideMessage; - if (wideMessage.capacity() < formattedMessage.length()) + size_t len = FormatStringIntoVector(format, vararg, buffer); + std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len); + + switch (outputType) { - wideMessage.reserve(formattedMessage.size()); + case DebugTraceOutputTypeNone: + break; + case DebugTraceOutputTypeBeginEvent: + g_DebugAnnotationWrapper->beginEvent(formattedWideMessage); + break; + case DebugTraceOutputTypeSetMarker: + g_DebugAnnotationWrapper->setMarker(formattedWideMessage); + break; } - - wideMessage.assign(formattedMessage.begin(), formattedMessage.end()); - - perfFunc(0, wideMessage.c_str()); } -#endif // ANGLE_ENABLE_PERF +#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS -#if defined(ANGLE_ENABLE_TRACE) +#if defined(ANGLE_ENABLE_DEBUG_TRACE) #if defined(NDEBUG) - if (traceFileDebugOnly) + if (traceInDebugOnly) { return; } #endif // NDEBUG + std::string formattedMessage = FormatString(format, vararg); static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app); if (file) @@ -60,25 +230,29 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c file.flush(); } -#endif // ANGLE_ENABLE_TRACE +#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) + OutputDebugStringA(formattedMessage.c_str()); +#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER + +#endif // ANGLE_ENABLE_DEBUG_TRACE } -void trace(bool traceFileDebugOnly, const char *format, ...) +void trace(bool traceInDebugOnly, const char *format, ...) { va_list vararg; va_start(vararg, format); -#if defined(ANGLE_ENABLE_PERF) - output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg); +#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) + output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg); #else - output(traceFileDebugOnly, NULL, format, vararg); + output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg); #endif va_end(vararg); } bool perfActive() { -#if defined(ANGLE_ENABLE_PERF) - static bool active = D3DPERF_GetStatus() != 0; +#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) + static bool active = g_DebugAnnotationWrapper->getStatus(); return active; #else return false; @@ -87,26 +261,28 @@ bool perfActive() ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...) { -#if defined(ANGLE_ENABLE_PERF) -#if !defined(ANGLE_ENABLE_TRACE) +#if !defined(ANGLE_ENABLE_DEBUG_TRACE) if (!perfActive()) { return; } -#endif // !ANGLE_ENABLE_TRACE +#endif // !ANGLE_ENABLE_DEBUG_TRACE va_list vararg; va_start(vararg, format); - output(true, reinterpret_cast(D3DPERF_BeginEvent), format, vararg); +#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) + output(true, DebugTraceOutputTypeBeginEvent, format, vararg); +#else + output(true, DebugTraceOutputTypeNone, format, vararg); +#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS va_end(vararg); -#endif // ANGLE_ENABLE_PERF } ScopedPerfEventHelper::~ScopedPerfEventHelper() { -#if defined(ANGLE_ENABLE_PERF) +#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) if (perfActive()) { - D3DPERF_EndEvent(); + g_DebugAnnotationWrapper->endEvent(); } #endif } diff --git a/src/3rdparty/angle/src/common/debug.h b/src/3rdparty/angle/src/common/debug.h index bf2bca8f24..c177f51314 100644 --- a/src/3rdparty/angle/src/common/debug.h +++ b/src/3rdparty/angle/src/common/debug.h @@ -20,8 +20,8 @@ namespace gl { - // Outputs text to the debugging log - void trace(bool traceFileDebugOnly, const char *format, ...); + // Outputs text to the debugging log, or the debugging window + void trace(bool traceInDebugOnly, const char *format, ...); // Returns whether D3DPERF is active. bool perfActive(); @@ -36,31 +36,34 @@ namespace gl private: DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper); }; + + void InitializeDebugAnnotations(); + void UninitializeDebugAnnotations(); } // A macro to output a trace of a function call and its arguments to the debugging log -#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF) +#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) #define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) #else #define TRACE(message, ...) (void(0)) #endif // A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing. -#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF) +#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) #define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) #else #define FIXME(message, ...) (void(0)) #endif // A macro to output a function call and its arguments to the debugging log, in case of error. -#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF) +#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) #define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) #else #define ERR(message, ...) (void(0)) #endif // A macro to log a performance event around a scope. -#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF) +#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) #if defined(_MSC_VER) #define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__); #else @@ -83,7 +86,7 @@ namespace gl #define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable) #endif -#ifndef ANGLE_ENABLE_TRACE +#ifndef ANGLE_ENABLE_DEBUG_TRACE #define UNUSED_TRACE_VARIABLE(variable) ((void)variable) #else #define UNUSED_TRACE_VARIABLE(variable) @@ -128,7 +131,7 @@ namespace gl #endif // A macro functioning as a compile-time assert to validate constant conditions -#if defined(_MSC_VER) && _MSC_VER >= 1600 +#if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GNUC__) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)) #define META_ASSERT_MSG(condition, msg) static_assert(condition, msg) #else #define META_ASSERT_CONCAT(a, b) a ## b diff --git a/src/3rdparty/angle/src/common/features.h b/src/3rdparty/angle/src/common/features.h new file mode 100644 index 0000000000..b49a0ee852 --- /dev/null +++ b/src/3rdparty/angle/src/common/features.h @@ -0,0 +1,35 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#define ANGLE_DISABLED 0 +#define ANGLE_ENABLED 1 + +// Feature defaults + +// Direct3D9EX +// The "Debug This Pixel..." feature in PIX often fails when using the +// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 +// machine, define "ANGLE_D3D9EX=0" in your project file. +#if !defined(ANGLE_D3D9EX) +#define ANGLE_D3D9EX ANGLE_ENABLED +#endif + +// Vsync +// ENABLED allows Vsync to be configured at runtime +// DISABLED disallows Vsync +#if !defined(ANGLE_VSYNC) +#define ANGLE_VSYNC ANGLE_ENABLED +#endif + +// Program binary loading +#if !defined(ANGLE_PROGRAM_BINARY_LOAD) +#define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED +#endif + +// Shader debug info +#if !defined(ANGLE_SHADER_DEBUG_INFO) +#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED +#endif diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h index 52f2bc1c0e..a1717892fd 100644 --- a/src/3rdparty/angle/src/common/mathutil.h +++ b/src/3rdparty/angle/src/common/mathutil.h @@ -109,7 +109,7 @@ inline unsigned int unorm(float x) inline bool supportsSSE2() { -#ifdef ANGLE_PLATFORM_WINDOWS +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) static bool checked = false; static bool supports = false; @@ -118,7 +118,6 @@ inline bool supportsSSE2() return supports; } -#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid() int info[4]; __cpuid(info, 0); @@ -128,7 +127,6 @@ inline bool supportsSSE2() supports = (info[3] >> 26) & 1; } -#endif checked = true; diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h index b53394f337..0001e7142e 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h @@ -11,9 +11,6 @@ #if defined(_WIN32) || defined(_WIN64) # define ANGLE_PLATFORM_WINDOWS 1 -# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) -# define ANGLE_PLATFORM_WINRT 1 -# endif #elif defined(__APPLE__) # define ANGLE_PLATFORM_APPLE 1 # define ANGLE_PLATFORM_POSIX 1 @@ -37,6 +34,9 @@ #endif #ifdef ANGLE_PLATFORM_WINDOWS +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +# define ANGLE_ENABLE_WINDOWS_STORE 1 +# endif # ifndef STRICT # define STRICT 1 # endif @@ -50,7 +50,7 @@ # include # include -# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF) +# if defined(ANGLE_ENABLE_D3D9) # include # if !defined(COMPILER_IMPLEMENTATION) # include @@ -62,13 +62,26 @@ # include # include # include -# if _MSC_VER >= 1700 +# if defined(_MSC_VER) && (_MSC_VER >= 1700) +# include # include # endif # if !defined(COMPILER_IMPLEMENTATION) # include # endif -# if defined(__MINGW32__) +# endif + +# if defined(ANGLE_ENABLE_WINDOWS_STORE) +# include +# if defined(_DEBUG) +# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) +# include +# endif +# include +# endif +# endif + +# if defined(__MINGW32__) // Missing defines on MinGW typedef enum D3D11_MAP_FLAG { D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L @@ -78,8 +91,68 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS UINT64 NumPrimitivesWritten; UINT64 PrimitivesStorageNeeded; } D3D11_QUERY_DATA_SO_STATISTICS; -# endif -# endif +typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)( + IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *, + UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **); +#define D3D11_MESSAGE_CATEGORY UINT +#define D3D11_MESSAGE_SEVERITY UINT +#define D3D11_MESSAGE_ID UINT +struct D3D11_MESSAGE; +typedef struct D3D11_INFO_QUEUE_FILTER_DESC +{ + UINT NumCategories; + D3D11_MESSAGE_CATEGORY *pCategoryList; + UINT NumSeverities; + D3D11_MESSAGE_SEVERITY *pSeverityList; + UINT NumIDs; + D3D11_MESSAGE_ID *pIDList; +} D3D11_INFO_QUEUE_FILTER_DESC; +typedef struct D3D11_INFO_QUEUE_FILTER +{ + D3D11_INFO_QUEUE_FILTER_DESC AllowList; + D3D11_INFO_QUEUE_FILTER_DESC DenyList; +} D3D11_INFO_QUEUE_FILTER; +static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 }; +MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown +{ +public: + virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0; + virtual void __stdcall ClearStoredMessages() = 0; + virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0; + virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0; + virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0; + virtual UINT64 __stdcall GetNumStoredMessages() = 0; + virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0; + virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0; + virtual UINT64 __stdcall GetMessageCountLimit() = 0; + virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0; + virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0; + virtual void __stdcall ClearStorageFilter() = 0; + virtual HRESULT __stdcall PushEmptyStorageFilter() = 0; + virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0; + virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0; + virtual void __stdcall PopStorageFilter() = 0; + virtual UINT __stdcall GetStorageFilterStackSize() = 0; + virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0; + virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0; + virtual void __stdcall ClearRetrievalFilter() = 0; + virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0; + virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0; + virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0; + virtual void __stdcall PopRetrievalFilter() = 0; + virtual UINT __stdcall GetRetrievalFilterStackSize() = 0; + virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0; + virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0; + virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0; + virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0; + virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0; + virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0; + virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0; + virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0; + virtual void __stdcall SetMuteDebugOutput(BOOL) = 0; + virtual BOOL __stdcall GetMuteDebugOutput() = 0; +}; +#endif // __MINGW32__ # undef near # undef far diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp index c46fab5303..cb1b32d325 100644 --- a/src/3rdparty/angle/src/common/tls.cpp +++ b/src/3rdparty/angle/src/common/tls.cpp @@ -10,29 +10,50 @@ #include -#if defined(ANGLE_PLATFORM_WINRT) +#ifdef ANGLE_ENABLE_WINDOWS_STORE #include -std::vector *tls = nullptr; -std::vector *freeIndices = nullptr; +#include +#include +#include + +#include +#include +#include + +using namespace std; +using namespace Windows::Foundation; +using namespace ABI::Windows::System::Threading; + +// Thread local storage for Windows Store support +typedef vector ThreadLocalData; + +static __declspec(thread) ThreadLocalData* currentThreadData = nullptr; +static set allThreadData; +static DWORD nextTlsIndex = 0; +static vector freeTlsIndices; + #endif TLSIndex CreateTLSIndex() { TLSIndex index; -#if defined(ANGLE_PLATFORM_WINRT) - if (!tls) - tls = new std::vector; - if (freeIndices && !freeIndices->empty()) { - index = freeIndices->back(); - freeIndices->pop_back(); - return index; - } else { - tls->push_back(nullptr); - return tls->size() - 1; +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + if (!freeTlsIndices.empty()) + { + DWORD result = freeTlsIndices.back(); + freeTlsIndices.pop_back(); + index = result; } -#elif defined(ANGLE_PLATFORM_WINDOWS) + else + { + index = nextTlsIndex++; + } +#else index = TlsAlloc(); +#endif + #elif defined(ANGLE_PLATFORM_POSIX) // Create global pool key if ((pthread_key_create(&index, NULL)) != 0) @@ -53,13 +74,23 @@ bool DestroyTLSIndex(TLSIndex index) return false; } -#if defined(ANGLE_PLATFORM_WINRT) - if (!freeIndices) - freeIndices = new std::vector; - freeIndices->push_back(index); +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + assert(index < nextTlsIndex); + assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end()); + + freeTlsIndices.push_back(index); + for (auto threadData : allThreadData) + { + if (threadData->size() > index) + { + threadData->at(index) = nullptr; + } + } return true; -#elif ANGLE_PLATFORM_WINDOWS +#else return (TlsFree(index) == TRUE); +#endif #elif defined(ANGLE_PLATFORM_POSIX) return (pthread_key_delete(index) == 0); #endif @@ -73,11 +104,25 @@ bool SetTLSValue(TLSIndex index, void *value) return false; } -#if defined(ANGLE_PLATFORM_WINRT) - tls->at(index) = value; +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + ThreadLocalData* threadData = currentThreadData; + if (!threadData) + { + threadData = new ThreadLocalData(index + 1, nullptr); + allThreadData.insert(threadData); + currentThreadData = threadData; + } + else if (threadData->size() <= index) + { + threadData->resize(index + 1, nullptr); + } + + threadData->at(index) = value; return true; -#elif defined(ANGLE_PLATFORM_WINDOWS) +#else return (TlsSetValue(index, value) == TRUE); +#endif #elif defined(ANGLE_PLATFORM_POSIX) return (pthread_setspecific(index, value) == 0); #endif @@ -85,18 +130,26 @@ bool SetTLSValue(TLSIndex index, void *value) void *GetTLSValue(TLSIndex index) { -#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index"); -#endif if (index == TLS_INVALID_INDEX) { return NULL; } -#if defined(ANGLE_PLATFORM_WINRT) - return tls->at(index); -#elif defined(ANGLE_PLATFORM_WINDOWS) +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + ThreadLocalData* threadData = currentThreadData; + if (threadData && threadData->size() > index) + { + return threadData->at(index); + } + else + { + return nullptr; + } +#else return TlsGetValue(index); +#endif #elif defined(ANGLE_PLATFORM_POSIX) return pthread_getspecific(index); #endif diff --git a/src/3rdparty/angle/src/common/tls.h b/src/3rdparty/angle/src/common/tls.h index c40ae1a061..8a06e92d1a 100644 --- a/src/3rdparty/angle/src/common/tls.h +++ b/src/3rdparty/angle/src/common/tls.h @@ -11,11 +11,15 @@ #include "common/platform.h" -#if defined(ANGLE_PLATFORM_WINRT) - typedef size_t TLSIndex; -# define TLS_OUT_OF_INDEXES (static_cast(-1)) -# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES -#elif defined(ANGLE_PLATFORM_WINDOWS) +#ifdef ANGLE_PLATFORM_WINDOWS + +// TLS does not exist for Windows Store and needs to be emulated +# ifdef ANGLE_ENABLE_WINDOWS_STORE +# define TLS_OUT_OF_INDEXES -1 +# ifndef CREATE_SUSPENDED +# define CREATE_SUSPENDED 0x00000004 +# endif +# endif typedef DWORD TLSIndex; # define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES) #elif defined(ANGLE_PLATFORM_POSIX) @@ -28,6 +32,9 @@ # error Unsupported platform. #endif +// TODO(kbr): for POSIX platforms this will have to be changed to take +// in a destructor function pointer, to allow the thread-local storage +// to be properly deallocated upon thread exit. TLSIndex CreateTLSIndex(); bool DestroyTLSIndex(TLSIndex index); diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp index 4b8e325d22..9d797a6612 100644 --- a/src/3rdparty/angle/src/common/utilities.cpp +++ b/src/3rdparty/angle/src/common/utilities.cpp @@ -9,17 +9,16 @@ #include "common/utilities.h" #include "common/mathutil.h" #include "common/platform.h" -#if defined(ANGLE_PLATFORM_WINRT) -# include -# include -# include -# include - using namespace Microsoft::WRL; - using namespace ABI::Windows::Storage; -#endif #include +#if defined(ANGLE_ENABLE_WINDOWS_STORE) +# include +# include +# include +# include +#endif + namespace gl { @@ -447,50 +446,10 @@ int VariableSortOrder(GLenum type) } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) std::string getTempPath() { -#if defined(ANGLE_PLATFORM_WINRT) - static std::string path; - - while (path.empty()) - { - ComPtr factory; - Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData); - HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory)); - if (FAILED(result)) - break; - - ComPtr applicationData; - result = factory->get_Current(&applicationData); - if (FAILED(result)) - break; - - ComPtr storageFolder; - result = applicationData->get_LocalFolder(&storageFolder); - if (FAILED(result)) - break; - - ComPtr localFolder; - result = storageFolder.As(&localFolder); - if (FAILED(result)) - break; - - HSTRING localFolderPath; - result = localFolder->get_Path(&localFolderPath); - if (FAILED(result)) - break; - - std::wstring_convert< std::codecvt_utf8 > converter; - path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL)); - if (path.empty()) - { - UNREACHABLE(); - break; - } - } - - return path; -#elif defined(ANGLE_PLATFORM_WINDOWS) +#ifdef ANGLE_PLATFORM_WINDOWS char path[MAX_PATH]; DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); if (pathLen == 0) @@ -525,3 +484,33 @@ void writeFile(const char* path, const void* content, size_t size) fwrite(content, sizeof(char), size, file); fclose(file); } +#endif // !ANGLE_ENABLE_WINDOWS_STORE + +#if defined(ANGLE_ENABLE_WINDOWS_STORE) + +void Sleep(unsigned long dwMilliseconds) +{ + static HANDLE singletonEvent = nullptr; + HANDLE sleepEvent = singletonEvent; + if (!sleepEvent) + { + sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); + + if (!sleepEvent) + return; + + HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr); + + if (previousEvent) + { + // Back out if multiple threads try to demand create at the same time. + CloseHandle(sleepEvent); + sleepEvent = previousEvent; + } + } + + // Emulate sleep by waiting with timeout on an event that is never signalled. + WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false); +} + +#endif // ANGLE_ENABLE_WINDOWS_STORE diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h index a823184ecd..2cf6bed176 100644 --- a/src/3rdparty/angle/src/common/utilities.h +++ b/src/3rdparty/angle/src/common/utilities.h @@ -46,7 +46,13 @@ template outT uiround(GLfloat value) { return static_cast( } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) std::string getTempPath(); void writeFile(const char* path, const void* data, size_t size); +#endif + +#if defined(ANGLE_ENABLE_WINDOWS_STORE) +void Sleep(_In_ unsigned long dwMilliseconds); +#endif #endif // LIBGLESV2_UTILITIES_H diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp new file mode 100644 index 0000000000..2440747260 --- /dev/null +++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp @@ -0,0 +1,66 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow.cpp: Handler for managing HWND native window types. + +#include "common/NativeWindow.h" +#include "common/debug.h" + +namespace rx +{ +bool IsValidEGLNativeWindowType(EGLNativeWindowType window) +{ + return (IsWindow(window) == TRUE); +} + +NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display) +{ +} + +bool NativeWindow::initialize() +{ + return true; +} + +bool NativeWindow::getClientRect(LPRECT rect) +{ + return GetClientRect(mWindow, rect) == TRUE; +} + +bool NativeWindow::isIconic() +{ + return IsIconic(mWindow) == TRUE; +} + +HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, unsigned int width, unsigned int height, + DXGISwapChain** swapChain) +{ + if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) + { + return E_INVALIDARG; + } + + DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 }; + swapChainDesc.BufferCount = 1; + swapChainDesc.BufferDesc.Format = format; + swapChainDesc.BufferDesc.Width = width; + swapChainDesc.BufferDesc.Height = height; + swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; + swapChainDesc.Flags = 0; + swapChainDesc.OutputWindow = mWindow; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.Windowed = TRUE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + return factory->CreateSwapChain(device, &swapChainDesc, swapChain); +} +} diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp new file mode 100644 index 0000000000..9b65c15625 --- /dev/null +++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp @@ -0,0 +1,200 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types. + +#include +#include "common/winrt/CoreWindowNativeWindow.h" +using namespace ABI::Windows::Foundation::Collections; + +namespace rx +{ + +typedef ITypedEventHandler SizeChangedHandler; + +CoreWindowNativeWindow::~CoreWindowNativeWindow() +{ + unregisterForSizeChangeEvents(); +} + +bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) +{ + ComPtr props = propertySet; + ComPtr win = window; + ComPtr displayInformation = display; + SIZE swapChainSize = {}; + bool swapChainSizeSpecified = false; + HRESULT result = S_OK; + + // IPropertySet is an optional parameter and can be null. + // If one is specified, cache as an IMap and read the properties + // used for initial host initialization. + if (propertySet) + { + result = props.As(&mPropertyMap); + if (SUCCEEDED(result)) + { + // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet + // was prevalidated to contain the EGLNativeWindowType before being passed to + // this host. + result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified); + } + } + + if (SUCCEEDED(result)) + { + result = win.As(&mCoreWindow); + } + + if (SUCCEEDED(result)) + { + result = displayInformation.As(&mDisplayInformation); + } + + if (SUCCEEDED(result)) + { +#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + ComPtr displayInformation2; + result = mDisplayInformation.As(&displayInformation2); + ASSERT(SUCCEEDED(result)); + + result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor); + ASSERT(SUCCEEDED(result)); +#else + ABI::Windows::Graphics::Display::ResolutionScale resolutionScale; + result = mDisplayInformation->get_ResolutionScale(&resolutionScale); + ASSERT(SUCCEEDED(result)); + + mScaleFactor = DOUBLE(resolutionScale) / 100.0; +#endif + } + + if (SUCCEEDED(result)) + { + // If a swapchain size is specfied, then the automatic resize + // behaviors implemented by the host should be disabled. The swapchain + // will be still be scaled when being rendered to fit the bounds + // of the host. + // Scaling of the swapchain output occurs automatically because if + // the scaling mode setting DXGI_SCALING_STRETCH on the swapchain. + if (swapChainSizeSpecified) + { + mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy }; + mSupportsSwapChainResize = false; + } + else + { + ABI::Windows::Foundation::Rect rect; + HRESULT result = mCoreWindow->get_Bounds(&rect); + if (SUCCEEDED(result)) + { + LONG width = std::floor(rect.Width * mScaleFactor + 0.5); + LONG height = std::floor(rect.Height * mScaleFactor + 0.5); + mClientRect = { 0, 0, width, height }; + } + } + } + + if (SUCCEEDED(result)) + { + mNewClientRect = mClientRect; + mClientRectChanged = false; + return registerForSizeChangeEvents(); + } + + return false; +} + +bool CoreWindowNativeWindow::registerForSizeChangeEvents() +{ + HRESULT result = mCoreWindow->add_SizeChanged(Callback(this, &CoreWindowNativeWindow::onSizeChanged).Get(), + &mSizeChangedEventToken); + + if (SUCCEEDED(result)) + { + return true; + } + + return false; +} + +void CoreWindowNativeWindow::unregisterForSizeChangeEvents() +{ + if (mCoreWindow) + { + (void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken); + } + mSizeChangedEventToken.value = 0; +} + +HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) +{ + if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) + { + return E_INVALIDARG; + } + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; + swapChainDesc.BufferCount = 2; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + + *swapChain = nullptr; + + ComPtr newSwapChain; + HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf()); + if (SUCCEEDED(result)) + { + +#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected + // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On + // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed + // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations. + if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED) + { + mSupportsSwapChainResize = false; + } +#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + + result = newSwapChain.CopyTo(swapChain); + } + + if (SUCCEEDED(result)) + { + // If automatic swapchain resize behaviors have been disabled, then + // unregister for the resize change events. + if (mSupportsSwapChainResize == false) + { + unregisterForSizeChangeEvents(); + } + } + + return result; +} + +// Basically, this shouldn't be used on Phone +HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e) +{ + ABI::Windows::Foundation::Size size; + if (SUCCEEDED(e->get_Size(&size))) + { + SIZE windowSizeInPixels = { + std::floor(size.Width * mScaleFactor + 0.5), + std::floor(size.Height * mScaleFactor + 0.5) + }; + setNewClientSize(windowSizeInPixels); + } + + return S_OK; +} +} diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h new file mode 100644 index 0000000000..1c5512417d --- /dev/null +++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types. + +#ifndef COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_ +#define COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_ + +#include "common/winrt/InspectableNativeWindow.h" +#include +#include + +namespace rx +{ + +class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this +{ + public: + ~CoreWindowNativeWindow(); + + bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet); + bool registerForSizeChangeEvents(); + void unregisterForSizeChangeEvents(); + HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain); + + private: + HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); + + ComPtr mCoreWindow; + ComPtr mDisplayInformation; + ComPtr> mPropertyMap; +}; + +} + +#endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_ diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp new file mode 100644 index 0000000000..0589f6dce5 --- /dev/null +++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp @@ -0,0 +1,274 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// InspectableNativeWindow.cpp: NativeWindow base class for managing IInspectable native window types. + +#include "common/winrt/CoreWindowNativeWindow.h" +#include "common/winrt/SwapChainPanelNativeWindow.h" + +namespace rx +{ +NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) + : mWindow(window), mDisplay(display) +{ +} + +bool NativeWindow::initialize() +{ + // If the native window type is a IPropertySet, extract the + // EGLNativeWindowType (IInspectable) and initialize the + // proper host with this IPropertySet. + ComPtr propertySet; + ComPtr eglNativeWindow; + if (IsEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow)) + { + // A property set was found and the EGLNativeWindowType was + // retrieved. The mWindow member of the host to must be updated + // to use the EGLNativeWindowType specified in the property set. + // mWindow is treated as a raw pointer not an AddRef'd interface, so + // the old mWindow does not need a Release() before this assignment. + mWindow = eglNativeWindow.Get(); + } + + ComPtr coreWindow; + ComPtr swapChainPanel; + if (IsCoreWindow(mWindow, &coreWindow)) + { + mImpl = std::make_shared(); + if (mImpl) + { + return mImpl->initialize(mWindow, mDisplay, propertySet.Get()); + } + } + else if (IsSwapChainPanel(mWindow, &swapChainPanel)) + { + mImpl = std::make_shared(); + if (mImpl) + { + return mImpl->initialize(mWindow, mDisplay, propertySet.Get()); + } + } + else + { + ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow, ISwapChainPanel and IPropertySet"); + } + + return false; +} + +bool NativeWindow::getClientRect(RECT *rect) +{ + if (mImpl) + { + return mImpl->getClientRect(rect); + } + + return false; +} + +bool NativeWindow::isIconic() +{ + return false; +} + +HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) +{ + if (mImpl) + { + return mImpl->createSwapChain(device, factory, format, width, height, swapChain); + } + + return E_UNEXPECTED; +} + +bool IsCoreWindow(EGLNativeWindowType window, ComPtr *coreWindow) +{ + if (!window) + { + return false; + } + + ComPtr win = window; + ComPtr coreWin; + if (SUCCEEDED(win.As(&coreWin))) + { + if (coreWindow != nullptr) + { + *coreWindow = coreWin.Detach(); + } + return true; + } + + return false; +} + +bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr *swapChainPanel) +{ + if (!window) + { + return false; + } + + ComPtr win = window; + ComPtr panel; + if (SUCCEEDED(win.As(&panel))) + { + if (swapChainPanel != nullptr) + { + *swapChainPanel = panel.Detach(); + } + return true; + } + + return false; +} + +bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet, IInspectable **eglNativeWindow) +{ + if (!window) + { + return false; + } + + ComPtr props = window; + ComPtr propSet; + ComPtr nativeWindow; + ComPtr> propMap; + boolean hasEglNativeWindowPropertyKey = false; + + HRESULT result = props.As(&propSet); + if (SUCCEEDED(result)) + { + result = propSet.As(&propMap); + } + + // Look for the presence of the EGLNativeWindowType in the property set + if (SUCCEEDED(result)) + { + result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEglNativeWindowPropertyKey); + } + + // If the IPropertySet does not contain the required EglNativeWindowType key, the property set is + // considered invalid. + if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey) + { + ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow"); + return false; + } + + // The EglNativeWindowType property exists, so retreive the IInspectable that represents the EGLNativeWindowType + if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey) + { + result = propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow); + } + + if (SUCCEEDED(result)) + { + if (propertySet != nullptr) + { + result = propSet.CopyTo(propertySet); + } + } + + if (SUCCEEDED(result)) + { + if (eglNativeWindow != nullptr) + { + result = nativeWindow.CopyTo(eglNativeWindow); + } + } + + if (SUCCEEDED(result)) + { + return true; + } + + return false; +} + +// A Valid EGLNativeWindowType IInspectable can only be: +// +// ICoreWindow +// IPropertySet +// +// Anything else will be rejected as an invalid IInspectable. +bool IsValidEGLNativeWindowType(EGLNativeWindowType window) +{ + return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window); +} + +// Attempts to read an optional SIZE property value that is assumed to be in the form of +// an ABI::Windows::Foundation::Size. This function validates the Size value before returning +// it to the caller. +// +// Possible return values are: +// S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated +// S_OK, valueExists == false - optional SIZE value was not found +// E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set. +// * Incorrect property type ( must be PropertyType_Size) +// * Invalid property value (width/height must be > 0) +// Additional errors may be returned from IMap or IPropertyValue +// +HRESULT GetOptionalSizePropertyValue(const ComPtr>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists) +{ + if (!propertyMap || !propertyName || !value || !valueExists) + { + return false; + } + + // Assume that the value does not exist + *valueExists = false; + *value = { 0, 0 }; + + ComPtr propertyValue; + ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty; + Size sizeValue = { 0, 0 }; + boolean hasKey = false; + + HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey); + if (SUCCEEDED(result) && !hasKey) + { + // Value does not exist, so return S_OK and set the exists parameter to false to indicate + // that a the optional property does not exist. + *valueExists = false; + return S_OK; + } + + if (SUCCEEDED(result)) + { + result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue); + } + + if (SUCCEEDED(result)) + { + result = propertyValue->get_Type(&propertyType); + } + + // Check if the expected Size property is of PropertyType_Size type. + if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size) + { + if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0)) + { + // A valid property value exists + *value = { static_cast(sizeValue.Width), static_cast(sizeValue.Height) }; + *valueExists = true; + result = S_OK; + } + else + { + // An invalid Size property was detected. Width/Height values must > 0 + result = E_INVALIDARG; + } + } + else + { + // An invalid property type was detected. Size property must be of PropertyType_Size + result = E_INVALIDARG; + } + + return result; +} +} diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h new file mode 100644 index 0000000000..402941a788 --- /dev/null +++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h @@ -0,0 +1,91 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// InspectableNativeWindow.h: Host specific implementation interface for +// managing IInspectable native window types. + +#ifndef COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_ +#define COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_ + +#include "common/platform.h" +#include "common/NativeWindow.h" +#include "angle_windowsstore.h" + +#include +#include + +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; + +namespace rx +{ +class InspectableNativeWindow +{ + public: + InspectableNativeWindow() : + mSupportsSwapChainResize(true), + mRequiresSwapChainScaling(false), + mClientRectChanged(false), + mClientRect({0,0,0,0}), + mNewClientRect({0,0,0,0}), + mScaleFactor(1.0) + { + mSizeChangedEventToken.value = 0; + } + virtual ~InspectableNativeWindow(){} + + virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0; + virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0; + virtual bool registerForSizeChangeEvents() = 0; + virtual void unregisterForSizeChangeEvents() = 0; + virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; } + + bool getClientRect(RECT *rect) + { + if (mClientRectChanged && mSupportsSwapChainResize) + { + mClientRect = mNewClientRect; + mClientRectChanged = false; + } + + *rect = mClientRect; + + return true; + } + + void setNewClientSize(const SIZE &newSize) + { + if (mSupportsSwapChainResize && !mRequiresSwapChainScaling) + { + mNewClientRect = { 0, 0, newSize.cx, newSize.cy }; + mClientRectChanged = true; + } + + if (mRequiresSwapChainScaling) + { + scaleSwapChain(newSize); + } + } + +protected: + bool mSupportsSwapChainResize; + bool mRequiresSwapChainScaling; + RECT mClientRect; + RECT mNewClientRect; + bool mClientRectChanged; + DOUBLE mScaleFactor; + + EventRegistrationToken mSizeChangedEventToken; +}; + +bool IsCoreWindow(EGLNativeWindowType window, ComPtr *coreWindow = nullptr); +bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr *swapChainPanel = nullptr); +bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr); +HRESULT GetOptionalSizePropertyValue(const ComPtr>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists); +} +#endif // COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_ diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp new file mode 100644 index 0000000000..268dfbd8f0 --- /dev/null +++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp @@ -0,0 +1,226 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChainPanelNativeWindow.cpp: NativeWindow for managing ISwapChainPanel native window types. + +#include "common/winrt/SwapChainPanelNativeWindow.h" +#include +#include +using namespace ABI::Windows::Foundation::Collections; + +namespace rx +{ +SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow() +{ + unregisterForSizeChangeEvents(); +} + +bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) +{ + ComPtr props = propertySet; + ComPtr win = window; + SIZE swapChainSize = {}; + bool swapChainSizeSpecified = false; + HRESULT result = S_OK; + + // IPropertySet is an optional parameter and can be null. + // If one is specified, cache as an IMap and read the properties + // used for initial host initialization. + if (propertySet) + { + result = props.As(&mPropertyMap); + if (SUCCEEDED(result)) + { + // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet + // was prevalidated to contain the EGLNativeWindowType before being passed to + // this host. + result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified); + } + } + + if (SUCCEEDED(result)) + { + result = win.As(&mSwapChainPanel); + } + + if (SUCCEEDED(result)) + { + // If a swapchain size is specfied, then the automatic resize + // behaviors implemented by the host should be disabled. The swapchain + // will be still be scaled when being rendered to fit the bounds + // of the host. + // Scaling of the swapchain output needs to be handled by the + // host for swapchain panels even though the scaling mode setting + // DXGI_SCALING_STRETCH is configured on the swapchain. + if (swapChainSizeSpecified) + { + mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy }; + + // Enable host swapchain scaling + mRequiresSwapChainScaling = true; + } + else + { + result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect); + } + } + + if (SUCCEEDED(result)) + { + mNewClientRect = mClientRect; + mClientRectChanged = false; + return registerForSizeChangeEvents(); + } + + return false; +} + +bool SwapChainPanelNativeWindow::registerForSizeChangeEvents() +{ + ComPtr sizeChangedHandler; + ComPtr frameworkElement; + HRESULT result = Microsoft::WRL::MakeAndInitialize(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this()); + + if (SUCCEEDED(result)) + { + result = mSwapChainPanel.As(&frameworkElement); + } + + if (SUCCEEDED(result)) + { + result = frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken); + } + + if (SUCCEEDED(result)) + { + return true; + } + + return false; +} + +void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents() +{ + ComPtr frameworkElement; + if (SUCCEEDED(mSwapChainPanel.As(&frameworkElement))) + { + (void)frameworkElement->remove_SizeChanged(mSizeChangedEventToken); + } + + mSizeChangedEventToken.value = 0; +} + +HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) +{ + if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) + { + return E_INVALIDARG; + } + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; + swapChainDesc.BufferCount = 2; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + + *swapChain = nullptr; + + ComPtr newSwapChain; + ComPtr swapChainPanelNative; + RECT currentPanelSize = {}; + + HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf()); + + if (SUCCEEDED(result)) + { + result = mSwapChainPanel.As(&swapChainPanelNative); + } + + if (SUCCEEDED(result)) + { + result = swapChainPanelNative->SetSwapChain(newSwapChain.Get()); + } + + if (SUCCEEDED(result)) + { + // The swapchain panel host requires an instance of the swapchain set on the SwapChainPanel + // to perform the runtime-scale behavior. This swapchain is cached here because there are + // no methods for retreiving the currently configured on from ISwapChainPanelNative. + mSwapChain = newSwapChain; + result = newSwapChain.CopyTo(swapChain); + } + + // If the host is responsible for scaling the output of the swapchain, then + // scale it now before returning an instance to the caller. This is done by + // first reading the current size of the swapchain panel, then scaling + if (SUCCEEDED(result) && mRequiresSwapChainScaling) + { + result = GetSwapChainPanelSize(mSwapChainPanel, ¤tPanelSize); + } + + // Scale the swapchain to fit inside the contents of the panel. + if (SUCCEEDED(result) && mRequiresSwapChainScaling) + { + SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom }; + result = scaleSwapChain(currentSize); + } + + if (SUCCEEDED(result)) + { + // If automatic swapchain resize behaviors have been disabled, then + // unregister for the resize change events. + if (mSupportsSwapChainResize == false) + { + unregisterForSizeChangeEvents(); + } + } + + return result; +} + +HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize) +{ + ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom }; + // Setup a scale matrix for the swap chain + DXGI_MATRIX_3X2_F scaleMatrix = {}; + scaleMatrix._11 = renderScale.Width; + scaleMatrix._22 = renderScale.Height; + + ComPtr swapChain2; + HRESULT result = mSwapChain.As(&swapChain2); + if (SUCCEEDED(result)) + { + result = swapChain2->SetMatrixTransform(&scaleMatrix); + } + + return result; +} + +HRESULT GetSwapChainPanelSize(const ComPtr &swapChainPanel, RECT *windowSize) +{ + ComPtr uiElement; + ABI::Windows::Foundation::Size renderSize = { 0, 0 }; + HRESULT result = swapChainPanel.As(&uiElement); + if (SUCCEEDED(result)) + { + result = uiElement->get_RenderSize(&renderSize); + } + + if (SUCCEEDED(result)) + { + *windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) }; + } + + return result; +} +} diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h new file mode 100644 index 0000000000..5bbf274e64 --- /dev/null +++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h @@ -0,0 +1,79 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChainPanelNativeWindow.h: NativeWindow for managing ISwapChainPanel native window types. + +#ifndef COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_ +#define COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_ + +#include "common/winrt/InspectableNativeWindow.h" + +namespace rx +{ +class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this +{ + public: + ~SwapChainPanelNativeWindow(); + + bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet); + bool registerForSizeChangeEvents(); + void unregisterForSizeChangeEvents(); + HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain); + HRESULT scaleSwapChain(const SIZE &newSize); + + private: + ComPtr mSwapChainPanel; + ComPtr> mPropertyMap; + ComPtr mSwapChain; +}; + +[uuid(8ACBD974-8187-4508-AD80-AEC77F93CF36)] +class SwapChainPanelSizeChangedHandler : + public Microsoft::WRL::RuntimeClass, ABI::Windows::UI::Xaml::ISizeChangedEventHandler> +{ + public: + SwapChainPanelSizeChangedHandler() { } + HRESULT RuntimeClassInitialize(std::shared_ptr host) + { + if (!host) + { + return E_INVALIDARG; + } + + mHost = host; + return S_OK; + } + + // ISizeChangedEventHandler + IFACEMETHOD(Invoke)(IInspectable *sender, ABI::Windows::UI::Xaml::ISizeChangedEventArgs *sizeChangedEventArgs) + { + std::shared_ptr host = mHost.lock(); + if (host) + { + // The size of the ISwapChainPanel control is returned in DIPs. + // We are keeping these in dips because the swapchain created for composition + // also uses dip units. This keeps dimensions, viewports, etc in the same unit. + // XAML Clients of the ISwapChainPanel are required to use dips to define their + // layout sizes as well. + ABI::Windows::Foundation::Size newSize; + HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize); + if (SUCCEEDED(result)) + { + SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) }; + host->setNewClientSize(windowSize); + } + } + + return S_OK; + } + + private: + std::weak_ptr mHost; +}; + +HRESULT GetSwapChainPanelSize(const ComPtr &swapChainPanel, RECT *windowSize); +} +#endif // COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h index 040b25c6a2..eec0d5e5f0 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h @@ -29,7 +29,8 @@ class DirectiveHandler // Handle pragma of form: #pragma name[(value)] virtual void handlePragma(const SourceLocation &loc, const std::string &name, - const std::string &value) = 0; + const std::string &value, + bool stdgl) = 0; virtual void handleExtension(const SourceLocation &loc, const std::string &name, diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp index 6434d5cb5c..7803ee845a 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp @@ -38,19 +38,19 @@ enum DirectiveType DirectiveType getDirective(const pp::Token *token) { - static const std::string kDirectiveDefine("define"); - static const std::string kDirectiveUndef("undef"); - static const std::string kDirectiveIf("if"); - static const std::string kDirectiveIfdef("ifdef"); - static const std::string kDirectiveIfndef("ifndef"); - static const std::string kDirectiveElse("else"); - static const std::string kDirectiveElif("elif"); - static const std::string kDirectiveEndif("endif"); - static const std::string kDirectiveError("error"); - static const std::string kDirectivePragma("pragma"); - static const std::string kDirectiveExtension("extension"); - static const std::string kDirectiveVersion("version"); - static const std::string kDirectiveLine("line"); + const char kDirectiveDefine[] = "define"; + const char kDirectiveUndef[] = "undef"; + const char kDirectiveIf[] = "if"; + const char kDirectiveIfdef[] = "ifdef"; + const char kDirectiveIfndef[] = "ifndef"; + const char kDirectiveElse[] = "else"; + const char kDirectiveElif[] = "elif"; + const char kDirectiveEndif[] = "endif"; + const char kDirectiveError[] = "error"; + const char kDirectivePragma[] = "pragma"; + const char kDirectiveExtension[] = "extension"; + const char kDirectiveVersion[] = "version"; + const char kDirectiveLine[] = "line"; if (token->type != pp::Token::IDENTIFIER) return DIRECTIVE_NONE; @@ -155,7 +155,7 @@ class DefinedParser : public Lexer protected: virtual void lex(Token *token) { - static const std::string kDefined("defined"); + const char kDefined[] = "defined"; mLexer->lex(token); if (token->type != Token::IDENTIFIER) @@ -592,6 +592,11 @@ void DirectiveParser::parsePragma(Token *token) int state = PRAGMA_NAME; mTokenizer->lex(token); + bool stdgl = token->text == "STDGL"; + if (stdgl) + { + mTokenizer->lex(token); + } while ((token->type != '\n') && (token->type != Token::LAST)) { switch(state++) @@ -627,7 +632,7 @@ void DirectiveParser::parsePragma(Token *token) } else if (state > PRAGMA_NAME) // Do not notify for empty pragma. { - mDirectiveHandler->handlePragma(token->location, name, value); + mDirectiveHandler->handlePragma(token->location, name, value, stdgl); } } diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp index d7e0c83465..69e2f39069 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp @@ -194,8 +194,8 @@ bool MacroExpander::expandMacro(const Macro ¯o, if (macro.predefined) { - static const std::string kLine = "__LINE__"; - static const std::string kFile = "__FILE__"; + const char kLine[] = "__LINE__"; + const char kFile[] = "__FILE__"; assert(replacements->size() == 1); Token& repl = replacements->front(); diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp index 368cd2ae4a..5c62a64d10 100644 --- a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp @@ -29,24 +29,27 @@ bool IsWebGLBasedSpec(ShShaderSpec spec) { - return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC; + return (spec == SH_WEBGL_SPEC || + spec == SH_CSS_SHADERS_SPEC || + spec == SH_WEBGL2_SPEC); } size_t GetGlobalMaxTokenSize(ShShaderSpec spec) { // WebGL defines a max token legnth of 256, while ES2 leaves max token // size undefined. ES3 defines a max size of 1024 characters. - if (IsWebGLBasedSpec(spec)) + switch (spec) { + case SH_WEBGL_SPEC: + case SH_CSS_SHADERS_SPEC: return 256; - } - else - { + default: return 1024; } } namespace { + class TScopedPoolAllocator { public: @@ -82,6 +85,24 @@ class TScopedSymbolTableLevel private: TSymbolTable* mTable; }; + +int MapSpecToShaderVersion(ShShaderSpec spec) +{ + switch (spec) + { + case SH_GLES2_SPEC: + case SH_WEBGL_SPEC: + case SH_CSS_SHADERS_SPEC: + return 100; + case SH_GLES3_SPEC: + case SH_WEBGL2_SPEC: + return 300; + default: + UNREACHABLE(); + return 0; + } +} + } // namespace TShHandleBase::TShHandleBase() @@ -178,9 +199,21 @@ bool TCompiler::compile(const char* const shaderStrings[], (parseContext.treeRoot != NULL); shaderVersion = parseContext.getShaderVersion(); + if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion) + { + infoSink.info.prefix(EPrefixError); + infoSink.info << "unsupported shader version"; + success = false; + } if (success) { + mPragma = parseContext.pragma(); + if (mPragma.stdgl.invariantAll) + { + symbolTable.setGlobalInvariant(); + } + TIntermNode* root = parseContext.treeRoot; success = intermediate.postProcess(root); @@ -360,7 +393,8 @@ void TCompiler::setResourceString() << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset - << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset; + << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset + << ":NV_draw_buffers:" << compileResources.NV_draw_buffers; builtInResourcesString = strstream.str(); } @@ -377,7 +411,6 @@ void TCompiler::clearResults() uniforms.clear(); expandedUniforms.clear(); varyings.clear(); - expandedVaryings.clear(); interfaceBlocks.clear(); builtInFunctionEmulator.Cleanup(); @@ -507,13 +540,12 @@ void TCompiler::collectVariables(TIntermNode* root) &uniforms, &varyings, &interfaceBlocks, - hashFunction); + hashFunction, + symbolTable); root->traverse(&collect); - // For backwards compatiblity with ShGetVariableInfo, expand struct - // uniforms and varyings into separate variables for each field. - sh::ExpandVariables(uniforms, &expandedUniforms); - sh::ExpandVariables(varyings, &expandedVaryings); + // This is for enforcePackingRestriction(). + sh::ExpandUniforms(uniforms, &expandedUniforms); } bool TCompiler::enforcePackingRestrictions() @@ -581,3 +613,10 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const { return builtInFunctionEmulator; } + +void TCompiler::writePragma() +{ + TInfoSinkBase &sink = infoSink.obj; + if (mPragma.stdgl.invariantAll) + sink << "#pragma STDGL invariant(all)\n"; +} diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.h b/src/3rdparty/angle/src/compiler/translator/Compiler.h index ca0c157884..b6c9d13ed0 100644 --- a/src/3rdparty/angle/src/compiler/translator/Compiler.h +++ b/src/3rdparty/angle/src/compiler/translator/Compiler.h @@ -18,6 +18,7 @@ #include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/HashNames.h" #include "compiler/translator/InfoSink.h" +#include "compiler/translator/Pragma.h" #include "compiler/translator/SymbolTable.h" #include "compiler/translator/VariableInfo.h" #include "third_party/compiler/ArrayBoundsClamper.h" @@ -71,9 +72,7 @@ class TCompiler : public TShHandleBase const std::vector &getAttributes() const { return attributes; } const std::vector &getOutputVariables() const { return outputVariables; } const std::vector &getUniforms() const { return uniforms; } - const std::vector &getExpandedUniforms() const { return expandedUniforms; } const std::vector &getVaryings() const { return varyings; } - const std::vector &getExpandedVaryings() const { return expandedVaryings; } const std::vector &getInterfaceBlocks() const { return interfaceBlocks; } ShHashFunction64 getHashFunction() const { return hashFunction; } @@ -81,7 +80,7 @@ class TCompiler : public TShHandleBase TSymbolTable& getSymbolTable() { return symbolTable; } ShShaderSpec getShaderSpec() const { return shaderSpec; } ShShaderOutput getOutputType() const { return outputType; } - std::string getBuiltInResourcesString() const { return builtInResourcesString; } + const std::string &getBuiltInResourcesString() const { return builtInResourcesString; } // Get the resources set by InitBuiltInSymbolTable const ShBuiltInResources& getResources() const; @@ -131,6 +130,8 @@ class TCompiler : public TShHandleBase bool limitExpressionComplexity(TIntermNode* root); // Get built-in extensions with default behavior. const TExtensionBehavior& getExtensionBehavior() const; + const TPragma& getPragma() const { return mPragma; } + void writePragma(); const ArrayBoundsClamper& getArrayBoundsClamper() const; ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const; @@ -141,7 +142,6 @@ class TCompiler : public TShHandleBase std::vector uniforms; std::vector expandedUniforms; std::vector varyings; - std::vector expandedVaryings; std::vector interfaceBlocks; private: @@ -174,6 +174,8 @@ class TCompiler : public TShHandleBase // name hashing. ShHashFunction64 hashFunction; NameMap nameMap; + + TPragma mPragma; }; // diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp index 334eb0bfa8..f98d32b2b7 100644 --- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp +++ b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp @@ -14,6 +14,9 @@ namespace sh { + +// Detect Loop Discontinuity + bool DetectLoopDiscontinuity::traverse(TIntermNode *node) { mLoopDepth = 0; @@ -74,6 +77,55 @@ bool containsLoopDiscontinuity(TIntermNode *node) return detectLoopDiscontinuity.traverse(node); } +// Detect Any Loop + +bool DetectAnyLoop::traverse(TIntermNode *node) +{ + mHasLoop = false; + node->traverse(this); + return mHasLoop; +} + +bool DetectAnyLoop::visitLoop(Visit visit, TIntermLoop *loop) +{ + mHasLoop = true; + return false; +} + +// The following definitions stop all traversal when we have found a loop +bool DetectAnyLoop::visitBinary(Visit, TIntermBinary *) +{ + return !mHasLoop; +} + +bool DetectAnyLoop::visitUnary(Visit, TIntermUnary *) +{ + return !mHasLoop; +} + +bool DetectAnyLoop::visitSelection(Visit, TIntermSelection *) +{ + return !mHasLoop; +} + +bool DetectAnyLoop::visitAggregate(Visit, TIntermAggregate *) +{ + return !mHasLoop; +} + +bool DetectAnyLoop::visitBranch(Visit, TIntermBranch *) +{ + return !mHasLoop; +} + +bool containsAnyLoop(TIntermNode *node) +{ + DetectAnyLoop detectAnyLoop; + return detectAnyLoop.traverse(node); +} + +// Detect Gradient Operation + bool DetectGradientOperation::traverse(TIntermNode *node) { mGradientOperation = false; diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h index 35d66cbc2e..67e37be398 100644 --- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h +++ b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h @@ -32,6 +32,25 @@ class DetectLoopDiscontinuity : public TIntermTraverser bool containsLoopDiscontinuity(TIntermNode *node); +// Checks for the existence of any loop +class DetectAnyLoop : public TIntermTraverser +{ +public: + bool traverse(TIntermNode *node); + +protected: + bool visitBinary(Visit, TIntermBinary *); + bool visitUnary(Visit, TIntermUnary *); + bool visitSelection(Visit, TIntermSelection *); + bool visitAggregate(Visit, TIntermAggregate *); + bool visitLoop(Visit, TIntermLoop *); + bool visitBranch(Visit, TIntermBranch *); + + bool mHasLoop; +}; + +bool containsAnyLoop(TIntermNode *node); + // Checks for intrinsic functions which compute gradients class DetectGradientOperation : public TIntermTraverser { diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp index 59d2835f7b..f67a03aa93 100644 --- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp +++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp @@ -13,10 +13,10 @@ static TBehavior getBehavior(const std::string& str) { - static const std::string kRequire("require"); - static const std::string kEnable("enable"); - static const std::string kDisable("disable"); - static const std::string kWarn("warn"); + const char kRequire[] = "require"; + const char kEnable[] = "enable"; + const char kDisable[] = "disable"; + const char kWarn[] = "warn"; if (str == kRequire) return EBhRequire; else if (str == kEnable) return EBhEnable; @@ -46,50 +46,61 @@ void TDirectiveHandler::handleError(const pp::SourceLocation& loc, void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, const std::string& name, - const std::string& value) + const std::string& value, + bool stdgl) { - static const std::string kSTDGL("STDGL"); - static const std::string kOptimize("optimize"); - static const std::string kDebug("debug"); - static const std::string kOn("on"); - static const std::string kOff("off"); + if (stdgl) + { + const char kInvariant[] = "invariant"; + const char kAll[] = "all"; - bool invalidValue = false; - if (name == kSTDGL) - { + if (name == kInvariant && value == kAll) + mPragma.stdgl.invariantAll = true; // The STDGL pragma is used to reserve pragmas for use by future - // revisions of GLSL. Ignore it. + // revisions of GLSL. Do not generate an error on unexpected + // name and value. return; } - else if (name == kOptimize) - { - if (value == kOn) mPragma.optimize = true; - else if (value == kOff) mPragma.optimize = false; - else invalidValue = true; - } - else if (name == kDebug) - { - if (value == kOn) mPragma.debug = true; - else if (value == kOff) mPragma.debug = false; - else invalidValue = true; - } else { - mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name); - return; - } + const char kOptimize[] = "optimize"; + const char kDebug[] = "debug"; + const char kOn[] = "on"; + const char kOff[] = "off"; - if (invalidValue) - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, - "invalid pragma value", value, - "'on' or 'off' expected"); + bool invalidValue = false; + if (name == kOptimize) + { + if (value == kOn) mPragma.optimize = true; + else if (value == kOff) mPragma.optimize = false; + else invalidValue = true; + } + else if (name == kDebug) + { + if (value == kOn) mPragma.debug = true; + else if (value == kOff) mPragma.debug = false; + else invalidValue = true; + } + else + { + mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name); + return; + } + + if (invalidValue) + { + mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, + "invalid pragma value", value, + "'on' or 'off' expected"); + } + } } void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, const std::string& name, const std::string& behavior) { - static const std::string kExtAll("all"); + const char kExtAll[] = "all"; TBehavior behaviorVal = getBehavior(behavior); if (behaviorVal == EBhUndefined) diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h index 69418c277a..0433c3bf89 100644 --- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h +++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h @@ -29,7 +29,8 @@ class TDirectiveHandler : public pp::DirectiveHandler virtual void handlePragma(const pp::SourceLocation& loc, const std::string& name, - const std::string& value); + const std::string& value, + bool stdgl); virtual void handleExtension(const pp::SourceLocation& loc, const std::string& name, diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp index b155545ad2..aa0f31d170 100644 --- a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp +++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp @@ -133,6 +133,14 @@ bool CompareStructure(const TType &leftNodeType, // //////////////////////////////////////////////////////////////// +void TIntermTyped::setTypePreservePrecision(const TType &t) +{ + TPrecision precision = getPrecision(); + mType = t; + ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined); + mType.setPrecision(precision); +} + #define REPLACE_IF_IS(node, type, original, replacement) \ if (node == original) { \ node = static_cast(replacement); \ @@ -237,6 +245,52 @@ void TIntermAggregate::enqueueChildren(std::queue *nodeQueue) con } } +void TIntermAggregate::setPrecisionFromChildren() +{ + if (getBasicType() == EbtBool) + { + mType.setPrecision(EbpUndefined); + return; + } + + TPrecision precision = EbpUndefined; + TIntermSequence::iterator childIter = mSequence.begin(); + while (childIter != mSequence.end()) + { + TIntermTyped *typed = (*childIter)->getAsTyped(); + if (typed) + precision = GetHigherPrecision(typed->getPrecision(), precision); + ++childIter; + } + mType.setPrecision(precision); +} + +void TIntermAggregate::setBuiltInFunctionPrecision() +{ + // All built-ins returning bool should be handled as ops, not functions. + ASSERT(getBasicType() != EbtBool); + + TPrecision precision = EbpUndefined; + TIntermSequence::iterator childIter = mSequence.begin(); + while (childIter != mSequence.end()) + { + TIntermTyped *typed = (*childIter)->getAsTyped(); + // ESSL spec section 8: texture functions get their precision from the sampler. + if (typed && IsSampler(typed->getBasicType())) + { + precision = typed->getPrecision(); + break; + } + ++childIter; + } + // ESSL 3.0 spec section 8: textureSize always gets highp precision. + // All other functions that take a sampler are assumed to be texture functions. + if (mName.find("textureSize") == 0) + mType.setPrecision(EbpHigh); + else + mType.setPrecision(precision); +} + bool TIntermSelection::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { @@ -336,6 +390,7 @@ bool TIntermUnary::promote(TInfoSink &) return false; break; case EOpNegative: + case EOpPositive: case EOpPostIncrement: case EOpPostDecrement: case EOpPreIncrement: @@ -1068,6 +1123,27 @@ TIntermTyped *TIntermConstantUnion::fold( } break; + case EOpPositive: + switch (getType().getBasicType()) + { + case EbtFloat: + tempConstArray[i].setFConst(unionArray[i].getFConst()); + break; + case EbtInt: + tempConstArray[i].setIConst(unionArray[i].getIConst()); + break; + case EbtUInt: + tempConstArray[i].setUConst(static_cast( + static_cast(unionArray[i].getUConst()))); + break; + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return NULL; + } + break; + case EOpLogicalNot: // this code is written for possible future use, // will not get executed currently diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.h b/src/3rdparty/angle/src/compiler/translator/IntermNode.h index ec440da010..32c70f4671 100644 --- a/src/3rdparty/angle/src/compiler/translator/IntermNode.h +++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.h @@ -45,6 +45,7 @@ enum TOperator // EOpNegative, + EOpPositive, EOpLogicalNot, EOpVectorLogicalNot, @@ -265,6 +266,7 @@ class TIntermTyped : public TIntermNode virtual bool hasSideEffects() const = 0; void setType(const TType &t) { mType = t; } + void setTypePreservePrecision(const TType &t); const TType &getType() const { return mType; } TType *getTypePointer() { return &mType; } @@ -613,6 +615,9 @@ class TIntermAggregate : public TIntermOperator virtual void enqueueChildren(std::queue *nodeQueue) const; + void setPrecisionFromChildren(); + void setBuiltInFunctionPrecision(); + protected: TIntermAggregate(const TIntermAggregate &); // disallow copy constructor TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator diff --git a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp index ef4f83307c..e558683c55 100644 --- a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp @@ -198,6 +198,7 @@ TIntermTyped *TIntermediate::addUnaryMath( case EOpPostDecrement: case EOpPreDecrement: case EOpNegative: + case EOpPositive: if (child->getType().getBasicType() == EbtStruct || child->getType().isArray()) { diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp index 6d07cccc04..ed590967b1 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp +++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp @@ -395,6 +395,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node) switch (node->getOp()) { case EOpNegative: preString = "(-"; break; + case EOpPositive: preString = "(+"; break; case EOpVectorLogicalNot: preString = "not("; break; case EOpLogicalNot: preString = "(!"; break; @@ -574,7 +575,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) // Function declaration. ASSERT(visit == PreVisit); writeVariableType(node->getType()); - out << " " << hashName(node->getName()); + out << " " << hashFunctionName(node->getName()); out << "("; writeFunctionParameters(*(node->getSequence())); @@ -649,17 +650,18 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) mDeclaringVariables = false; } break; - case EOpInvariantDeclaration: { - // Invariant declaration. - ASSERT(visit == PreVisit); + case EOpInvariantDeclaration: + // Invariant declaration. + ASSERT(visit == PreVisit); + { const TIntermSequence *sequence = node->getSequence(); ASSERT(sequence && sequence->size() == 1); const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode(); ASSERT(symbol); - out << "invariant " << symbol->getSymbol() << ";"; - visitChildren = false; - break; + out << "invariant " << hashVariableName(symbol->getSymbol()); } + visitChildren = false; + break; case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break; @@ -741,7 +743,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction); break; case EOpComma: - writeTriplet(visit, NULL, ", ", NULL); + writeTriplet(visit, "(", ", ", ")"); break; case EOpMod: diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp index a5ea71599d..30bbbff0f5 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp @@ -135,6 +135,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator) mUniqueIndex = 0; mContainsLoopDiscontinuity = false; + mContainsAnyLoop = false; mOutputLod0Function = false; mInsideDiscontinuousLoop = false; mNestedLoopDepth = 0; @@ -172,6 +173,7 @@ OutputHLSL::~OutputHLSL() void OutputHLSL::output() { mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot); + mContainsAnyLoop = containsAnyLoop(mContext.treeRoot); const std::vector &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot); makeFlaggedStructMaps(flaggedStructs); @@ -320,14 +322,22 @@ void OutputHLSL::header() if (mUsesDiscardRewriting) { - out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n"; + out << "#define ANGLE_USES_DISCARD_REWRITING\n"; } if (mUsesNestedBreak) { - out << "#define ANGLE_USES_NESTED_BREAK" << "\n"; + out << "#define ANGLE_USES_NESTED_BREAK\n"; } + out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n" + "#define LOOP [loop]\n" + "#define FLATTEN [flatten]\n" + "#else\n" + "#define LOOP\n" + "#define FLATTEN\n" + "#endif\n"; + if (mContext.shaderType == GL_FRAGMENT_SHADER) { TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers"); @@ -1747,6 +1757,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) switch (node->getOp()) { case EOpNegative: outputTriplet(visit, "(-", "", ")"); break; + case EOpPositive: outputTriplet(visit, "(+", "", ")"); break; case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break; case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break; case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break; @@ -1860,15 +1871,20 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration { - if (!mInsideFunction) - { - out << "static "; - } - - out << TypeString(variable->getType()) + " "; - for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++) { + if (isSingleStatement(*sit)) + { + mUnfoldShortCircuit->traverse(*sit); + } + + if (!mInsideFunction) + { + out << "static "; + } + + out << TypeString(variable->getType()) + " "; + TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); if (symbol) @@ -1884,7 +1900,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) if (*sit != sequence->back()) { - out << ", "; + out << ";\n"; } } } @@ -1925,7 +1941,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) case EOpPrototype: if (visit == PreVisit) { - out << TypeString(node->getType()) << " " << Decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "("); + out << TypeString(node->getType()) << " " << Decorate(TFunction::unmangleName(node->getName())) << (mOutputLod0Function ? "Lod0(" : "("); TIntermSequence *arguments = node->getSequence(); @@ -2287,6 +2303,15 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) { mUnfoldShortCircuit->traverse(node->getCondition()); + // D3D errors when there is a gradient operation in a loop in an unflattened if + // however flattening all the ifs in branch heavy shaders made D3D error too. + // As a temporary workaround we flatten the ifs only if there is at least a loop + // present somewhere in the shader. + if (mContext.shaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop) + { + out << "FLATTEN "; + } + out << "if ("; node->getCondition()->traverse(this); @@ -2367,14 +2392,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) if (node->getType() == ELoopDoWhile) { - out << "{do\n"; + out << "{LOOP do\n"; outputLineDirective(node->getLine().first_line); out << "{\n"; } else { - out << "{for("; + out << "{LOOP for("; if (node->getInit()) { @@ -2503,6 +2528,12 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node) { return false; } + else if (aggregate->getOp() == EOpDeclaration) + { + // Declaring multiple comma-separated variables must be considered multiple statements + // because each individual declaration has side effects which are visible in the next. + return false; + } else { for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++) @@ -2675,7 +2706,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) // for(int index = initial; index < clampedLimit; index += increment) - out << "for("; + out << "LOOP for("; index->traverse(this); out << " = "; out << initial; diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h index bec02479bb..5525e6eaa6 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h @@ -144,6 +144,7 @@ class OutputHLSL : public TIntermTraverser int mUniqueIndex; // For creating unique names bool mContainsLoopDiscontinuity; + bool mContainsAnyLoop; bool mOutputLod0Function; bool mInsideDiscontinuousLoop; int mNestedLoopDepth; diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp index ff0a49667c..37969b5468 100644 --- a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp @@ -1004,12 +1004,12 @@ void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char* directiveHandler.handleExtension(srcLoc, extName, behavior); } -void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value) +void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl) { pp::SourceLocation srcLoc; srcLoc.file = loc.first_file; srcLoc.line = loc.first_line; - directiveHandler.handlePragma(srcLoc, name, value); + directiveHandler.handlePragma(srcLoc, name, value, stdgl); } ///////////////////////////////////////////////////////////////////////////////// @@ -1364,11 +1364,18 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv { error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str()); recover(); - return NULL; } else { + const TString kGlFrontFacing("gl_FrontFacing"); + if (*identifier == kGlFrontFacing) + { + error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str()); + recover(); + return NULL; + } + symbolTable.addInvariantVarying(*identifier); const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol); ASSERT(variable); const TType &type = variable->getType(); diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.h b/src/3rdparty/angle/src/compiler/translator/ParseContext.h index 1f4cbdeba9..414c475cbb 100644 --- a/src/3rdparty/angle/src/compiler/translator/ParseContext.h +++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.h @@ -116,7 +116,7 @@ struct TParseContext { bool supportsExtension(const char* extension); bool isExtensionEnabled(const char* extension) const; void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior); - void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value); + void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl); bool containsSampler(TType& type); bool areAllChildConst(TIntermAggregate* aggrNode); diff --git a/src/3rdparty/angle/src/compiler/translator/Pragma.h b/src/3rdparty/angle/src/compiler/translator/Pragma.h index 2f744123b8..4a930a2962 100644 --- a/src/3rdparty/angle/src/compiler/translator/Pragma.h +++ b/src/3rdparty/angle/src/compiler/translator/Pragma.h @@ -7,13 +7,23 @@ #ifndef COMPILER_PRAGMA_H_ #define COMPILER_PRAGMA_H_ -struct TPragma { +struct TPragma +{ + struct STDGL + { + STDGL() : invariantAll(false) { } + + bool invariantAll; + }; + + // By default optimization is turned on and debug is turned off. TPragma() : optimize(true), debug(false) { } TPragma(bool o, bool d) : optimize(o), debug(d) { } bool optimize; bool debug; + STDGL stdgl; }; #endif // COMPILER_PRAGMA_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp index 20ce71605c..0d6a1d64cf 100644 --- a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp @@ -37,72 +37,6 @@ bool isInitialized = false; // and the shading language compiler. // -static bool CheckVariableMaxLengths(const ShHandle handle, - size_t expectedValue) -{ - size_t activeUniformLimit = 0; - ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit); - size_t activeAttribLimit = 0; - ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit); - size_t varyingLimit = 0; - ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit); - return (expectedValue == activeUniformLimit && - expectedValue == activeAttribLimit && - expectedValue == varyingLimit); -} - -bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue) -{ - size_t mappedNameMaxLength = 0; - ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength); - return (expectedValue == mappedNameMaxLength); -} - -template -const sh::ShaderVariable *ReturnVariable(const std::vector &infoList, int index) -{ - if (index < 0 || static_cast(index) >= infoList.size()) - { - return NULL; - } - - return &infoList[index]; -} - -const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index) -{ - switch (varType) - { - case SH_ACTIVE_ATTRIBUTES: - return ReturnVariable(compiler->getAttributes(), index); - case SH_ACTIVE_UNIFORMS: - return ReturnVariable(compiler->getExpandedUniforms(), index); - case SH_VARYINGS: - return ReturnVariable(compiler->getExpandedVaryings(), index); - default: - UNREACHABLE(); - return NULL; - } -} - -ShPrecisionType ConvertPrecision(sh::GLenum precision) -{ - switch (precision) - { - case GL_HIGH_FLOAT: - case GL_HIGH_INT: - return SH_PRECISION_HIGHP; - case GL_MEDIUM_FLOAT: - case GL_MEDIUM_INT: - return SH_PRECISION_MEDIUMP; - case GL_LOW_FLOAT: - case GL_LOW_INT: - return SH_PRECISION_LOWP; - default: - return SH_PRECISION_UNDEFINED; - } -} - template const std::vector *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType); @@ -150,32 +84,48 @@ const std::vector *GetShaderVariables(const ShHandle handle, ShaderVariabl return GetVariableList(compiler, variableType); } +TCompiler *GetCompilerFromHandle(ShHandle handle) +{ + if (!handle) + return NULL; + TShHandleBase *base = static_cast(handle); + return base->getAsCompiler(); } +TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle) +{ + if (!handle) + return NULL; + TShHandleBase *base = static_cast(handle); + return base->getAsTranslatorHLSL(); +} + +} // namespace anonymous + // // Driver must call this first, once, before doing any other compiler operations. // Subsequent calls to this function are no-op. // -int ShInitialize() +bool ShInitialize() { if (!isInitialized) { isInitialized = InitProcess(); } - return isInitialized ? 1 : 0; + return isInitialized; } // // Cleanup symbol tables // -int ShFinalize() +bool ShFinalize() { if (isInitialized) { DetachProcess(); isInitialized = false; } - return 1; + return true; } // @@ -183,6 +133,9 @@ int ShFinalize() // void ShInitBuiltInResources(ShBuiltInResources* resources) { + // Make comparable. + memset(resources, 0, sizeof(*resources)); + // Constants. resources->MaxVertexAttribs = 8; resources->MaxVertexUniformVectors = 128; @@ -201,6 +154,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) resources->EXT_frag_depth = 0; resources->EXT_shader_texture_lod = 0; + resources->NV_draw_buffers = 0; + // Disable highp precision in fragment shader by default. resources->FragmentPrecisionHigh = 0; @@ -251,23 +206,13 @@ void ShDestruct(ShHandle handle) DeleteCompiler(base->getAsCompiler()); } -void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString) +const std::string &ShGetBuiltInResourcesString(const ShHandle handle) { - if (!handle || !outString) - { - return; - } - - TShHandleBase *base = static_cast(handle); - TCompiler *compiler = base->getAsCompiler(); - if (!compiler) - { - return; - } - - strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen); - outString[outStringLen - 1] = '\0'; + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return compiler->getBuiltInResourcesString(); } + // // Do an actual compile on the given strings. The result is left // in the given compile object. @@ -275,219 +220,62 @@ void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, cha // Return: The return value of ShCompile is really boolean, indicating // success or failure. // -int ShCompile( +bool ShCompile( const ShHandle handle, - const char* const shaderStrings[], + const char *const shaderStrings[], size_t numStrings, int compileOptions) { - if (handle == 0) - return 0; + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); - TShHandleBase* base = reinterpret_cast(handle); - TCompiler* compiler = base->getAsCompiler(); - if (compiler == 0) - return 0; - - bool success = compiler->compile(shaderStrings, numStrings, compileOptions); - return success ? 1 : 0; + return compiler->compile(shaderStrings, numStrings, compileOptions); } -void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params) +int ShGetShaderVersion(const ShHandle handle) { - if (!handle || !params) - return; + TCompiler* compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return compiler->getShaderVersion(); +} - TShHandleBase* base = static_cast(handle); - TCompiler* compiler = base->getAsCompiler(); - if (!compiler) return; - - switch(pname) - { - case SH_INFO_LOG_LENGTH: - *params = compiler->getInfoSink().info.size() + 1; - break; - case SH_OBJECT_CODE_LENGTH: - *params = compiler->getInfoSink().obj.size() + 1; - break; - case SH_ACTIVE_UNIFORMS: - *params = compiler->getExpandedUniforms().size(); - break; - case SH_ACTIVE_UNIFORM_MAX_LENGTH: - *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); - break; - case SH_ACTIVE_ATTRIBUTES: - *params = compiler->getAttributes().size(); - break; - case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); - break; - case SH_VARYINGS: - *params = compiler->getExpandedVaryings().size(); - break; - case SH_VARYING_MAX_LENGTH: - *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); - break; - case SH_MAPPED_NAME_MAX_LENGTH: - // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to - // handle array and struct dereferences. - *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); - break; - case SH_NAME_MAX_LENGTH: - *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); - break; - case SH_HASHED_NAME_MAX_LENGTH: - if (compiler->getHashFunction() == NULL) { - *params = 0; - } else { - // 64 bits hashing output requires 16 bytes for hex - // representation. - const char HashedNamePrefix[] = HASHED_NAME_PREFIX; - (void)HashedNamePrefix; - *params = 16 + sizeof(HashedNamePrefix); - } - break; - case SH_HASHED_NAMES_COUNT: - *params = compiler->getNameMap().size(); - break; - case SH_SHADER_VERSION: - *params = compiler->getShaderVersion(); - break; - case SH_RESOURCES_STRING_LENGTH: - *params = compiler->getBuiltInResourcesString().length() + 1; - break; - case SH_OUTPUT_TYPE: - *params = compiler->getOutputType(); - break; - default: UNREACHABLE(); - } +ShShaderOutput ShGetShaderOutputType(const ShHandle handle) +{ + TCompiler* compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return compiler->getOutputType(); } // // Return any compiler log of messages for the application. // -void ShGetInfoLog(const ShHandle handle, char* infoLog) +const std::string &ShGetInfoLog(const ShHandle handle) { - if (!handle || !infoLog) - return; + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); - TShHandleBase* base = static_cast(handle); - TCompiler* compiler = base->getAsCompiler(); - if (!compiler) return; - - TInfoSink& infoSink = compiler->getInfoSink(); - strcpy(infoLog, infoSink.info.c_str()); + TInfoSink &infoSink = compiler->getInfoSink(); + return infoSink.info.str(); } // // Return any object code. // -void ShGetObjectCode(const ShHandle handle, char* objCode) +const std::string &ShGetObjectCode(const ShHandle handle) { - if (!handle || !objCode) - return; + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); - TShHandleBase* base = static_cast(handle); - TCompiler* compiler = base->getAsCompiler(); - if (!compiler) return; - - TInfoSink& infoSink = compiler->getInfoSink(); - strcpy(objCode, infoSink.obj.c_str()); + TInfoSink &infoSink = compiler->getInfoSink(); + return infoSink.obj.str(); } -void ShGetVariableInfo(const ShHandle handle, - ShShaderInfo varType, - int index, - size_t* length, - int* size, - sh::GLenum* type, - ShPrecisionType* precision, - int* staticUse, - char* name, - char* mappedName) +const std::map *ShGetNameHashingMap( + const ShHandle handle) { - if (!handle || !size || !type || !precision || !staticUse || !name) - return; - ASSERT((varType == SH_ACTIVE_ATTRIBUTES) || - (varType == SH_ACTIVE_UNIFORMS) || - (varType == SH_VARYINGS)); - - TShHandleBase* base = reinterpret_cast(handle); - TCompiler* compiler = base->getAsCompiler(); - if (compiler == 0) - return; - - const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index); - if (!varInfo) - { - return; - } - - if (length) *length = varInfo->name.size(); - *size = varInfo->elementCount(); - *type = varInfo->type; - *precision = ConvertPrecision(varInfo->precision); - *staticUse = varInfo->staticUse ? 1 : 0; - - // This size must match that queried by - // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH - // in ShGetInfo, below. - size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); - ASSERT(CheckVariableMaxLengths(handle, variableLength)); - strncpy(name, varInfo->name.c_str(), variableLength); - name[variableLength - 1] = 0; - if (mappedName) - { - // This size must match that queried by - // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below. - size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec()); - ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength)); - strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength); - mappedName[maxMappedNameLength - 1] = 0; - } -} - -void ShGetNameHashingEntry(const ShHandle handle, - int index, - char* name, - char* hashedName) -{ - if (!handle || !name || !hashedName || index < 0) - return; - - TShHandleBase* base = static_cast(handle); - TCompiler* compiler = base->getAsCompiler(); - if (!compiler) return; - - const NameMap& nameMap = compiler->getNameMap(); - if (index >= static_cast(nameMap.size())) - return; - - NameMap::const_iterator it = nameMap.begin(); - for (int i = 0; i < index; ++i) - ++it; - - size_t len = it->first.length() + 1; - size_t max_len = 0; - ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len); - if (len > max_len) { - ASSERT(false); - len = max_len; - } - strncpy(name, it->first.c_str(), len); - // To be on the safe side in case the source is longer than expected. - name[len - 1] = '\0'; - - len = it->second.length() + 1; - max_len = 0; - ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len); - if (len > max_len) { - ASSERT(false); - len = max_len; - } - strncpy(hashedName, it->second.c_str(), len); - // To be on the safe side in case the source is longer than expected. - hashedName[len - 1] = '\0'; + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + return &(compiler->getNameMap()); } const std::vector *ShGetUniforms(const ShHandle handle) @@ -515,11 +303,11 @@ const std::vector *ShGetInterfaceBlocks(const ShHandle handl return GetShaderVariables(handle, SHADERVAR_INTERFACEBLOCK); } -int ShCheckVariablesWithinPackingLimits( - int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize) +bool ShCheckVariablesWithinPackingLimits( + int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize) { if (varInfoArraySize == 0) - return 1; + return true; ASSERT(varInfoArray); std::vector variables; for (size_t ii = 0; ii < varInfoArraySize; ++ii) @@ -528,24 +316,17 @@ int ShCheckVariablesWithinPackingLimits( variables.push_back(var); } VariablePacker packer; - return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0; + return packer.CheckVariablesWithinPackingLimits(maxVectors, variables); } bool ShGetInterfaceBlockRegister(const ShHandle handle, - const char *interfaceBlockName, + const std::string &interfaceBlockName, unsigned int *indexOut) { - if (!handle || !interfaceBlockName || !indexOut) - { - return false; - } + ASSERT(indexOut); - TShHandleBase* base = static_cast(handle); - TranslatorHLSL* translator = base->getAsTranslatorHLSL(); - if (!translator) - { - return false; - } + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); if (!translator->hasInterfaceBlock(interfaceBlockName)) { @@ -557,20 +338,12 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle, } bool ShGetUniformRegister(const ShHandle handle, - const char *uniformName, + const std::string &uniformName, unsigned int *indexOut) { - if (!handle || !uniformName || !indexOut) - { - return false; - } - - TShHandleBase* base = static_cast(handle); - TranslatorHLSL* translator = base->getAsTranslatorHLSL(); - if (!translator) - { - return false; - } + ASSERT(indexOut); + TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); + ASSERT(translator); if (!translator->hasUniform(uniformName)) { diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp index 822c558c9b..3098a7f0c9 100644 --- a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp @@ -9,6 +9,8 @@ #include +#include "compiler/translator/compilerdebug.h" + namespace sh { @@ -53,6 +55,126 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other) return *this; } +bool ShaderVariable::operator==(const ShaderVariable &other) const +{ + if (type != other.type || + precision != other.precision || + name != other.name || + mappedName != other.mappedName || + arraySize != other.arraySize || + staticUse != other.staticUse || + fields.size() != other.fields.size() || + structName != other.structName) + { + return false; + } + for (size_t ii = 0; ii < fields.size(); ++ii) + { + if (fields[ii] != other.fields[ii]) + return false; + } + return true; +} + +bool ShaderVariable::findInfoByMappedName( + const std::string &mappedFullName, + const ShaderVariable **leafVar, std::string *originalFullName) const +{ + ASSERT(leafVar && originalFullName); + // There are three cases: + // 1) the top variable is of struct type; + // 2) the top variable is an array; + // 3) otherwise. + size_t pos = mappedFullName.find_first_of(".["); + std::string topName; + + if (pos == std::string::npos) + { + // Case 3. + if (mappedFullName != this->mappedName) + return false; + *originalFullName = this->name; + *leafVar = this; + return true; + } + else + { + std::string topName = mappedFullName.substr(0, pos); + if (topName != this->mappedName) + return false; + std::string originalName = this->name; + std::string remaining; + if (mappedFullName[pos] == '[') + { + // Case 2. + size_t closePos = mappedFullName.find_first_of(']'); + if (closePos < pos || closePos == std::string::npos) + return false; + // Append '[index]'. + originalName += mappedFullName.substr(pos, closePos - pos + 1); + if (closePos + 1 == mappedFullName.size()) + { + *originalFullName = originalName; + *leafVar = this; + return true; + } + else + { + // In the form of 'a[0].b', so after ']', '.' is expected. + if (mappedFullName[closePos + 1] != '.') + return false; + remaining = mappedFullName.substr(closePos + 2); // Skip "]." + } + } + else + { + // Case 1. + remaining = mappedFullName.substr(pos + 1); // Skip "." + } + for (size_t ii = 0; ii < this->fields.size(); ++ii) + { + const ShaderVariable *fieldVar = NULL; + std::string originalFieldName; + bool found = fields[ii].findInfoByMappedName( + remaining, &fieldVar, &originalFieldName); + if (found) + { + *originalFullName = originalName + "." + originalFieldName; + *leafVar = fieldVar; + return true; + } + } + return false; + } +} + +bool ShaderVariable::isSameVariableAtLinkTime( + const ShaderVariable &other, bool matchPrecision) const +{ + if (type != other.type) + return false; + if (matchPrecision && precision != other.precision) + return false; + if (name != other.name) + return false; + ASSERT(mappedName == other.mappedName); + if (arraySize != other.arraySize) + return false; + if (fields.size() != other.fields.size()) + return false; + for (size_t ii = 0; ii < fields.size(); ++ii) + { + if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], + matchPrecision)) + { + return false; + } + } + if (structName != other.structName) + return false; + return true; +} + Uniform::Uniform() {} @@ -69,6 +191,16 @@ Uniform &Uniform::operator=(const Uniform &other) return *this; } +bool Uniform::operator==(const Uniform &other) const +{ + return ShaderVariable::operator==(other); +} + +bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const +{ + return ShaderVariable::isSameVariableAtLinkTime(other, true); +} + Attribute::Attribute() : location(-1) {} @@ -88,6 +220,12 @@ Attribute &Attribute::operator=(const Attribute &other) return *this; } +bool Attribute::operator==(const Attribute &other) const +{ + return (ShaderVariable::operator==(other) && + location == other.location); +} + InterfaceBlockField::InterfaceBlockField() : isRowMajorLayout(false) {} @@ -107,6 +245,19 @@ InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &o return *this; } +bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const +{ + return (ShaderVariable::operator==(other) && + isRowMajorLayout == other.isRowMajorLayout); +} + +bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime( + const InterfaceBlockField &other) const +{ + return (ShaderVariable::isSameVariableAtLinkTime(other, true) && + isRowMajorLayout == other.isRowMajorLayout); +} + Varying::Varying() : interpolation(INTERPOLATION_SMOOTH), isInvariant(false) @@ -129,6 +280,20 @@ Varying &Varying::operator=(const Varying &other) return *this; } +bool Varying::operator==(const Varying &other) const +{ + return (ShaderVariable::operator==(other) && + interpolation == other.interpolation && + isInvariant == other.isInvariant); +} + +bool Varying::isSameVaryingAtLinkTime(const Varying &other) const +{ + return (ShaderVariable::isSameVariableAtLinkTime(other, false) && + interpolation == other.interpolation && + isInvariant == other.isInvariant); +} + InterfaceBlock::InterfaceBlock() : arraySize(0), layout(BLOCKLAYOUT_PACKED), diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h index 6b0e0c0a03..9cd74218dc 100644 --- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h +++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h @@ -31,6 +31,7 @@ // #include +#include #include "common/angleutils.h" #include "compiler/translator/InfoSink.h" @@ -299,19 +300,21 @@ class TSymbolTableLevel tLevel level; }; -enum ESymbolLevel -{ - COMMON_BUILTINS = 0, - ESSL1_BUILTINS = 1, - ESSL3_BUILTINS = 2, - LAST_BUILTIN_LEVEL = ESSL3_BUILTINS, - GLOBAL_LEVEL = 3 -}; +// Define ESymbolLevel as int rather than an enum since level can go +// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the +// compiler optimizes the >= of the last element to ==. +typedef int ESymbolLevel; +const int COMMON_BUILTINS = 0; +const int ESSL1_BUILTINS = 1; +const int ESSL3_BUILTINS = 2; +const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS; +const int GLOBAL_LEVEL = 3; class TSymbolTable { public: TSymbolTable() + : mGlobalInvariant(false) { // The symbol table cannot be used until push() is called, but // the lack of an initial call to push() can be used to detect @@ -408,6 +411,25 @@ class TSymbolTable // for the specified TBasicType TPrecision getDefaultPrecision(TBasicType type) const; + // This records invariant varyings declared through + // "invariant varying_name;". + void addInvariantVarying(const TString &originalName) + { + mInvariantVaryings.insert(originalName); + } + // If this returns false, the varying could still be invariant + // if it is set as invariant during the varying variable + // declaration - this piece of information is stored in the + // variable's type, not here. + bool isVaryingInvariant(const TString &originalName) const + { + return (mGlobalInvariant || + mInvariantVaryings.count(originalName) > 0); + } + + void setGlobalInvariant() { mGlobalInvariant = true; } + bool getGlobalInvariant() const { return mGlobalInvariant; } + static int nextUniqueId() { return ++uniqueIdCounter; @@ -423,6 +445,9 @@ class TSymbolTable typedef TMap PrecisionStackLevel; std::vector< PrecisionStackLevel *> precisionStack; + std::set mInvariantVaryings; + bool mGlobalInvariant; + static int uniqueIdCounter; }; diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp index 5b99fea948..dcbf3cea1d 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp @@ -16,6 +16,8 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec) void TranslatorESSL::translate(TIntermNode* root) { TInfoSinkBase& sink = getInfoSink().obj; + writePragma(); + // Write built-in extension behaviors. writeExtensionBehavior(); @@ -37,8 +39,13 @@ void TranslatorESSL::writeExtensionBehavior() { for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin(); iter != extensionBehavior.end(); ++iter) { if (iter->second != EBhUndefined) { - sink << "#extension " << iter->first << " : " - << getBehaviorString(iter->second) << "\n"; + if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") { + sink << "#extension GL_NV_draw_buffers : " + << getBehaviorString(iter->second) << "\n"; + } else { + sink << "#extension " << iter->first << " : " + << getBehaviorString(iter->second) << "\n"; + } } } } diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp index 4b2aecab33..6acbf7c5a8 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp @@ -9,18 +9,6 @@ #include "compiler/translator/OutputGLSL.h" #include "compiler/translator/VersionGLSL.h" -static void writeVersion(sh::GLenum type, TIntermNode* root, - TInfoSinkBase& sink) { - TVersionGLSL versionGLSL(type); - root->traverse(&versionGLSL); - int version = versionGLSL.getVersion(); - // We need to write version directive only if it is greater than 110. - // If there is no version directive in the shader, 110 is implied. - if (version > 110) { - sink << "#version " << version << "\n"; - } -} - TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec) : TCompiler(type, spec, SH_GLSL_OUTPUT) { } @@ -29,7 +17,9 @@ void TranslatorGLSL::translate(TIntermNode* root) { TInfoSinkBase& sink = getInfoSink().obj; // Write GLSL version. - writeVersion(getShaderType(), root, sink); + writeVersion(root); + + writePragma(); // Write extension behaviour as needed writeExtensionBehavior(); @@ -46,6 +36,20 @@ void TranslatorGLSL::translate(TIntermNode* root) { root->traverse(&outputGLSL); } +void TranslatorGLSL::writeVersion(TIntermNode *root) +{ + TVersionGLSL versionGLSL(getShaderType(), getPragma()); + root->traverse(&versionGLSL); + int version = versionGLSL.getVersion(); + // We need to write version directive only if it is greater than 110. + // If there is no version directive in the shader, 110 is implied. + if (version > 110) + { + TInfoSinkBase& sink = getInfoSink().obj; + sink << "#version " << version << "\n"; + } +} + void TranslatorGLSL::writeExtensionBehavior() { TInfoSinkBase& sink = getInfoSink().obj; const TExtensionBehavior& extensionBehavior = getExtensionBehavior(); diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h index 3c6c2e426a..766d8d910e 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h @@ -9,14 +9,16 @@ #include "compiler/translator/Compiler.h" -class TranslatorGLSL : public TCompiler { -public: +class TranslatorGLSL : public TCompiler +{ + public: TranslatorGLSL(sh::GLenum type, ShShaderSpec spec); -protected: - virtual void translate(TIntermNode* root); + protected: + virtual void translate(TIntermNode *root); -private: + private: + void writeVersion(TIntermNode *root); void writeExtensionBehavior(); }; diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp index c1a7b7524f..896e1cd7a0 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp @@ -94,6 +94,7 @@ const char *GetOperatorString(TOperator op) case EOpLogicalXor: return "^^"; case EOpLogicalAnd: return "&&"; case EOpNegative: return "-"; + case EOpPositive: return "+"; case EOpVectorLogicalNot: return "not"; case EOpLogicalNot: return "!"; case EOpPostIncrement: return "++"; diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp index f26c1566ac..d8e13788b7 100644 --- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp +++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp @@ -5,6 +5,7 @@ // #include "angle_gl.h" +#include "compiler/translator/SymbolTable.h" #include "compiler/translator/VariableInfo.h" #include "compiler/translator/util.h" #include "common/utilities.h" @@ -131,7 +132,8 @@ CollectVariables::CollectVariables(std::vector *attribs, std::vector *uniforms, std::vector *varyings, std::vector *interfaceBlocks, - ShHashFunction64 hashFunction) + ShHashFunction64 hashFunction, + const TSymbolTable &symbolTable) : mAttribs(attribs), mOutputVariables(outputVariables), mUniforms(uniforms), @@ -140,7 +142,10 @@ CollectVariables::CollectVariables(std::vector *attribs, mPointCoordAdded(false), mFrontFacingAdded(false), mFragCoordAdded(false), - mHashFunction(hashFunction) + mPositionAdded(false), + mPointSizeAdded(false), + mHashFunction(hashFunction), + mSymbolTable(symbolTable) { } @@ -200,12 +205,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) if (!mFragCoordAdded) { Varying info; - info.name = "gl_FragCoord"; - info.mappedName = "gl_FragCoord"; + const char kName[] = "gl_FragCoord"; + info.name = kName; + info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = 0; - info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter. + info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; + info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mFragCoordAdded = true; } @@ -214,12 +221,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) if (!mFrontFacingAdded) { Varying info; - info.name = "gl_FrontFacing"; - info.mappedName = "gl_FrontFacing"; + const char kName[] = "gl_FrontFacing"; + info.name = kName; + info.mappedName = kName; info.type = GL_BOOL; info.arraySize = 0; info.precision = GL_NONE; info.staticUse = true; + info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mFrontFacingAdded = true; } @@ -228,16 +237,50 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) if (!mPointCoordAdded) { Varying info; - info.name = "gl_PointCoord"; - info.mappedName = "gl_PointCoord"; + const char kName[] = "gl_PointCoord"; + info.name = kName; + info.mappedName = kName; info.type = GL_FLOAT_VEC2; info.arraySize = 0; - info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter. + info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; + info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mPointCoordAdded = true; } return; + case EvqPosition: + if (!mPositionAdded) + { + Varying info; + const char kName[] = "gl_Position"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT_VEC4; + info.arraySize = 0; + info.precision = GL_HIGH_FLOAT; // Defined by spec. + info.staticUse = true; + info.isInvariant = mSymbolTable.isVaryingInvariant(kName); + mVaryings->push_back(info); + mPositionAdded = true; + } + return; + case EvqPointSize: + if (!mPointSizeAdded) + { + Varying info; + const char kName[] = "gl_PointSize"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT; + info.arraySize = 0; + info.precision = GL_MEDIUM_FLOAT; // Defined by spec. + info.staticUse = true; + info.isInvariant = mSymbolTable.isVaryingInvariant(kName); + mVaryings->push_back(info); + mPointSizeAdded = true; + } + return; default: break; } @@ -251,8 +294,10 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) class NameHashingTraverser : public GetVariableTraverser { public: - NameHashingTraverser(ShHashFunction64 hashFunction) - : mHashFunction(hashFunction) + NameHashingTraverser(ShHashFunction64 hashFunction, + const TSymbolTable &symbolTable) + : GetVariableTraverser(symbolTable), + mHashFunction(hashFunction) {} private: @@ -312,7 +357,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable, const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field); const TType &fieldType = *field.type(); - GetVariableTraverser traverser; + GetVariableTraverser traverser(mSymbolTable); traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields); interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor); @@ -325,7 +370,7 @@ template void CollectVariables::visitVariable(const TIntermSymbol *variable, std::vector *infoList) const { - NameHashingTraverser traverser(mHashFunction); + NameHashingTraverser traverser(mHashFunction, mSymbolTable); traverser.traverse(variable->getType(), variable->getSymbol(), infoList); } @@ -421,9 +466,8 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) return true; } -template -void ExpandVariables(const std::vector &compact, - std::vector *expanded) +void ExpandUniforms(const std::vector &compact, + std::vector *expanded) { for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++) { @@ -432,7 +476,4 @@ void ExpandVariables(const std::vector &compact, } } -template void ExpandVariables(const std::vector &, std::vector *); -template void ExpandVariables(const std::vector &, std::vector *); - } diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h index 5ac4c46baa..92d376d879 100644 --- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h +++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h @@ -11,6 +11,8 @@ #include "compiler/translator/IntermNode.h" +class TSymbolTable; + namespace sh { @@ -23,7 +25,8 @@ class CollectVariables : public TIntermTraverser std::vector *uniforms, std::vector *varyings, std::vector *interfaceBlocks, - ShHashFunction64 hashFunction); + ShHashFunction64 hashFunction, + const TSymbolTable &symbolTable); virtual void visitSymbol(TIntermSymbol *symbol); virtual bool visitAggregate(Visit, TIntermAggregate *node); @@ -48,13 +51,17 @@ class CollectVariables : public TIntermTraverser bool mFrontFacingAdded; bool mFragCoordAdded; + bool mPositionAdded; + bool mPointSizeAdded; + ShHashFunction64 mHashFunction; + + const TSymbolTable &mSymbolTable; }; -// Expand struct variables to flattened lists of split variables -template -void ExpandVariables(const std::vector &compact, - std::vector *expanded); +// Expand struct uniforms to flattened lists of split variables +void ExpandUniforms(const std::vector &compact, + std::vector *expanded); } diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp index 8edbd009b0..05b111a7a7 100644 --- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp @@ -26,18 +26,12 @@ static const int GLSL_VERSION_120 = 120; // GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that // are built-in types, entire structures or arrays... are all l-values." // -// TODO(alokp): The following two cases of invariant decalaration get lost -// during parsing - they do not get carried over to the intermediate tree. -// Handle these cases: -// 1. When a pragma is used to force all output variables to be invariant: -// - #pragma STDGL invariant(all) -// 2. When a previously decalared or built-in variable is marked invariant: -// - invariant gl_Position; -// - varying vec3 color; invariant color; -// -TVersionGLSL::TVersionGLSL(sh::GLenum type) - : mVersion(GLSL_VERSION_110) +TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma) { + if (pragma.stdgl.invariantAll) + mVersion = GLSL_VERSION_120; + else + mVersion = GLSL_VERSION_110; } void TVersionGLSL::visitSymbol(TIntermSymbol *node) diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h index 30f5a138a0..72368e39d6 100644 --- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h @@ -9,6 +9,8 @@ #include "compiler/translator/IntermNode.h" +#include "compiler/translator/Pragma.h" + // Traverses the intermediate tree to return the minimum GLSL version // required to legally access all built-in features used in the shader. // GLSL 1.1 which is mandated by OpenGL 2.0 provides: @@ -27,7 +29,7 @@ class TVersionGLSL : public TIntermTraverser { public: - TVersionGLSL(sh::GLenum type); + TVersionGLSL(sh::GLenum type, const TPragma &pragma); // Returns 120 if the following is used the shader: // - "invariant", diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.y b/src/3rdparty/angle/src/compiler/translator/glslang.y index 5c945ad5ad..e271de978c 100644 --- a/src/3rdparty/angle/src/compiler/translator/glslang.y +++ b/src/3rdparty/angle/src/compiler/translator/glslang.y @@ -354,6 +354,15 @@ function_call // Treat it like a built-in unary operator. // $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1); + const TType& returnType = fnCandidate->getReturnType(); + if (returnType.getBasicType() == EbtBool) { + // Bool types should not have precision, so we'll override any precision + // that might have been set by addUnaryMath. + $$->setType(returnType); + } else { + // addUnaryMath has set the precision of the node based on the operand. + $$->setTypePreservePrecision(returnType); + } if ($$ == 0) { std::stringstream extraInfoStream; extraInfoStream << "built in unary operator function. Type: " << static_cast($1.intermNode)->getCompleteString(); @@ -362,20 +371,29 @@ function_call YYERROR; } } else { - $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1); + TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1); + aggregate->setType(fnCandidate->getReturnType()); + aggregate->setPrecisionFromChildren(); + $$ = aggregate; } } else { // This is a real function call - $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1); - $$->setType(fnCandidate->getReturnType()); + TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1); + aggregate->setType(fnCandidate->getReturnType()); // this is how we know whether the given function is a builtIn function or a user defined function // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also // if builtIn == true, it's definitely a builtIn function with EOpNull if (!builtIn) - $$->getAsAggregate()->setUserDefined(); - $$->getAsAggregate()->setName(fnCandidate->getMangledName()); + aggregate->setUserDefined(); + aggregate->setName(fnCandidate->getMangledName()); + + // This needs to happen after the name is set + if (builtIn) + aggregate->setBuiltInFunctionPrecision(); + + $$ = aggregate; TQualifier qual; for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) { @@ -388,7 +406,6 @@ function_call } } } - $$->setType(fnCandidate->getReturnType()); } else { // error message was put out by PaFindFunction() // Put on a dummy node for error recovery @@ -500,6 +517,7 @@ unary_expression const char* errorOp = ""; switch($1.op) { case EOpNegative: errorOp = "-"; break; + case EOpPositive: errorOp = "+"; break; case EOpLogicalNot: errorOp = "!"; break; default: break; } @@ -514,7 +532,7 @@ unary_expression // Grammar Note: No traditional style type casts. unary_operator - : PLUS { $$.op = EOpNull; } + : PLUS { $$.op = EOpPositive; } | DASH { $$.op = EOpNegative; } | BANG { $$.op = EOpLogicalNot; } ; @@ -762,7 +780,7 @@ declaration TIntermAggregate *prototype = new TIntermAggregate; prototype->setType(function.getReturnType()); - prototype->setName(function.getName()); + prototype->setName(function.getMangledName()); for (size_t i = 0; i < function.getParamCount(); i++) { diff --git a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp index 56340c6f9e..00780f0454 100644 --- a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp +++ b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp @@ -62,7 +62,9 @@ TString TType::getCompleteString() const TStringStream stream; if (qualifier != EvqTemporary && qualifier != EvqGlobal) - stream << getQualifierString() << " " << getPrecisionString() << " "; + stream << getQualifierString() << " "; + if (precision != EbpUndefined) + stream << getPrecisionString() << " "; if (array) stream << "array[" << getArraySize() << "] of "; if (isMatrix()) @@ -221,6 +223,7 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node) switch (node->getOp()) { case EOpNegative: out << "Negate value"; break; + case EOpPositive: out << "Positive sign"; break; case EOpVectorLogicalNot: case EOpLogicalNot: out << "Negate conditional"; break; @@ -292,6 +295,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node) case EOpFunction: out << "Function Definition: " << node->getName(); break; case EOpFunctionCall: out << "Function Call: " << node->getName(); break; case EOpParameters: out << "Function Parameters: "; break; + case EOpPrototype: out << "Function Prototype: " << node->getName(); break; case EOpConstructFloat: out << "Construct float"; break; case EOpConstructVec2: out << "Construct vec2"; break; diff --git a/src/3rdparty/angle/src/compiler/translator/util.cpp b/src/3rdparty/angle/src/compiler/translator/util.cpp index f74c7d1173..8cc06a658a 100644 --- a/src/3rdparty/angle/src/compiler/translator/util.cpp +++ b/src/3rdparty/angle/src/compiler/translator/util.cpp @@ -9,6 +9,7 @@ #include #include "compiler/preprocessor/numeric_lex.h" +#include "compiler/translator/SymbolTable.h" #include "common/utilities.h" bool atof_clamp(const char *str, float *value) @@ -281,8 +282,47 @@ InterpolationType GetInterpolationType(TQualifier qualifier) } } +GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable) + : mSymbolTable(symbolTable) +{ +} + +template void GetVariableTraverser::setTypeSpecificInfo( + const TType &type, const TString& name, InterfaceBlockField *variable); +template void GetVariableTraverser::setTypeSpecificInfo( + const TType &type, const TString& name, ShaderVariable *variable); +template void GetVariableTraverser::setTypeSpecificInfo( + const TType &type, const TString& name, Uniform *variable); + +template<> +void GetVariableTraverser::setTypeSpecificInfo( + const TType &type, const TString& name, Varying *variable) +{ + ASSERT(variable); + switch (type.getQualifier()) + { + case EvqInvariantVaryingIn: + case EvqInvariantVaryingOut: + variable->isInvariant = true; + break; + case EvqVaryingIn: + case EvqVaryingOut: + if (mSymbolTable.isVaryingInvariant(name)) + { + variable->isInvariant = true; + } + break; + default: + break; + } + + variable->interpolation = GetInterpolationType(type.getQualifier()); +} + template -void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector *output) +void GetVariableTraverser::traverse(const TType &type, + const TString &name, + std::vector *output) { const TStructure *structure = type.getStruct(); @@ -309,15 +349,16 @@ void GetVariableTraverser::traverse(const TType &type, const TString &name, std: traverse(*field->type(), field->name(), &variable.fields); } } - + setTypeSpecificInfo(type, name, &variable); visitVariable(&variable); ASSERT(output); output->push_back(variable); } +template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); +template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); -template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); } diff --git a/src/3rdparty/angle/src/compiler/translator/util.h b/src/3rdparty/angle/src/compiler/translator/util.h index 241e2cc1c2..fb5308759e 100644 --- a/src/3rdparty/angle/src/compiler/translator/util.h +++ b/src/3rdparty/angle/src/compiler/translator/util.h @@ -24,6 +24,8 @@ extern bool atof_clamp(const char *str, float *value); // Return false if overflow happens. extern bool atoi_clamp(const char *str, int *value); +class TSymbolTable; + namespace sh { @@ -38,7 +40,7 @@ TString ArrayString(const TType &type); class GetVariableTraverser { public: - GetVariableTraverser() {} + GetVariableTraverser(const TSymbolTable &symbolTable); template void traverse(const TType &type, const TString &name, std::vector *output); @@ -48,6 +50,14 @@ class GetVariableTraverser virtual void visitVariable(ShaderVariable *newVar) {} private: + // Helper function called by traverse() to fill specific fields + // for attributes/varyings/uniforms. + template + void setTypeSpecificInfo( + const TType &type, const TString &name, VarT *variable) {} + + const TSymbolTable &mSymbolTable; + DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser); }; diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.cpp b/src/3rdparty/angle/src/libEGL/AttributeMap.cpp new file mode 100644 index 0000000000..28dd3d842e --- /dev/null +++ b/src/3rdparty/angle/src/libEGL/AttributeMap.cpp @@ -0,0 +1,40 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "libEGL/AttributeMap.h" + +namespace egl +{ + +AttributeMap::AttributeMap() +{ +} + +AttributeMap::AttributeMap(const EGLint *attributes) +{ + for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + insert(curAttrib[0], curAttrib[1]); + } +} + +void AttributeMap::insert(EGLint key, EGLint value) +{ + mAttributes[key] = value; +} + +bool AttributeMap::contains(EGLint key) const +{ + return (mAttributes.find(key) != mAttributes.end()); +} + +EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const +{ + std::map::const_iterator iter = mAttributes.find(key); + return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue; +} + +} diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.h b/src/3rdparty/angle/src/libEGL/AttributeMap.h new file mode 100644 index 0000000000..f2f082fe21 --- /dev/null +++ b/src/3rdparty/angle/src/libEGL/AttributeMap.h @@ -0,0 +1,33 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef LIBEGL_ATTRIBUTEMAP_H_ +#define LIBEGL_ATTRIBUTEMAP_H_ + +#include + +#include + +namespace egl +{ + +class AttributeMap +{ + public: + AttributeMap(); + explicit AttributeMap(const EGLint *attributes); + + virtual void insert(EGLint key, EGLint value); + virtual bool contains(EGLint key) const; + virtual EGLint get(EGLint key, EGLint defaultValue) const; + + private: + std::map mAttributes; +}; + +} + +#endif // LIBEGL_ATTRIBUTEMAP_H_ diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp index 5a50e4baf5..eea93b1d87 100644 --- a/src/3rdparty/angle/src/libEGL/Display.cpp +++ b/src/3rdparty/angle/src/libEGL/Display.cpp @@ -35,32 +35,36 @@ static DisplayMap *GetDisplayMap() return &displays; } -egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, EGLint displayType) +egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap) { + Display *display = NULL; + DisplayMap *displays = GetDisplayMap(); DisplayMap::const_iterator iter = displays->find(displayId); if (iter != displays->end()) { - return iter->second; + display = iter->second; + } + else + { + display = new egl::Display(displayId); + displays->insert(std::make_pair(displayId, display)); } - - // FIXME: Check if displayId is a valid display device context - egl::Display *display = new egl::Display(displayId, displayType); - displays->insert(std::make_pair(displayId, display)); + // Apply new attributes if the display is not initialized yet. + if (!display->isInitialized()) + { + display->setAttributes(attribMap); + } return display; } -Display::Display(EGLNativeDisplayType displayId, EGLint displayType) +Display::Display(EGLNativeDisplayType displayId) : mDisplayId(displayId), - mRequestedDisplayType(displayType), + mAttributeMap(), mRenderer(NULL) { -#if defined(ANGLE_PLATFORM_WINRT) - if (mDisplayId) - mDisplayId->AddRef(); -#endif } Display::~Display() @@ -73,28 +77,29 @@ Display::~Display() { displays->erase(iter); } - -#if defined(ANGLE_PLATFORM_WINRT) - if (mDisplayId) - mDisplayId->Release(); -#endif } -bool Display::initialize() +void Display::setAttributes(const AttributeMap &attribMap) +{ + mAttributeMap = attribMap; +} + +Error Display::initialize() { if (isInitialized()) { - return true; + return Error(EGL_SUCCESS); } - mRenderer = glCreateRenderer(this, mDisplayId, mRequestedDisplayType); + mRenderer = glCreateRenderer(this, mDisplayId, mAttributeMap); if (!mRenderer) { terminate(); - return error(EGL_NOT_INITIALIZED, false); + return Error(EGL_NOT_INITIALIZED); } + //TODO(jmadill): should be part of caps? EGLint minSwapInterval = mRenderer->getMinSwapInterval(); EGLint maxSwapInterval = mRenderer->getMaxSwapInterval(); EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize; @@ -125,13 +130,13 @@ bool Display::initialize() if (!isInitialized()) { terminate(); - return false; + return Error(EGL_NOT_INITIALIZED); } initDisplayExtensionString(); initVendorString(); - return true; + return Error(EGL_SUCCESS); } void Display::terminate() @@ -148,6 +153,8 @@ void Display::terminate() glDestroyRenderer(mRenderer); mRenderer = NULL; + + mConfigSet.mSet.clear(); } bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig) @@ -202,7 +209,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) -EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList) +Error Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface) { const Config *configuration = mConfigSet.get(config); EGLint postSubBufferSupported = EGL_FALSE; @@ -223,9 +230,9 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co case EGL_BACK_BUFFER: break; case EGL_SINGLE_BUFFER: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported + return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); } break; case EGL_POST_SUB_BUFFER_SUPPORTED_NV: @@ -241,11 +248,11 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co fixedSize = attribList[1]; break; case EGL_VG_COLORSPACE: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + return Error(EGL_BAD_MATCH); case EGL_VG_ALPHA_FORMAT: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + return Error(EGL_BAD_MATCH); default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); } attribList += 2; @@ -254,7 +261,7 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co if (width < 0 || height < 0) { - return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + return Error(EGL_BAD_PARAMETER); } if (!fixedSize) @@ -265,29 +272,33 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co if (hasExistingWindowSurface(window)) { - return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); + return Error(EGL_BAD_ALLOC); } if (mRenderer->testDeviceLost(false)) { - if (!restoreLostDevice()) - return EGL_NO_SURFACE; + Error error = restoreLostDevice(); + if (error.isError()) + { + return error; + } } Surface *surface = new Surface(this, configuration, window, fixedSize, width, height, postSubBufferSupported); - - if (!surface->initialize()) + Error error = surface->initialize(); + if (error.isError()) { - delete surface; - return EGL_NO_SURFACE; + SafeDelete(surface); + return error; } mSurfaceSet.insert(surface); - return success(surface); + *outSurface = surface; + return Error(EGL_SUCCESS); } -EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList) +Error Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface) { EGLint width = 0, height = 0; EGLenum textureFormat = EGL_NO_TEXTURE; @@ -319,7 +330,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, textureFormat = attribList[1]; break; default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); } break; case EGL_TEXTURE_TARGET: @@ -330,19 +341,19 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, textureTarget = attribList[1]; break; default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); } break; case EGL_MIPMAP_TEXTURE: if (attribList[1] != EGL_FALSE) - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); break; case EGL_VG_COLORSPACE: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + return Error(EGL_BAD_MATCH); case EGL_VG_ALPHA_FORMAT: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + return Error(EGL_BAD_MATCH); default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); } attribList += 2; @@ -351,88 +362,100 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, if (width < 0 || height < 0) { - return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + return Error(EGL_BAD_PARAMETER); } if (width == 0 || height == 0) { - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); } if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height))) { - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + return Error(EGL_BAD_MATCH); } if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) { - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + return Error(EGL_BAD_MATCH); } if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT)) { - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + return Error(EGL_BAD_MATCH); } if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) || (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE)) { - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + return Error(EGL_BAD_ATTRIBUTE); } if (mRenderer->testDeviceLost(false)) { - if (!restoreLostDevice()) - return EGL_NO_SURFACE; + Error error = restoreLostDevice(); + if (error.isError()) + { + return error; + } } Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget); - - if (!surface->initialize()) + Error error = surface->initialize(); + if (error.isError()) { - delete surface; - return EGL_NO_SURFACE; + SafeDelete(surface); + return error; } mSurfaceSet.insert(surface); - return success(surface); + *outSurface = surface; + return Error(EGL_SUCCESS); } -EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess) +Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, + bool robustAccess, EGLContext *outContext) { if (!mRenderer) { - return EGL_NO_CONTEXT; + *outContext = EGL_NO_CONTEXT; + return Error(EGL_SUCCESS); } else if (mRenderer->testDeviceLost(false)) // Lost device { - if (!restoreLostDevice()) + Error error = restoreLostDevice(); + if (error.isError()) { - return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT); + return error; } } + //TODO(jmadill): shader model is not cross-platform if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4) { - return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); + return Error(EGL_BAD_CONFIG); } gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess); mContextSet.insert(context); - return success(context); + *outContext = context; + return Error(EGL_SUCCESS); } -bool Display::restoreLostDevice() +Error Display::restoreLostDevice() { for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++) { if ((*ctx)->isResetNotificationEnabled()) - return false; // If reset notifications have been requested, application must delete all contexts first + { + // If reset notifications have been requested, application must delete all contexts first + return Error(EGL_CONTEXT_LOST); + } } - + // Release surface resources to make the Reset() succeed for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) { @@ -441,16 +464,20 @@ bool Display::restoreLostDevice() if (!mRenderer->resetDevice()) { - return error(EGL_BAD_ALLOC, false); + return Error(EGL_BAD_ALLOC); } // Restore any surfaces that may have been lost for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) { - (*surface)->resetSwapChain(); + Error error = (*surface)->resetSwapChain(); + if (error.isError()) + { + return error; + } } - return true; + return Error(EGL_SUCCESS); } @@ -472,7 +499,6 @@ void Display::notifyDeviceLost() { (*context)->markContextLost(); } - egl::error(EGL_CONTEXT_LOST); } void Display::recreateSwapChains() @@ -604,10 +630,11 @@ void Display::initVendorString() LUID adapterLuid = {0}; + //TODO(jmadill): LUID is not cross-platform if (mRenderer && mRenderer->getLUID(&adapterLuid)) { char adapterLuidString[64]; - snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart); + sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart); mVendorString += adapterLuidString; } diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h index 73ba7673ff..b3ffcc84c5 100644 --- a/src/3rdparty/angle/src/libEGL/Display.h +++ b/src/3rdparty/angle/src/libEGL/Display.h @@ -14,7 +14,9 @@ #include #include +#include "libEGL/Error.h" #include "libEGL/Config.h" +#include "libEGL/AttributeMap.h" namespace gl { @@ -30,10 +32,10 @@ class Display public: ~Display(); - bool initialize(); + Error initialize(); void terminate(); - static egl::Display *getDisplay(EGLNativeDisplayType displayId, EGLint displayType); + static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap); static const char *getExtensionString(egl::Display *display); @@ -43,9 +45,10 @@ class Display bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig); bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value); - EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList); - EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList); - EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess); + Error createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface); + Error createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface); + Error createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, + bool robustAccess, EGLContext *outContext); void destroySurface(egl::Surface *surface); void destroyContext(gl::Context *context); @@ -64,18 +67,19 @@ class Display const char *getExtensionString() const; const char *getVendorString() const; - EGLNativeDisplayType getDisplayId() const { return mDisplayId; } private: DISALLOW_COPY_AND_ASSIGN(Display); - Display(EGLNativeDisplayType displayId, EGLint displayType); + Display(EGLNativeDisplayType displayId); - bool restoreLostDevice(); + void setAttributes(const AttributeMap &attribMap); + + Error restoreLostDevice(); EGLNativeDisplayType mDisplayId; - EGLint mRequestedDisplayType; + AttributeMap mAttributeMap; typedef std::set SurfaceSet; SurfaceSet mSurfaceSet; diff --git a/src/3rdparty/angle/src/libEGL/Error.cpp b/src/3rdparty/angle/src/libEGL/Error.cpp new file mode 100644 index 0000000000..df5f163d32 --- /dev/null +++ b/src/3rdparty/angle/src/libEGL/Error.cpp @@ -0,0 +1,48 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Error.cpp: Implements the egl::Error class which encapsulates an EGL error +// and optional error message. + +#include "libEGL/Error.h" + +#include "common/angleutils.h" + +#include + +namespace egl +{ + +Error::Error(EGLint errorCode) + : mCode(errorCode), + mMessage() +{ +} + +Error::Error(EGLint errorCode, const char *msg, ...) + : mCode(errorCode), + mMessage() +{ + va_list vararg; + va_start(vararg, msg); + mMessage = FormatString(msg, vararg); + va_end(vararg); +} + +Error::Error(const Error &other) + : mCode(other.mCode), + mMessage(other.mMessage) +{ +} + +Error &Error::operator=(const Error &other) +{ + mCode = other.mCode; + mMessage = other.mMessage; + return *this; +} + +} diff --git a/src/3rdparty/angle/src/libEGL/Error.h b/src/3rdparty/angle/src/libEGL/Error.h new file mode 100644 index 0000000000..71805d2fb7 --- /dev/null +++ b/src/3rdparty/angle/src/libEGL/Error.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Error.h: Defines the egl::Error class which encapsulates an EGL error +// and optional error message. + +#ifndef LIBEGL_ERROR_H_ +#define LIBEGL_ERROR_H_ + +#include + +#include + +namespace egl +{ + +class Error +{ + public: + explicit Error(EGLint errorCode); + Error(EGLint errorCode, const char *msg, ...); + Error(const Error &other); + Error &operator=(const Error &other); + + EGLint getCode() const { return mCode; } + bool isError() const { return (mCode != EGL_SUCCESS); } + + const std::string &getMessage() const { return mMessage; } + + private: + EGLint mCode; + std::string mMessage; +}; + +} + +#endif // LIBEGL_ERROR_H_ diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp index fa7996152a..b664a8530e 100644 --- a/src/3rdparty/angle/src/libEGL/Surface.cpp +++ b/src/3rdparty/angle/src/libEGL/Surface.cpp @@ -22,23 +22,19 @@ #include "libEGL/main.h" #include "libEGL/Display.h" -#if defined(ANGLE_PLATFORM_WINRT) -# include "wrl.h" -# include "windows.graphics.display.h" -# include "windows.ui.core.h" -using namespace ABI::Windows::Graphics::Display; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::UI::Core; -using namespace Microsoft::WRL; -#endif +#include "common/NativeWindow.h" + +//TODO(jmadill): phase this out +#include "libGLESv2/renderer/d3d/RendererD3D.h" namespace egl { -Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported) - : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported) +Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported) + : mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported) { - mRenderer = mDisplay->getRenderer(); + //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues) + mRenderer = static_cast(mDisplay->getRenderer()); mSwapChain = NULL; mShareHandle = NULL; mTexture = NULL; @@ -51,27 +47,19 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win mSwapInterval = -1; mWidth = width; mHeight = height; + mFixedWidth = mWidth; + mFixedHeight = mHeight; setSwapInterval(1); mFixedSize = fixedSize; - mSwapFlags = rx::SWAP_NORMAL; -#if defined(ANGLE_PLATFORM_WINRT) - if (mWindow) - mWindow->AddRef(); - mScaleFactor = 1.0; - mSizeToken.value = 0; - mDpiToken.value = 0; -# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - mOrientationToken.value = 0; -# endif -#endif subclassWindow(); } Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType) - : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) + : mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) { - mRenderer = mDisplay->getRenderer(); + //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues) + mRenderer = static_cast(mDisplay->getRenderer()); mSwapChain = NULL; mWindowSubclassed = false; mTexture = NULL; @@ -85,90 +73,33 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL setSwapInterval(1); // This constructor is for offscreen surfaces, which are always fixed-size. mFixedSize = EGL_TRUE; - mSwapFlags = rx::SWAP_NORMAL; -#if defined(ANGLE_PLATFORM_WINRT) - mScaleFactor = 1.0; - mSizeToken.value = 0; - mDpiToken.value = 0; -# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - mOrientationToken.value = 0; -# endif -#endif + mFixedWidth = mWidth; + mFixedHeight = mHeight; } Surface::~Surface() { -#if defined(ANGLE_PLATFORM_WINRT) - if (mSizeToken.value) { - ComPtr coreWindow; - HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf()); - ASSERT(SUCCEEDED(hr)); - - hr = coreWindow->remove_SizeChanged(mSizeToken); - ASSERT(SUCCEEDED(hr)); - } - if (mDpiToken.value) { - ComPtr displayInformation; - HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); - ASSERT(SUCCEEDED(hr)); - - hr = displayInformation->remove_DpiChanged(mDpiToken); - ASSERT(SUCCEEDED(hr)); - } -# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - if (mOrientationToken.value) { - ComPtr displayInformation; - HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); - ASSERT(SUCCEEDED(hr)); - - hr = displayInformation->remove_OrientationChanged(mOrientationToken); - ASSERT(SUCCEEDED(hr)); - } -# endif -#endif unsubclassWindow(); release(); } -bool Surface::initialize() +Error Surface::initialize() { -#if defined(ANGLE_PLATFORM_WINRT) - if (!mFixedSize) { - HRESULT hr; - ComPtr displayInformation; - hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); - ASSERT(SUCCEEDED(hr)); - onDpiChanged(displayInformation.Get(), 0); - hr = displayInformation->add_DpiChanged(Callback>(this, &Surface::onDpiChanged).Get(), - &mDpiToken); - ASSERT(SUCCEEDED(hr)); - -# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - onOrientationChanged(displayInformation.Get(), 0); - hr = displayInformation->add_OrientationChanged(Callback>(this, &Surface::onOrientationChanged).Get(), - &mOrientationToken); - ASSERT(SUCCEEDED(hr)); -# endif - - ComPtr coreWindow; - hr = mWindow->QueryInterface(coreWindow.GetAddressOf()); - ASSERT(SUCCEEDED(hr)); - - Rect rect; - hr = coreWindow->get_Bounds(&rect); - ASSERT(SUCCEEDED(hr)); - mWidth = rect.Width * mScaleFactor; - mHeight = rect.Height * mScaleFactor; - hr = coreWindow->add_SizeChanged(Callback>(this, &Surface::onSizeChanged).Get(), - &mSizeToken); - ASSERT(SUCCEEDED(hr)); + if (mNativeWindow.getNativeWindow()) + { + if (!mNativeWindow.initialize()) + { + return Error(EGL_BAD_SURFACE); + } } -#endif - if (!resetSwapChain()) - return false; + Error error = resetSwapChain(); + if (error.isError()) + { + return error; + } - return true; + return Error(EGL_SUCCESS); } void Surface::release() @@ -181,85 +112,80 @@ void Surface::release() mTexture->releaseTexImage(); mTexture = NULL; } - -#if defined(ANGLE_PLATFORM_WINRT) - if (mWindow) - mWindow->Release(); -#endif } -bool Surface::resetSwapChain() +Error Surface::resetSwapChain() { ASSERT(!mSwapChain); int width; int height; -#if !defined(ANGLE_PLATFORM_WINRT) if (!mFixedSize) { RECT windowRect; - if (!GetClientRect(getWindowHandle(), &windowRect)) + if (!mNativeWindow.getClientRect(&windowRect)) { ASSERT(false); - ERR("Could not retrieve the window dimensions"); - return error(EGL_BAD_SURFACE, false); + return Error(EGL_BAD_SURFACE, "Could not retrieve the window dimensions"); } width = windowRect.right - windowRect.left; height = windowRect.bottom - windowRect.top; } else -#endif { // non-window surface - size is determined at creation width = mWidth; height = mHeight; } - mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle, + mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mConfig->mRenderTargetFormat, mConfig->mDepthStencilFormat); if (!mSwapChain) { - return error(EGL_BAD_ALLOC, false); + return Error(EGL_BAD_ALLOC); } - if (!resetSwapChain(width, height)) + Error error = resetSwapChain(width, height); + if (error.isError()) { - delete mSwapChain; - mSwapChain = NULL; - return false; + SafeDelete(mSwapChain); + return error; } - return true; + return Error(EGL_SUCCESS); } -bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight) +Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight) { - ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); ASSERT(mSwapChain); - EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight)); +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + backbufferWidth = std::max(1, backbufferWidth); + backbufferHeight = std::max(1, backbufferHeight); +#endif + EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight); if (status == EGL_CONTEXT_LOST) { mDisplay->notifyDeviceLost(); - return false; + return Error(status); } else if (status != EGL_SUCCESS) { - return error(status, false); + return Error(status); } mWidth = backbufferWidth; mHeight = backbufferHeight; - return true; + return Error(EGL_SUCCESS); } -bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) +Error Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) { ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); ASSERT(mSwapChain); @@ -269,69 +195,71 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) if (status == EGL_CONTEXT_LOST) { mRenderer->notifyDeviceLost(); - return false; + return Error(status); } else if (status != EGL_SUCCESS) { - return error(status, false); + return Error(status); } mWidth = backbufferWidth; mHeight = backbufferHeight; mSwapIntervalDirty = false; - return true; + return Error(EGL_SUCCESS); } -bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { - return true; + return Error(EGL_SUCCESS); } - if (x + width > mWidth) + if (x + width > abs(mWidth)) { - width = mWidth - x; + width = abs(mWidth) - x; } - if (y + height > mHeight) + if (y + height > abs(mHeight)) { - height = mHeight - y; + height = abs(mHeight) - y; } if (width == 0 || height == 0) { - return true; + return Error(EGL_SUCCESS); } - EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags); + ASSERT(width > 0); + ASSERT(height > 0); + + EGLint status = mSwapChain->swapRect(x, y, width, height); if (status == EGL_CONTEXT_LOST) { mRenderer->notifyDeviceLost(); - return false; + return Error(status); } else if (status != EGL_SUCCESS) { - return error(status, false); + return Error(status); } checkForOutOfDateSwapChain(); - return true; + return Error(EGL_SUCCESS); } EGLNativeWindowType Surface::getWindowHandle() { - return mWindow; + return mNativeWindow.getNativeWindow(); } - +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) #define kSurfaceProperty _TEXT("Egl::SurfaceOwner") #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") -#if !defined(ANGLE_PLATFORM_WINRT) static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { if (message == WM_SIZE) @@ -349,45 +277,50 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam void Surface::subclassWindow() { -#if !defined(ANGLE_PLATFORM_WINRT) - if (!mWindow) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + HWND window = mNativeWindow.getNativeWindow(); + if (!window) { return; } DWORD processId; - DWORD threadId = GetWindowThreadProcessId(mWindow, &processId); + DWORD threadId = GetWindowThreadProcessId(window, &processId); if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId()) { return; } SetLastError(0); - LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast(SurfaceWindowProc)); + LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast(SurfaceWindowProc)); if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) { mWindowSubclassed = false; return; } - SetProp(mWindow, kSurfaceProperty, reinterpret_cast(this)); - SetProp(mWindow, kParentWndProc, reinterpret_cast(oldWndProc)); + SetProp(window, kSurfaceProperty, reinterpret_cast(this)); + SetProp(window, kParentWndProc, reinterpret_cast(oldWndProc)); mWindowSubclassed = true; -#else - mWindowSubclassed = false; #endif } void Surface::unsubclassWindow() { -#if !defined(ANGLE_PLATFORM_WINRT) if(!mWindowSubclassed) { return; } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + HWND window = mNativeWindow.getNativeWindow(); + if (!window) + { + return; + } + // un-subclass - LONG_PTR parentWndFunc = reinterpret_cast(GetProp(mWindow, kParentWndProc)); + LONG_PTR parentWndFunc = reinterpret_cast(GetProp(window, kParentWndProc)); // Check the windowproc is still SurfaceWindowProc. // If this assert fails, then it is likely the application has subclassed the @@ -396,29 +329,28 @@ void Surface::unsubclassWindow() // EGL context, or to unsubclass before destroying the EGL context. if(parentWndFunc) { - LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc); + LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc); UNUSED_ASSERTION_VARIABLE(prevWndFunc); ASSERT(prevWndFunc == reinterpret_cast(SurfaceWindowProc)); } - RemoveProp(mWindow, kSurfaceProperty); - RemoveProp(mWindow, kParentWndProc); - mWindowSubclassed = false; + RemoveProp(window, kSurfaceProperty); + RemoveProp(window, kParentWndProc); #endif + mWindowSubclassed = false; } bool Surface::checkForOutOfDateSwapChain() { + RECT client; int clientWidth = getWidth(); int clientHeight = getHeight(); bool sizeDirty = false; -#if !defined(ANGLE_PLATFORM_WINRT) - if (!mFixedSize && !IsIconic(getWindowHandle())) + if (!mFixedSize && !mNativeWindow.isIconic()) { - RECT client; // The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized // because that's not a useful size to render to. - if (!GetClientRect(getWindowHandle(), &client)) + if (!mNativeWindow.getClientRect(&client)) { ASSERT(false); return false; @@ -429,7 +361,13 @@ bool Surface::checkForOutOfDateSwapChain() clientHeight = client.bottom - client.top; sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); } -#endif + + if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight)) + { + clientWidth = mFixedWidth; + clientHeight = mFixedHeight; + sizeDirty = true; + } bool wasDirty = (mSwapIntervalDirty || sizeDirty); @@ -455,17 +393,17 @@ bool Surface::checkForOutOfDateSwapChain() return false; } -bool Surface::swap() +Error Surface::swap() { - return swapRect(0, 0, mWidth, mHeight); + return swapRect(0, 0, abs(mWidth), abs(mHeight)); } -bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mPostSubBufferSupported) { // Spec is not clear about how this should be handled. - return true; + return Error(EGL_SUCCESS); } return swapRect(x, y, width, height); @@ -550,77 +488,18 @@ EGLint Surface::isFixedSize() const return mFixedSize; } +void Surface::setFixedWidth(EGLint width) +{ + mFixedWidth = width; +} + +void Surface::setFixedHeight(EGLint height) +{ + mFixedHeight = height; +} + EGLenum Surface::getFormat() const { return mConfig->mRenderTargetFormat; } - -#if defined(ANGLE_PLATFORM_WINRT) - -HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args) -{ - HRESULT hr; - Size size; - hr = args->get_Size(&size); - ASSERT(SUCCEEDED(hr)); - - resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5), - std::floor(size.Height * mScaleFactor + 0.5)); - - if (static_cast(getCurrentDrawSurface()) == this) - { - glMakeCurrent(glGetCurrentContext(), static_cast(getCurrentDisplay()), this); - } - - return S_OK; -} - -HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *) -{ - HRESULT hr; -# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - ComPtr displayInformation2; - hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf()); - ASSERT(SUCCEEDED(hr)); - - hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor); - ASSERT(SUCCEEDED(hr)); -# else - ResolutionScale resolutionScale; - hr = displayInformation->get_ResolutionScale(&resolutionScale); - ASSERT(SUCCEEDED(hr)); - - mScaleFactor = double(resolutionScale) / 100.0; -# endif - return S_OK; -} - -# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *) -{ - HRESULT hr; - DisplayOrientations orientation; - hr = displayInformation->get_CurrentOrientation(&orientation); - ASSERT(SUCCEEDED(hr)); - switch (orientation) { - default: - case DisplayOrientations_Portrait: - mSwapFlags = rx::SWAP_NORMAL; - break; - case DisplayOrientations_Landscape: - mSwapFlags = rx::SWAP_ROTATE_90; - break; - case DisplayOrientations_LandscapeFlipped: - mSwapFlags = rx::SWAP_ROTATE_270; - break; - case DisplayOrientations_PortraitFlipped: - mSwapFlags = rx::SWAP_ROTATE_180; - break; - } - return S_OK; -} -# endif - -#endif - } diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h index ebffce8fed..46382d06e1 100644 --- a/src/3rdparty/angle/src/libEGL/Surface.h +++ b/src/3rdparty/angle/src/libEGL/Surface.h @@ -11,23 +11,12 @@ #ifndef LIBEGL_SURFACE_H_ #define LIBEGL_SURFACE_H_ +#include "libEGL/Error.h" + #include #include "common/angleutils.h" - -#if defined(ANGLE_PLATFORM_WINRT) -#include -namespace ABI { namespace Windows { - namespace UI { namespace Core { - struct ICoreWindow; - struct IWindowSizeChangedEventArgs; - } } - namespace Graphics { namespace Display { - struct IDisplayInformation; - } } -} } -struct IInspectable; -#endif +#include "common/NativeWindow.h" namespace gl { @@ -35,8 +24,8 @@ class Texture2D; } namespace rx { -class Renderer; class SwapChain; +class RendererD3D; //TODO(jmadill): remove this } namespace egl @@ -52,13 +41,13 @@ class Surface virtual ~Surface(); - bool initialize(); + Error initialize(); void release(); - bool resetSwapChain(); + Error resetSwapChain(); EGLNativeWindowType getWindowHandle(); - bool swap(); - bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height); + Error swap(); + Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height); virtual EGLint isPostSubBufferSupported() const; @@ -81,35 +70,31 @@ class Surface virtual gl::Texture2D *getBoundTexture() const; EGLint isFixedSize() const; + void setFixedWidth(EGLint width); + void setFixedHeight(EGLint height); -private: + private: DISALLOW_COPY_AND_ASSIGN(Surface); -#if defined(ANGLE_PLATFORM_WINRT) - HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); - HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); -# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); -# endif -#endif - Display *const mDisplay; - rx::Renderer *mRenderer; + rx::RendererD3D *mRenderer; HANDLE mShareHandle; rx::SwapChain *mSwapChain; void subclassWindow(); void unsubclassWindow(); - bool resizeSwapChain(int backbufferWidth, int backbufferHeight); - bool resetSwapChain(int backbufferWidth, int backbufferHeight); - bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height); + Error resizeSwapChain(int backbufferWidth, int backbufferHeight); + Error resetSwapChain(int backbufferWidth, int backbufferHeight); + Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - const EGLNativeWindowType mWindow; // Window that the surface is created for. + rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking const egl::Config *mConfig; // EGL config surface was created with EGLint mHeight; // Height of surface EGLint mWidth; // Width of surface + EGLint mFixedHeight; // Pending height of the surface + EGLint mFixedWidth; // Pending width of the surface // EGLint horizontalResolution; // Horizontal dot pitch // EGLint verticalResolution; // Vertical dot pitch // EGLBoolean largestPBuffer; // If true, create largest pbuffer possible @@ -126,18 +111,9 @@ private: EGLint mSwapInterval; EGLint mPostSubBufferSupported; EGLint mFixedSize; - EGLint mSwapFlags; bool mSwapIntervalDirty; gl::Texture2D *mTexture; -#if defined(ANGLE_PLATFORM_WINRT) - double mScaleFactor; - EventRegistrationToken mSizeToken; - EventRegistrationToken mDpiToken; -# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - EventRegistrationToken mOrientationToken; -# endif -#endif }; } diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp index c2e0fd6d3d..68399d63a4 100644 --- a/src/3rdparty/angle/src/libEGL/libEGL.cpp +++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp @@ -13,7 +13,6 @@ #include "common/debug.h" #include "common/version.h" -#include "common/platform.h" #include "libGLESv2/Context.h" #include "libGLESv2/Texture.h" #include "libGLESv2/main.h" @@ -26,16 +25,20 @@ #include "libEGL/Display.h" #include "libEGL/Surface.h" +#include "common/NativeWindow.h" + bool validateDisplay(egl::Display *display) { if (display == EGL_NO_DISPLAY) { - return egl::error(EGL_BAD_DISPLAY, false); + recordError(egl::Error(EGL_BAD_DISPLAY)); + return false; } if (!display->isInitialized()) { - return egl::error(EGL_NOT_INITIALIZED, false); + recordError(egl::Error(EGL_NOT_INITIALIZED)); + return false; } return true; @@ -50,7 +53,8 @@ bool validateConfig(egl::Display *display, EGLConfig config) if (!display->isValidConfig(config)) { - return egl::error(EGL_BAD_CONFIG, false); + recordError(egl::Error(EGL_BAD_CONFIG)); + return false; } return true; @@ -65,7 +69,8 @@ bool validateContext(egl::Display *display, gl::Context *context) if (!display->isValidContext(context)) { - return egl::error(EGL_BAD_CONTEXT, false); + recordError(egl::Error(EGL_BAD_CONTEXT)); + return false; } return true; @@ -80,7 +85,8 @@ bool validateSurface(egl::Display *display, egl::Surface *surface) if (!display->isValidSurface(surface)) { - return egl::error(EGL_BAD_SURFACE, false); + recordError(egl::Error(EGL_BAD_SURFACE)); + return false; } return true; @@ -93,12 +99,7 @@ EGLint __stdcall eglGetError(void) EVENT("()"); EGLint error = egl::getCurrentError(); - - if (error != EGL_SUCCESS) - { - egl::setCurrentError(EGL_SUCCESS); - } - + recordError(egl::Error(EGL_SUCCESS)); return error; } @@ -106,7 +107,7 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id) { EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); - return egl::Display::getDisplay(display_id, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + return egl::Display::getDisplay(display_id, egl::AttributeMap()); } EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list) @@ -120,19 +121,26 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis break; default: - return egl::error(EGL_BAD_CONFIG, EGL_NO_DISPLAY); + recordError(egl::Error(EGL_BAD_CONFIG)); + return EGL_NO_DISPLAY; } EGLNativeDisplayType displayId = static_cast(native_display); -#if !defined(ANGLE_PLATFORM_WINRT) + +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) // Validate the display device context if (WindowFromDC(displayId) == NULL) { - return egl::success(EGL_NO_DISPLAY); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_NO_DISPLAY; } #endif - EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; + EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; + bool majorVersionSpecified = false; + bool minorVersionSpecified = false; + bool requestedWARP = false; + if (attrib_list) { for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) @@ -140,7 +148,69 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis switch (curAttrib[0]) { case EGL_PLATFORM_ANGLE_TYPE_ANGLE: - requestedDisplayType = curAttrib[1]; + switch (curAttrib[1]) + { + case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: + break; + + case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: + if (!egl::Display::supportsPlatformD3D()) + { + recordError(egl::Error(EGL_SUCCESS)); + return EGL_NO_DISPLAY; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: + if (!egl::Display::supportsPlatformOpenGL()) + { + recordError(egl::Error(EGL_SUCCESS)); + return EGL_NO_DISPLAY; + } + break; + + default: + recordError(egl::Error(EGL_SUCCESS)); + return EGL_NO_DISPLAY; + } + platformType = curAttrib[1]; + break; + + case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: + if (curAttrib[1] != EGL_DONT_CARE) + { + majorVersionSpecified = true; + } + break; + + case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: + if (curAttrib[1] != EGL_DONT_CARE) + { + minorVersionSpecified = true; + } + break; + + case EGL_PLATFORM_ANGLE_USE_WARP_ANGLE: + if (!egl::Display::supportsPlatformD3D()) + { + recordError(egl::Error(EGL_SUCCESS)); + return EGL_NO_DISPLAY; + } + + switch (curAttrib[1]) + { + case EGL_FALSE: + case EGL_TRUE: + break; + + default: + recordError(egl::Error(EGL_SUCCESS)); + return EGL_NO_DISPLAY; + } + + requestedWARP = (curAttrib[1] == EGL_TRUE); break; default: @@ -149,33 +219,20 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis } } - switch (requestedDisplayType) + if (!majorVersionSpecified && minorVersionSpecified) { - case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: - break; - - case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: - case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: - case EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE: - if (!egl::Display::supportsPlatformD3D()) - { - return egl::success(EGL_NO_DISPLAY); - } - break; - - case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: - case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: - if (!egl::Display::supportsPlatformOpenGL()) - { - return egl::success(EGL_NO_DISPLAY); - } - break; - - default: - return egl::success(EGL_NO_DISPLAY); + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_DISPLAY; } - return egl::Display::getDisplay(displayId, requestedDisplayType); + if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE && requestedWARP) + { + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_DISPLAY; + } + + recordError(egl::Error(EGL_SUCCESS)); + return egl::Display::getDisplay(displayId, egl::AttributeMap(attrib_list)); } EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) @@ -185,20 +242,24 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) if (dpy == EGL_NO_DISPLAY) { - return egl::error(EGL_BAD_DISPLAY, EGL_FALSE); + recordError(egl::Error(EGL_BAD_DISPLAY)); + return EGL_FALSE; } egl::Display *display = static_cast(dpy); - if (!display->initialize()) + egl::Error error = display->initialize(); + if (error.isError()) { - return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE); + recordError(error); + return EGL_FALSE; } if (major) *major = 1; if (minor) *minor = 4; - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) @@ -207,14 +268,16 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) if (dpy == EGL_NO_DISPLAY) { - return egl::error(EGL_BAD_DISPLAY, EGL_FALSE); + recordError(egl::Error(EGL_BAD_DISPLAY)); + return EGL_FALSE; } egl::Display *display = static_cast(dpy); display->terminate(); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) @@ -227,19 +290,28 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) return NULL; } + const char *result; switch (name) { case EGL_CLIENT_APIS: - return egl::success("OpenGL_ES"); + result = "OpenGL_ES"; + break; case EGL_EXTENSIONS: - return egl::success(egl::Display::getExtensionString(display)); + result = egl::Display::getExtensionString(display); + break; case EGL_VENDOR: - return egl::success(display->getVendorString()); + result = display->getVendorString(); + break; case EGL_VERSION: - return egl::success("1.4 (ANGLE " ANGLE_VERSION_STRING ")"); + result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")"; + break; default: - return egl::error(EGL_BAD_PARAMETER, (const char*)NULL); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return NULL; } + + recordError(egl::Error(EGL_SUCCESS)); + return result; } EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) @@ -257,17 +329,20 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co if (!num_config) { - return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; } const EGLint attribList[] = {EGL_NONE}; if (!display->getConfigs(configs, attribList, config_size, num_config)) { - return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_FALSE; } - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) @@ -285,7 +360,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, if (!num_config) { - return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; } const EGLint attribList[] = {EGL_NONE}; @@ -297,7 +373,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, display->getConfigs(configs, attrib_list, config_size, num_config); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) @@ -314,10 +391,12 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint if (!display->getConfigAttrib(config, attribute, value)) { - return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_FALSE; } - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) @@ -332,16 +411,21 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG return EGL_NO_SURFACE; } -#if !defined(ANGLE_PLATFORM_WINRT) - HWND window = (HWND)win; - - if (!IsWindow(window)) + if (!rx::IsValidEGLNativeWindowType(win)) { - return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); + recordError(egl::Error(EGL_BAD_NATIVE_WINDOW)); + return EGL_NO_SURFACE; } -#endif - return display->createWindowSurface(win, config, attrib_list); + EGLSurface surface = EGL_NO_SURFACE; + egl::Error error = display->createWindowSurface(win, config, attrib_list, &surface); + if (error.isError()) + { + recordError(error); + return EGL_NO_SURFACE; + } + + return surface; } EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) @@ -356,7 +440,15 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c return EGL_NO_SURFACE; } - return display->createOffscreenSurface(config, NULL, attrib_list); + EGLSurface surface = EGL_NO_SURFACE; + egl::Error error = display->createOffscreenSurface(config, NULL, attrib_list, &surface); + if (error.isError()) + { + recordError(error); + return EGL_NO_SURFACE; + } + + return surface; } EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) @@ -373,7 +465,8 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG UNIMPLEMENTED(); // FIXME - return egl::success(EGL_NO_SURFACE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_NO_SURFACE; } EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) @@ -390,12 +483,14 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) if (surface == EGL_NO_SURFACE) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } display->destroySurface((egl::Surface*)surface); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) @@ -413,7 +508,8 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint if (surface == EGL_NO_SURFACE) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } switch (attribute) @@ -473,10 +569,12 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint *value = eglSurface->isFixedSize(); break; default: - return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_FALSE; } - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value) @@ -498,7 +596,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf if (surface == EGL_NO_SURFACE) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } rx::SwapChain *swapchain = eglSurface->getSwapChain(); @@ -522,7 +621,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf if (renderer->getMajorShaderModel() < 4) { - return egl::error(EGL_BAD_CONTEXT, EGL_FALSE); + recordError(egl::Error(EGL_BAD_CONTEXT)); + return EGL_FALSE; } *value = static_cast(renderer)->getDevice(); @@ -530,10 +630,12 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf break; #endif default: - return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_FALSE; } - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglBindAPI(EGLenum api) @@ -544,16 +646,19 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api) { case EGL_OPENGL_API: case EGL_OPENVG_API: - return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; // Not supported by this implementation case EGL_OPENGL_ES_API: break; default: - return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; } egl::setCurrentAPI(api); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLenum __stdcall eglQueryAPI(void) @@ -562,7 +667,8 @@ EGLenum __stdcall eglQueryAPI(void) EGLenum API = egl::getCurrentAPI(); - return egl::success(API); + recordError(egl::Error(EGL_SUCCESS)); + return API; } EGLBoolean __stdcall eglWaitClient(void) @@ -571,7 +677,8 @@ EGLBoolean __stdcall eglWaitClient(void) UNIMPLEMENTED(); // FIXME - return egl::success(0); + recordError(egl::Error(EGL_SUCCESS)); + return 0; } EGLBoolean __stdcall eglReleaseThread(void) @@ -580,7 +687,8 @@ EGLBoolean __stdcall eglReleaseThread(void) eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) @@ -598,10 +706,19 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer) { - return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_NO_SURFACE; } - return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list); + EGLSurface surface = EGL_NO_SURFACE; + egl::Error error = display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list, &surface); + if (error.isError()) + { + recordError(error); + return EGL_NO_SURFACE; + } + + return surface; } EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) @@ -617,9 +734,30 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint return EGL_FALSE; } + switch (attribute) + { + case EGL_WIDTH: + if (!eglSurface->isFixedSize() || !value) { + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; + } + eglSurface->setFixedWidth(value); + return EGL_TRUE; + case EGL_HEIGHT: + if (!eglSurface->isFixedSize() || !value) { + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; + } + eglSurface->setFixedHeight(value); + return EGL_TRUE; + default: + break; + } + UNIMPLEMENTED(); // FIXME - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) @@ -636,30 +774,36 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint if (buffer != EGL_BACK_BUFFER) { - return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } if (eglSurface->getBoundTexture()) { - return egl::error(EGL_BAD_ACCESS, EGL_FALSE); + recordError(egl::Error(EGL_BAD_ACCESS)); + return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { - return egl::error(EGL_BAD_MATCH, EGL_FALSE); + recordError(egl::Error(EGL_BAD_MATCH)); + return EGL_FALSE; } if (!glBindTexImage(eglSurface)) { - return egl::error(EGL_BAD_MATCH, EGL_FALSE); + recordError(egl::Error(EGL_BAD_MATCH)); + return EGL_FALSE; } - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) @@ -676,17 +820,20 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi if (buffer != EGL_BACK_BUFFER) { - return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { - return egl::error(EGL_BAD_MATCH, EGL_FALSE); + recordError(egl::Error(EGL_BAD_MATCH)); + return EGL_FALSE; } gl::Texture2D *texture = eglSurface->getBoundTexture(); @@ -696,7 +843,8 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi texture->releaseTexImage(); } - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) @@ -714,12 +862,14 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) if (draw_surface == NULL) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } draw_surface->setSwapInterval(interval); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) @@ -744,27 +894,38 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: if (attribute[1] == EGL_TRUE) { - return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented + recordError(egl::Error(EGL_BAD_CONFIG)); // Unimplemented + return EGL_NO_CONTEXT; // robust_access = true; } else if (attribute[1] != EGL_FALSE) - return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + { + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_CONTEXT; + } break; case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT) + { reset_notification = true; + } else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT) - return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + { + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_CONTEXT; + } break; default: - return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_CONTEXT; } } } if (client_version != 2 && client_version != 3) { - return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); + recordError(egl::Error(EGL_BAD_CONFIG)); + return EGL_NO_CONTEXT; } egl::Display *display = static_cast(dpy); @@ -775,18 +936,21 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte if (sharedGLContext->isResetNotificationEnabled() != reset_notification) { - return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT); + recordError(egl::Error(EGL_BAD_MATCH)); + return EGL_NO_CONTEXT; } if (sharedGLContext->getClientVersion() != client_version) { - return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT); + recordError(egl::Error(EGL_BAD_CONTEXT)); + return EGL_NO_CONTEXT; } // Can not share contexts between displays if (sharedGLContext->getRenderer() != display->getRenderer()) { - return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT); + recordError(egl::Error(EGL_BAD_MATCH)); + return EGL_NO_CONTEXT; } } @@ -795,7 +959,16 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte return EGL_NO_CONTEXT; } - return display->createContext(config, client_version, static_cast(share_context), reset_notification, robust_access); + EGLContext context = EGL_NO_CONTEXT; + egl::Error error = display->createContext(config, client_version, static_cast(share_context), + reset_notification, robust_access, &context); + if (error.isError()) + { + recordError(error); + return EGL_NO_CONTEXT; + } + + return context; } EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) @@ -812,12 +985,14 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) if (ctx == EGL_NO_CONTEXT) { - return egl::error(EGL_BAD_CONTEXT, EGL_FALSE); + recordError(egl::Error(EGL_BAD_CONTEXT)); + return EGL_FALSE; } display->destroyContext(context); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) @@ -832,7 +1007,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE); if (noContext != noSurface) { - return egl::error(EGL_BAD_MATCH, EGL_FALSE); + recordError(egl::Error(EGL_BAD_MATCH)); + return EGL_FALSE; } if (ctx != EGL_NO_CONTEXT && !validateContext(display, context)) @@ -850,7 +1026,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface if (renderer->isDeviceLost()) { - return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); + recordError(egl::Error(EGL_CONTEXT_LOST)); + return EGL_FALSE; } } @@ -871,7 +1048,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface glMakeCurrent(context, display, static_cast(draw)); - return egl::success(EGL_TRUE); + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLContext __stdcall eglGetCurrentContext(void) @@ -880,7 +1058,8 @@ EGLContext __stdcall eglGetCurrentContext(void) EGLContext context = glGetCurrentContext(); - return egl::success(context); + recordError(egl::Error(EGL_SUCCESS)); + return context; } EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) @@ -889,17 +1068,18 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) if (readdraw == EGL_READ) { - EGLSurface read = egl::getCurrentReadSurface(); - return egl::success(read); + recordError(egl::Error(EGL_SUCCESS)); + return egl::getCurrentReadSurface(); } else if (readdraw == EGL_DRAW) { - EGLSurface draw = egl::getCurrentDrawSurface(); - return egl::success(draw); + recordError(egl::Error(EGL_SUCCESS)); + return egl::getCurrentDrawSurface(); } else { - return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_NO_SURFACE; } } @@ -909,7 +1089,8 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void) EGLDisplay dpy = egl::getCurrentDisplay(); - return egl::success(dpy); + recordError(egl::Error(EGL_SUCCESS)); + return dpy; } EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) @@ -927,7 +1108,8 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr UNIMPLEMENTED(); // FIXME - return egl::success(0); + recordError(egl::Error(EGL_SUCCESS)); + return 0; } EGLBoolean __stdcall eglWaitGL(void) @@ -936,7 +1118,8 @@ EGLBoolean __stdcall eglWaitGL(void) UNIMPLEMENTED(); // FIXME - return egl::success(0); + recordError(egl::Error(EGL_SUCCESS)); + return 0; } EGLBoolean __stdcall eglWaitNative(EGLint engine) @@ -945,7 +1128,8 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine) UNIMPLEMENTED(); // FIXME - return egl::success(0); + recordError(egl::Error(EGL_SUCCESS)); + return 0; } EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) @@ -962,20 +1146,25 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) if (display->getRenderer()->isDeviceLost()) { - return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); + recordError(egl::Error(EGL_CONTEXT_LOST)); + return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } - if (eglSurface->swap()) + egl::Error error = eglSurface->swap(); + if (error.isError()) { - return egl::success(EGL_TRUE); + recordError(error); + return EGL_FALSE; } - return EGL_FALSE; + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) @@ -992,12 +1181,14 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ if (display->getRenderer()->isDeviceLost()) { - return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); + recordError(egl::Error(EGL_CONTEXT_LOST)); + return EGL_FALSE; } UNIMPLEMENTED(); // FIXME - return egl::success(0); + recordError(egl::Error(EGL_SUCCESS)); + return 0; } EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) @@ -1006,7 +1197,8 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi if (x < 0 || y < 0 || width < 0 || height < 0) { - return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); + recordError(egl::Error(EGL_BAD_PARAMETER)); + return EGL_FALSE; } egl::Display *display = static_cast(dpy); @@ -1019,20 +1211,25 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi if (display->getRenderer()->isDeviceLost()) { - return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); + recordError(egl::Error(EGL_CONTEXT_LOST)); + return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - return egl::error(EGL_BAD_SURFACE, EGL_FALSE); + recordError(egl::Error(EGL_BAD_SURFACE)); + return EGL_FALSE; } - if (eglSurface->postSubBuffer(x, y, width, height)) + egl::Error error = eglSurface->postSubBuffer(x, y, width, height); + if (error.isError()) { - return egl::success(EGL_TRUE); + recordError(error); + return EGL_FALSE; } - return EGL_FALSE; + recordError(egl::Error(EGL_SUCCESS)); + return EGL_TRUE; } __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname) diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp index e74737eaba..e88cad775f 100644 --- a/src/3rdparty/angle/src/libEGL/main.cpp +++ b/src/3rdparty/angle/src/libEGL/main.cpp @@ -11,9 +11,6 @@ #include "common/debug.h" #include "common/tls.h" -#if defined(ANGLE_PLATFORM_WINRT) -__declspec(thread) -#endif static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; namespace egl @@ -21,12 +18,6 @@ namespace egl Current *AllocateCurrent() { -#if defined(ANGLE_PLATFORM_WINRT) - if (currentTLS == TLS_OUT_OF_INDEXES) - { - currentTLS = CreateTLSIndex(); - } -#endif ASSERT(currentTLS != TLS_OUT_OF_INDEXES); if (currentTLS == TLS_OUT_OF_INDEXES) { @@ -51,12 +42,6 @@ Current *AllocateCurrent() void DeallocateCurrent() { -#if defined(ANGLE_PLATFORM_WINRT) - if (currentTLS == TLS_OUT_OF_INDEXES) - { - return; - } -#endif Current *current = reinterpret_cast(GetTLSValue(currentTLS)); SafeDelete(current); SetTLSValue(currentTLS, NULL); @@ -72,7 +57,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved { case DLL_PROCESS_ATTACH: { -#if defined(ANGLE_ENABLE_TRACE) +#if defined(ANGLE_ENABLE_DEBUG_TRACE) FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt"); if (debug) @@ -87,15 +72,15 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved } #endif -#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain - return DisableThreadLibraryCalls(instance); -#endif - currentTLS = CreateTLSIndex(); if (currentTLS == TLS_OUT_OF_INDEXES) { return FALSE; } + +#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS + gl::InitializeDebugAnnotations(); +#endif } // Fall through to initialize index case DLL_THREAD_ATTACH: @@ -105,15 +90,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved break; case DLL_THREAD_DETACH: { -#if !defined(ANGLE_PLATFORM_WINRT) egl::DeallocateCurrent(); -#endif } break; case DLL_PROCESS_DETACH: { egl::DeallocateCurrent(); DestroyTLSIndex(currentTLS); + +#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS + gl::UninitializeDebugAnnotations(); +#endif } break; default: @@ -143,11 +130,11 @@ Current *GetCurrentData() #endif } -void setCurrentError(EGLint error) +void recordError(const Error &error) { Current *current = GetCurrentData(); - current->error = error; + current->error = error.getCode(); } EGLint getCurrentError() @@ -213,9 +200,4 @@ EGLSurface getCurrentReadSurface() return current->readSurface; } -void error(EGLint errorCode) -{ - egl::setCurrentError(errorCode); -} - } diff --git a/src/3rdparty/angle/src/libEGL/main.h b/src/3rdparty/angle/src/libEGL/main.h index 07f5b9e675..e5361a4a5e 100644 --- a/src/3rdparty/angle/src/libEGL/main.h +++ b/src/3rdparty/angle/src/libEGL/main.h @@ -9,6 +9,8 @@ #ifndef LIBEGL_MAIN_H_ #define LIBEGL_MAIN_H_ +#include "libEGL/Error.h" + #include #include @@ -23,7 +25,7 @@ struct Current EGLSurface readSurface; }; -void setCurrentError(EGLint error); +void recordError(const Error &error); EGLint getCurrentError(); void setCurrentAPI(EGLenum API); @@ -38,24 +40,6 @@ EGLSurface getCurrentDrawSurface(); void setCurrentReadSurface(EGLSurface surface); EGLSurface getCurrentReadSurface(); -void error(EGLint errorCode); - -template -const T &error(EGLint errorCode, const T &returnValue) -{ - error(errorCode); - - return returnValue; -} - -template -const T &success(const T &returnValue) -{ - egl::setCurrentError(EGL_SUCCESS); - - return returnValue; -} - } #endif // LIBEGL_MAIN_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h index 4d7dde04e1..4f7f5f2c85 100644 --- a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h +++ b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace gl { @@ -26,7 +27,7 @@ class BinaryInputStream { mError = false; mOffset = 0; - mData = static_cast(data); + mData = static_cast(data); mLength = length; } @@ -85,7 +86,7 @@ class BinaryInputStream return; } - v->assign(mData + mOffset, length); + v->assign(reinterpret_cast(mData) + mOffset, length); mOffset += length; } @@ -115,11 +116,16 @@ class BinaryInputStream return mOffset == mLength; } + const uint8_t *data() + { + return mData; + } + private: DISALLOW_COPY_AND_ASSIGN(BinaryInputStream); bool mError; size_t mOffset; - const char *mData; + const uint8_t *mData; size_t mLength; template diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h index 35a6767502..daa862ca0d 100644 --- a/src/3rdparty/angle/src/libGLESv2/Buffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h @@ -19,7 +19,6 @@ namespace rx { -class Renderer; class BufferImpl; }; diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp index 5342de1331..b87689cd3f 100644 --- a/src/3rdparty/angle/src/libGLESv2/Context.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp @@ -9,10 +9,8 @@ #include "libGLESv2/Context.h" -#include "libGLESv2/main.h" #include "common/utilities.h" #include "common/platform.h" -#include "libGLESv2/formatutils.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Fence.h" #include "libGLESv2/Framebuffer.h" @@ -21,14 +19,15 @@ #include "libGLESv2/Program.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Query.h" -#include "libGLESv2/Texture.h" #include "libGLESv2/ResourceManager.h" -#include "libGLESv2/renderer/d3d/IndexDataManager.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/VertexArray.h" #include "libGLESv2/Sampler.h" -#include "libGLESv2/validationES.h" +#include "libGLESv2/Texture.h" #include "libGLESv2/TransformFeedback.h" +#include "libGLESv2/VertexArray.h" +#include "libGLESv2/formatutils.h" +#include "libGLESv2/main.h" +#include "libGLESv2/validationES.h" +#include "libGLESv2/renderer/Renderer.h" #include "libEGL/Surface.h" @@ -38,7 +37,7 @@ namespace gl { -Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) +Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer) { ASSERT(robustAccess == false); // Unimplemented @@ -66,22 +65,24 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere // In order that access to these initial textures not be lost, they are treated as texture // objects all of whose names are 0. - mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0)); - bindTexture(GL_TEXTURE_2D, 0); + Texture2D *zeroTexture2D = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0); + mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D); - mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0)); - bindTexture(GL_TEXTURE_CUBE_MAP, 0); + TextureCubeMap *zeroTextureCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0); + mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube); if (mClientVersion >= 3) { // TODO: These could also be enabled via extension - mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0)); - bindTexture(GL_TEXTURE_3D, 0); + Texture3D *zeroTexture3D = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0); + mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D); - mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0)); - bindTexture(GL_TEXTURE_2D_ARRAY, 0); + Texture2DArray *zeroTexture2DArray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0); + mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray); } + mState.initializeZeroTextures(mZeroTextures); + bindVertexArray(0); bindArrayBuffer(0); bindElementArrayBuffer(0); @@ -91,13 +92,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere bindRenderbuffer(0); bindGenericUniformBuffer(0); - for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) + for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++) { bindIndexedUniformBuffer(0, i, 0, -1); } bindGenericTransformFeedbackBuffer(0); - for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (unsigned int i = 0; i < mCaps.maxTransformFeedbackSeparateAttributes; i++) { bindIndexedTransformFeedbackBuffer(0, i, 0, -1); } @@ -119,8 +120,6 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere mResetStatus = GL_NO_ERROR; mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT); mRobustAccess = robustAccess; - - mState.setContext(this); } Context::~Context() @@ -175,7 +174,10 @@ Context::~Context() } mZeroTextures.clear(); - mResourceManager->release(); + if (mResourceManager) + { + mResourceManager->release(); + } } void Context::makeCurrent(egl::Surface *surface) @@ -194,14 +196,11 @@ void Context::makeCurrent(egl::Surface *surface) // Wrap the existing swapchain resources into GL objects and assign them to the '0' names rx::SwapChain *swapchain = surface->getSwapChain(); - Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain); - DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain); - Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero); + rx::RenderbufferImpl *colorbufferZero = mRenderer->createRenderbuffer(swapchain, false); + rx::RenderbufferImpl *depthStencilbufferZero = mRenderer->createRenderbuffer(swapchain, true); + Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); setFramebufferZero(framebufferZero); - - // Store the current client version in the renderer - mRenderer->setCurrentClientVersion(mClientVersion); } // NOTE: this function should not assume that this context is current! @@ -229,7 +228,7 @@ GLuint Context::createProgram() GLuint Context::createShader(GLenum type) { - return mResourceManager->createShader(type); + return mResourceManager->createShader(getData(), type); } GLuint Context::createTexture() @@ -242,15 +241,10 @@ GLuint Context::createRenderbuffer() return mResourceManager->createRenderbuffer(); } -GLsync Context::createFenceSync(GLenum condition) +GLsync Context::createFenceSync() { GLuint handle = mResourceManager->createFenceSync(); - gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle); - ASSERT(fenceSync); - - fenceSync->set(condition); - return reinterpret_cast(handle); } @@ -294,7 +288,7 @@ GLuint Context::createFenceNV() { GLuint handle = mFenceNVHandleAllocator.allocate(); - mFenceNVMap[handle] = new FenceNV(mRenderer); + mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV()); return handle; } @@ -355,12 +349,12 @@ void Context::deleteFenceSync(GLsync fenceSync) // wait commands finish. However, since the name becomes invalid, we cannot query the fence, // and since our API is currently designed for being called from a single thread, we can delete // the fence immediately. - mResourceManager->deleteFenceSync(uintptr_t(fenceSync)); + mResourceManager->deleteFenceSync(reinterpret_cast(fenceSync)); } void Context::deleteVertexArray(GLuint vertexArray) { - auto vertexArrayObject = mVertexArrayMap.find(vertexArray); + VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray); if (vertexArrayObject != mVertexArrayMap.end()) { @@ -461,12 +455,12 @@ Renderbuffer *Context::getRenderbuffer(GLuint handle) FenceSync *Context::getFenceSync(GLsync handle) const { - return mResourceManager->getFenceSync(uintptr_t(handle)); + return mResourceManager->getFenceSync(reinterpret_cast(handle)); } VertexArray *Context::getVertexArray(GLuint handle) const { - auto vertexArray = mVertexArrayMap.find(handle); + VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle); if (vertexArray == mVertexArrayMap.end()) { @@ -515,18 +509,30 @@ void Context::bindElementArrayBuffer(unsigned int buffer) mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer)); } -void Context::bindTexture(GLenum target, GLuint texture) +void Context::bindTexture(GLenum target, GLuint handle) { - mResourceManager->checkTextureAllocation(texture, target); + Texture *texture = NULL; - mState.setSamplerTexture(target, getTexture(texture)); + if (handle == 0) + { + texture = mZeroTextures[target].get(); + } + else + { + mResourceManager->checkTextureAllocation(handle, target); + texture = getTexture(handle); + } + + ASSERT(texture); + + mState.setSamplerTexture(target, texture); } void Context::bindReadFramebuffer(GLuint framebuffer) { if (!getFramebuffer(framebuffer)) { - mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer); + mFramebufferMap[framebuffer] = new Framebuffer(framebuffer); } mState.setReadFramebufferBinding(getFramebuffer(framebuffer)); @@ -536,7 +542,7 @@ void Context::bindDrawFramebuffer(GLuint framebuffer) { if (!getFramebuffer(framebuffer)) { - mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer); + mFramebufferMap[framebuffer] = new Framebuffer(framebuffer); } mState.setDrawFramebufferBinding(getFramebuffer(framebuffer)); @@ -640,33 +646,44 @@ void Context::useProgram(GLuint program) } } -void Context::linkProgram(GLuint program) +Error Context::linkProgram(GLuint program) { Program *programObject = mResourceManager->getProgram(program); - bool linked = programObject->link(getCaps()); + Error error = programObject->link(getData()); + if (error.isError()) + { + return error; + } // if the current program was relinked successfully we // need to install the new executables - if (linked && program == mState.getCurrentProgramId()) + if (programObject->isLinked() && program == mState.getCurrentProgramId()) { mState.setCurrentProgramBinary(programObject->getProgramBinary()); } + + return Error(GL_NO_ERROR); } -void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length) +Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length) { Program *programObject = mResourceManager->getProgram(program); - bool loaded = programObject->setProgramBinary(binaryFormat, binary, length); + Error error = programObject->setProgramBinary(binaryFormat, binary, length); + if (error.isError()) + { + return error; + } // if the current program was reloaded successfully we // need to install the new executables - if (loaded && program == mState.getCurrentProgramId()) + if (programObject->isLinked() && program == mState.getCurrentProgramId()) { mState.setCurrentProgramBinary(programObject->getProgramBinary()); } + return Error(GL_NO_ERROR); } void Context::bindTransformFeedback(GLuint transformFeedback) @@ -724,33 +741,6 @@ void Context::setFramebufferZero(Framebuffer *buffer) mFramebufferMap[0] = buffer; } -void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) -{ - ASSERT(getTextureCaps().get(internalformat).renderable); - - RenderbufferStorage *renderbuffer = NULL; - - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0) - { - renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples); - } - else if (formatInfo.depthBits > 0) - { - renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples); - } - else if (formatInfo.stencilBits > 0) - { - renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples); - } - else - { - renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples); - } - - mState.getCurrentRenderbuffer()->setStorage(renderbuffer); -} - Framebuffer *Context::getFramebuffer(unsigned int handle) const { FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle); @@ -837,14 +827,7 @@ Texture2DArray *Context::getTexture2DArray() const Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const { - if (mState.getSamplerTextureId(sampler, type) == 0) - { - return mZeroTextures.at(type).get(); - } - else - { - return mState.getSamplerTexture(sampler, type); - } + return mState.getSamplerTexture(sampler, type); } void Context::getBooleanv(GLenum pname, GLboolean *params) @@ -962,7 +945,7 @@ void Context::getIntegerv(GLenum pname, GLint *params) *params = static_cast(mExtensionStrings.size()); break; default: - mState.getIntegerv(pname, params); + mState.getIntegerv(getData(), pname, params); break; } } @@ -1309,309 +1292,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned return false; } -// Applies the render target surface, depth stencil surface, viewport rectangle and -// scissor rectangle to the renderer -Error Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport) -{ - Framebuffer *framebufferObject = mState.getDrawFramebuffer(); - ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE); - - gl::Error error = mRenderer->applyRenderTarget(framebufferObject); - if (error.isError()) - { - return error; - } - - float nearZ, farZ; - mState.getDepthRange(&nearZ, &farZ); - mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace, - ignoreViewport); - - mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled()); - - return gl::Error(GL_NO_ERROR); -} - -// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device -Error Context::applyState(GLenum drawMode) -{ - Framebuffer *framebufferObject = mState.getDrawFramebuffer(); - int samples = framebufferObject->getSamples(); - - RasterizerState rasterizer = mState.getRasterizerState(); - rasterizer.pointDrawMode = (drawMode == GL_POINTS); - rasterizer.multiSample = (samples != 0); - - Error error = mRenderer->setRasterizerState(rasterizer); - if (error.isError()) - { - return error; - } - - unsigned int mask = 0; - if (mState.isSampleCoverageEnabled()) - { - GLclampf coverageValue; - bool coverageInvert = false; - mState.getSampleCoverageParams(&coverageValue, &coverageInvert); - if (coverageValue != 0) - { - float threshold = 0.5f; - - for (int i = 0; i < samples; ++i) - { - mask <<= 1; - - if ((i + 1) * coverageValue >= threshold) - { - threshold += 1.0f; - mask |= 1; - } - } - } - - if (coverageInvert) - { - mask = ~mask; - } - } - else - { - mask = 0xFFFFFFFF; - } - error = mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask); - if (error.isError()) - { - return error; - } - - error = mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(), - rasterizer.frontFace == GL_CCW); - if (error.isError()) - { - return error; - } - - return Error(GL_NO_ERROR); -} - -// Applies the shaders and shader constants to the Direct3D 9 device -Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive) -{ - const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes(); - - VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]; - VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues()); - - const Framebuffer *fbo = mState.getDrawFramebuffer(); - - Error error = mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - return programBinary->applyUniforms(); -} - -Error Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type) -{ - size_t samplerRange = programBinary->getUsedSamplerRange(type); - - for (size_t i = 0; i < samplerRange; i++) - { - GLenum textureType = programBinary->getSamplerTextureType(type, i); - GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps()); - if (textureUnit != -1) - { - Texture* texture = getSamplerTexture(textureUnit, textureType); - if (texture->getSamplerState().swizzleRequired()) - { - Error error = mRenderer->generateSwizzle(texture); - if (error.isError()) - { - return error; - } - } - } - } - - return Error(GL_NO_ERROR); -} - -Error Context::generateSwizzles(ProgramBinary *programBinary) -{ - Error error = generateSwizzles(programBinary, SAMPLER_VERTEX); - if (error.isError()) - { - return error; - } - - error = generateSwizzles(programBinary, SAMPLER_PIXEL); - if (error.isError()) - { - return error; - } - - return Error(GL_NO_ERROR); -} - -// For each Direct3D sampler of either the pixel or vertex stage, -// looks up the corresponding OpenGL texture image unit and texture type, -// and sets the texture and its addressing/filtering state (or NULL when inactive). -Error Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType, - const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount) -{ - size_t samplerRange = programBinary->getUsedSamplerRange(shaderType); - for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) - { - GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex); - GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps()); - if (textureUnit != -1) - { - SamplerState sampler; - Texture* texture = getSamplerTexture(textureUnit, textureType); - texture->getSamplerStateWithNativeOffset(&sampler); - - Sampler *samplerObject = mState.getSampler(textureUnit); - if (samplerObject) - { - samplerObject->getState(&sampler); - } - - // TODO: std::binary_search may become unavailable using older versions of GCC - if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) && - !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial())) - { - Error error = mRenderer->setSamplerState(shaderType, samplerIndex, sampler); - if (error.isError()) - { - return error; - } - - error = mRenderer->setTexture(shaderType, samplerIndex, texture); - if (error.isError()) - { - return error; - } - } - else - { - // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. - Texture *incompleteTexture = getIncompleteTexture(textureType); - gl::Error error = mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture); - if (error.isError()) - { - return error; - } - } - } - else - { - // No texture bound to this slot even though it is used by the shader, bind a NULL texture - Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } - } - } - - // Set all the remaining textures to NULL - size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits - : mCaps.maxVertexTextureImageUnits; - for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) - { - Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } - } - - return Error(GL_NO_ERROR); -} - -Error Context::applyTextures(ProgramBinary *programBinary) -{ - FramebufferTextureSerialArray framebufferSerials; - size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials); - - Error error = applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - error = applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - return Error(GL_NO_ERROR); -} - -Error Context::applyUniformBuffers() -{ - Program *programObject = getProgram(mState.getCurrentProgramId()); - ProgramBinary *programBinary = programObject->getProgramBinary(); - - std::vector boundBuffers; - - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++) - { - GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex); - - if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0) - { - // undefined behaviour - return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer."); - } - else - { - Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding); - ASSERT(uniformBuffer); - boundBuffers.push_back(uniformBuffer); - } - } - - return programBinary->applyUniformBuffers(boundBuffers, getCaps()); -} - -bool Context::applyTransformFeedbackBuffers() -{ - TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback(); - if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) - { - Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) - { - transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i); - transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i); - } - mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets); - return true; - } - else - { - return false; - } -} - -void Context::markTransformFeedbackUsage() -{ - for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) - { - Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i); - if (buffer) - { - buffer->markTransformFeedbackUsage(); - } - } -} - Error Context::clear(GLbitfield mask) { if (mState.isRasterizerDiscardEnabled()) @@ -1619,290 +1299,71 @@ Error Context::clear(GLbitfield mask) return Error(GL_NO_ERROR); } - ClearParameters clearParams = mState.getClearParameters(mask); - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clear(getData(), mask); } -Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values) +Error Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferfv can be called to clear the color buffer or depth buffer - ClearParameters clearParams = mState.getClearParameters(0); - - if (buffer == GL_COLOR) - { - for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) - { - clearParams.clearColor[i] = (drawbuffer == static_cast(i)); - } - clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_FLOAT; - } - - if (buffer == GL_DEPTH) - { - clearParams.clearDepth = true; - clearParams.depthClearValue = values[0]; - } - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferfv(getData(), buffer, drawbuffer, values); } -Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values) +Error Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferuv can only be called to clear a color buffer - ClearParameters clearParams = mState.getClearParameters(0); - for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) - { - clearParams.clearColor[i] = (drawbuffer == static_cast(i)); - } - clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_UNSIGNED_INT; - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferuiv(getData(), buffer, drawbuffer, values); } -Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values) +Error Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferfv can be called to clear the color buffer or stencil buffer - ClearParameters clearParams = mState.getClearParameters(0); - - if (buffer == GL_COLOR) - { - for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) - { - clearParams.clearColor[i] = (drawbuffer == static_cast(i)); - } - clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_INT; - } - - if (buffer == GL_STENCIL) - { - clearParams.clearStencil = true; - clearParams.stencilClearValue = values[1]; - } - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferiv(getData(), buffer, drawbuffer, values); } -Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil) +Error Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { if (mState.isRasterizerDiscardEnabled()) { return Error(GL_NO_ERROR); } - // glClearBufferfi can only be called to clear a depth stencil buffer - ClearParameters clearParams = mState.getClearParameters(0); - clearParams.clearDepth = true; - clearParams.depthClearValue = depth; - clearParams.clearStencil = true; - clearParams.stencilClearValue = stencil; - - applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport - - return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); + return mRenderer->clearBufferfi(getData(), buffer, drawbuffer, depth, stencil); } Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels) { - Framebuffer *framebuffer = mState.getReadFramebuffer(); - - GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); - const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat); - GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment()); - - return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(), - reinterpret_cast(pixels)); + return mRenderer->readPixels(getData(), x, y, width, height, format, type, bufSize, pixels); } Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances) { - ASSERT(mState.getCurrentProgramId() != 0); - - ProgramBinary *programBinary = mState.getCurrentProgramBinary(); - programBinary->updateSamplerMapping(); - - Error error = generateSwizzles(programBinary); - if (error.isError()) - { - return error; - } - - if (!mRenderer->applyPrimitiveType(mode, count)) - { - return Error(GL_NO_ERROR); - } - - error = applyRenderTarget(mode, false); - if (error.isError()) - { - return error; - } - - error = applyState(mode); - if (error.isError()) - { - return error; - } - - error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances); - if (error.isError()) - { - return error; - } - - bool transformFeedbackActive = applyTransformFeedbackBuffers(); - - error = applyShaders(programBinary, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - error = applyTextures(programBinary); - if (error.isError()) - { - return error; - } - - error = applyUniformBuffers(); - if (error.isError()) - { - return error; - } - - if (!skipDraw(mode)) - { - error = mRenderer->drawArrays(mode, count, instances, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - if (transformFeedbackActive) - { - markTransformFeedbackUsage(); - } - } - - return gl::Error(GL_NO_ERROR); + return mRenderer->drawArrays(getData(), mode, first, count, instances); } Error Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances, const rx::RangeUI &indexRange) { - ASSERT(mState.getCurrentProgramId() != 0); - - ProgramBinary *programBinary = mState.getCurrentProgramBinary(); - programBinary->updateSamplerMapping(); - - Error error = generateSwizzles(programBinary); - if (error.isError()) - { - return error; - } - - if (!mRenderer->applyPrimitiveType(mode, count)) - { - return Error(GL_NO_ERROR); - } - - error = applyRenderTarget(mode, false); - if (error.isError()) - { - return error; - } - - error = applyState(mode); - if (error.isError()) - { - return error; - } - - VertexArray *vao = mState.getVertexArray(); - rx::TranslatedIndexData indexInfo; - indexInfo.indexRange = indexRange; - error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo); - if (error.isError()) - { - return error; - } - - GLsizei vertexCount = indexInfo.indexRange.length() + 1; - error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), - mState.getVertexAttribCurrentValues(), - indexInfo.indexRange.start, vertexCount, instances); - if (error.isError()) - { - return error; - } - - bool transformFeedbackActive = applyTransformFeedbackBuffers(); - // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation - // layer. - ASSERT(!transformFeedbackActive); - - error = applyShaders(programBinary, transformFeedbackActive); - if (error.isError()) - { - return error; - } - - error = applyTextures(programBinary); - if (error.isError()) - { - return error; - } - - error = applyUniformBuffers(); - if (error.isError()) - { - return error; - } - - if (!skipDraw(mode)) - { - error = mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances); - if (error.isError()) - { - return error; - } - } - - return Error(GL_NO_ERROR); + return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange); } // Implements glFlush when block is false, glFinish when block is true -void Context::sync(bool block) +Error Context::sync(bool block) { - mRenderer->sync(block); + return mRenderer->sync(block); } void Context::recordError(const Error &error) @@ -1931,6 +1392,7 @@ GLenum Context::getError() GLenum Context::getResetStatus() { + //TODO(jmadill): needs MANGLE reworking if (mResetStatus == GL_NO_ERROR && !mContextLost) { // mResetStatus will be set by the markContextLost callback @@ -1981,7 +1443,7 @@ const Extensions &Context::getExtensions() const void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type) { Framebuffer *framebuffer = mState.getReadFramebuffer(); - ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE); + ASSERT(framebuffer && framebuffer->completeness(getData()) == GL_FRAMEBUFFER_COMPLETE); FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); ASSERT(attachment); @@ -2000,7 +1462,7 @@ void Context::detachTexture(GLuint texture) // allocation map management either here or in the resource manager at detach time. // Zero textures are held by the Context, and we don't attempt to request them from // the State. - mState.detachTexture(texture); + mState.detachTexture(mZeroTextures, texture); } void Context::detachBuffer(GLuint buffer) @@ -2072,95 +1534,6 @@ void Context::detachSampler(GLuint sampler) mState.detachSampler(sampler); } -Texture *Context::getIncompleteTexture(GLenum type) -{ - if (mIncompleteTextures.find(type) == mIncompleteTextures.end()) - { - const GLubyte color[] = { 0, 0, 0, 255 }; - const PixelUnpackState incompleteUnpackState(1); - - Texture* t = NULL; - switch (type) - { - default: - UNREACHABLE(); - // default falls through to TEXTURE_2D - - case GL_TEXTURE_2D: - { - Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID); - incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - t = incomplete2d; - } - break; - - case GL_TEXTURE_CUBE_MAP: - { - TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID); - - incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - - t = incompleteCube; - } - break; - - case GL_TEXTURE_3D: - { - Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID); - incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - - t = incomplete3d; - } - break; - - case GL_TEXTURE_2D_ARRAY: - { - Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID); - incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); - - t = incomplete2darray; - } - break; - } - - mIncompleteTextures[type].set(t); - } - - return mIncompleteTextures[type].get(); -} - -bool Context::skipDraw(GLenum drawMode) -{ - if (drawMode == GL_POINTS) - { - // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, - // which affects varying interpolation. Since the value of gl_PointSize is - // undefined when not written, just skip drawing to avoid unexpected results. - if (!mState.getCurrentProgramBinary()->usesPointSize()) - { - // This is stictly speaking not an error, but developers should be - // notified of risking undefined behavior. - ERR("Point rendering without writing to gl_PointSize."); - - return true; - } - } - else if (IsTriangleMode(drawMode)) - { - if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK) - { - return true; - } - } - - return false; -} - void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) { mState.getVertexArray()->setVertexAttribDivisor(index, divisor); @@ -2293,63 +1666,12 @@ size_t Context::getExtensionStringCount() const return mExtensionStrings.size(); } -size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray) +Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { - size_t serialCount = 0; - - Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); - for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++) - { - FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); - if (attachment && attachment->isTexture()) - { - Texture *texture = attachment->getTexture(); - (*outSerialArray)[serialCount++] = texture->getTextureSerial(); - } - } - - FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); - if (depthStencilAttachment && depthStencilAttachment->isTexture()) - { - Texture *depthStencilTexture = depthStencilAttachment->getTexture(); - (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial(); - } - - std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount); - - return serialCount; -} - -void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - Framebuffer *readFramebuffer = mState.getReadFramebuffer(); - Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); - - bool blitRenderTarget = false; - bool blitDepth = false; - bool blitStencil = false; - if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer()) - { - blitRenderTarget = true; - } - if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) - { - blitStencil = true; - } - if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) - { - blitDepth = true; - } - - Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); - Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); - if (blitRenderTarget || blitDepth || blitStencil) - { - const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL; - mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor, - blitRenderTarget, blitDepth, blitStencil, filter); - } + return mRenderer->blitFramebuffer(getData(), srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); } void Context::releaseShaderCompiler() @@ -2416,6 +1738,11 @@ void Context::initCaps(GLuint clientVersion) mExtensions.maxSamples = maxSamples; } +Data Context::getData() const +{ + return Data(mClientVersion, mState, mCaps, mTextureCaps, mExtensions, mResourceManager); +} + } extern "C" diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h index 1b888aec83..1e890de3ef 100644 --- a/src/3rdparty/angle/src/libGLESv2/Context.h +++ b/src/3rdparty/angle/src/libGLESv2/Context.h @@ -13,12 +13,12 @@ #include "common/angleutils.h" #include "common/RefCountObject.h" #include "libGLESv2/Caps.h" +#include "libGLESv2/Constants.h" +#include "libGLESv2/Data.h" #include "libGLESv2/Error.h" #include "libGLESv2/HandleAllocator.h" -#include "libGLESv2/angletypes.h" -#include "libGLESv2/Constants.h" #include "libGLESv2/VertexAttribute.h" -#include "libGLESv2/State.h" +#include "libGLESv2/angletypes.h" #include "angle_gl.h" @@ -50,11 +50,6 @@ class Texture3D; class Texture2DArray; class Framebuffer; class Renderbuffer; -class RenderbufferStorage; -class Colorbuffer; -class Depthbuffer; -class Stencilbuffer; -class DepthStencilbuffer; class FenceNV; class FenceSync; class Query; @@ -68,7 +63,7 @@ class TransformFeedback; class Context { public: - Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); + Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); virtual ~Context(); @@ -86,7 +81,7 @@ class Context GLuint createRenderbuffer(); GLuint createSampler(); GLuint createTransformFeedback(); - GLsync createFenceSync(GLenum condition); + GLsync createFenceSync(); void deleteBuffer(GLuint buffer); void deleteShader(GLuint shader); @@ -115,7 +110,7 @@ class Context void bindArrayBuffer(GLuint buffer); void bindElementArrayBuffer(GLuint buffer); - void bindTexture(GLenum target, GLuint texture); + void bindTexture(GLenum target, GLuint handle); void bindReadFramebuffer(GLuint framebuffer); void bindDrawFramebuffer(GLuint framebuffer); void bindRenderbuffer(GLuint renderbuffer); @@ -130,8 +125,8 @@ class Context void bindPixelPackBuffer(GLuint buffer); void bindPixelUnpackBuffer(GLuint buffer); void useProgram(GLuint program); - void linkProgram(GLuint program); - void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length); + Error linkProgram(GLuint program); + Error setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length); void bindTransformFeedback(GLuint transformFeedback); Error beginQuery(GLenum target, GLuint query); @@ -139,8 +134,6 @@ class Context void setFramebufferZero(Framebuffer *framebuffer); - void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples); - void setVertexAttribDivisor(GLuint index, GLuint divisor); void samplerParameteri(GLuint sampler, GLenum pname, GLint param); @@ -183,17 +176,17 @@ class Context bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams); Error clear(GLbitfield mask); - Error clearBufferfv(GLenum buffer, int drawbuffer, const float *values); - Error clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values); - Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values); - Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil); + Error clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values); + Error clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values); + Error clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values); + Error clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels); Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances); Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances, const rx::RangeUI &indexRange); - void sync(bool block); // flush/finish + Error sync(bool block); // flush/finish void recordError(const Error &error); @@ -215,32 +208,21 @@ class Context void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type); - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); + Error blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); rx::Renderer *getRenderer() { return mRenderer; } State &getState() { return mState; } const State &getState() const { return mState; } + Data getData() const; + void releaseShaderCompiler(); private: DISALLOW_COPY_AND_ASSIGN(Context); - // TODO: std::array may become unavailable using older versions of GCC - typedef std::array FramebufferTextureSerialArray; - - Error applyRenderTarget(GLenum drawMode, bool ignoreViewport); - Error applyState(GLenum drawMode); - Error applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive); - Error applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials, - size_t framebufferSerialCount); - Error applyTextures(ProgramBinary *programBinary); - Error applyUniformBuffers(); - bool applyTransformFeedbackBuffers(); - void markTransformFeedbackUsage(); - void detachBuffer(GLuint buffer); void detachTexture(GLuint texture); void detachFramebuffer(GLuint framebuffer); @@ -249,18 +231,9 @@ class Context void detachTransformFeedback(GLuint transformFeedback); void detachSampler(GLuint sampler); - Error generateSwizzles(ProgramBinary *programBinary, SamplerType type); - Error generateSwizzles(ProgramBinary *programBinary); - - Texture *getIncompleteTexture(GLenum type); - - bool skipDraw(GLenum drawMode); - void initRendererString(); void initExtensionStrings(); - size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray); - void initCaps(GLuint clientVersion); // Caps to use for validation @@ -273,7 +246,6 @@ class Context int mClientVersion; - typedef std::map< GLenum, BindingPointer > TextureMap; TextureMap mZeroTextures; TextureMap mIncompleteTextures; diff --git a/src/3rdparty/angle/src/libGLESv2/Data.cpp b/src/3rdparty/angle/src/libGLESv2/Data.cpp new file mode 100644 index 0000000000..3ddf591d77 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/Data.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Data.cpp: Container class for all GL relevant state, caps and objects + +#include "libGLESv2/Data.h" +#include "libGLESv2/ResourceManager.h" + +namespace gl +{ + +Data::Data(GLint clientVersionIn, const State &stateIn, const Caps &capsIn, + const TextureCapsMap &textureCapsIn, const Extensions &extensionsIn, + const ResourceManager *resourceManagerIn) + : clientVersion(clientVersionIn), + state(&stateIn), + caps(&capsIn), + textureCaps(&textureCapsIn), + extensions(&extensionsIn), + resourceManager(resourceManagerIn) +{} + +Data::~Data() +{ +} + +Data::Data(const Data &other) + : clientVersion(other.clientVersion), + state(other.state), + caps(other.caps), + textureCaps(other.textureCaps), + extensions(other.extensions), + resourceManager(other.resourceManager) +{ +} + +Data &Data::operator=(const Data &other) +{ + clientVersion = other.clientVersion; + state = other.state; + caps = other.caps; + textureCaps = other.textureCaps; + extensions = other.extensions; + resourceManager = other.resourceManager; + return *this; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libGLESv2/Data.h new file mode 100644 index 0000000000..9234403e13 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/Data.h @@ -0,0 +1,38 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Data.h: Container class for all GL relevant state, caps and objects + +#ifndef LIBGLESV2_DATA_H_ +#define LIBGLESV2_DATA_H_ + +#include "libGLESv2/State.h" + +namespace gl +{ + +struct Data +{ + public: + Data(GLint clientVersion, const State &state, const Caps &caps, + const TextureCapsMap &textureCaps, const Extensions &extensions, + const ResourceManager *resourceManager); + ~Data(); + + Data(const Data &other); + Data &operator=(const Data &other); + + GLint clientVersion; + const State *state; + const Caps *caps; + const TextureCapsMap *textureCaps; + const Extensions *extensions; + const ResourceManager *resourceManager; +}; + +} + +#endif // LIBGLESV2_DATA_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.cpp b/src/3rdparty/angle/src/libGLESv2/Fence.cpp index ee9a07a5c4..966a327de5 100644 --- a/src/3rdparty/angle/src/libGLESv2/Fence.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Fence.cpp @@ -4,191 +4,113 @@ // found in the LICENSE file. // -// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension. - -// Important note on accurate timers in Windows: -// -// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call -// as timeGetTime on laptops and "jumping" during certain hardware events. -// -// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc" -// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc -// -// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer -// from buggy implementations. +// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence +// extension and GLES3 sync objects. #include "libGLESv2/Fence.h" #include "libGLESv2/renderer/FenceImpl.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/main.h" +#include "common/utilities.h" #include "angle_gl.h" namespace gl { -FenceNV::FenceNV(rx::Renderer *renderer) +FenceNV::FenceNV(rx::FenceNVImpl *impl) + : mFence(impl), + mIsSet(false), + mStatus(GL_FALSE), + mCondition(GL_NONE) { - mFence = renderer->createFence(); } FenceNV::~FenceNV() { - delete mFence; + SafeDelete(mFence); } GLboolean FenceNV::isFence() const { // GL_NV_fence spec: // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. - return (mFence->isSet() ? GL_TRUE : GL_FALSE); + return (mIsSet ? GL_TRUE : GL_FALSE); } -void FenceNV::setFence(GLenum condition) +Error FenceNV::setFence(GLenum condition) { - mFence->set(); + Error error = mFence->set(); + if (error.isError()) + { + return error; + } mCondition = condition; mStatus = GL_FALSE; + mIsSet = true; + + return Error(GL_NO_ERROR); } -GLboolean FenceNV::testFence() +Error FenceNV::testFence(GLboolean *outResult) { // Flush the command buffer by default - bool result = mFence->test(true); - - mStatus = (result ? GL_TRUE : GL_FALSE); - return mStatus; -} - -void FenceNV::finishFence() -{ - ASSERT(mFence->isSet()); - - while (!mFence->test(true)) + Error error = mFence->test(true, &mStatus); + if (error.isError()) { - Sleep(0); + return error; } + + *outResult = mStatus; + return Error(GL_NO_ERROR); } -GLint FenceNV::getFencei(GLenum pname) +Error FenceNV::finishFence() { - ASSERT(mFence->isSet()); + ASSERT(mIsSet); - switch (pname) - { - case GL_FENCE_STATUS_NV: - { - // GL_NV_fence spec: - // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV - // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. - if (mStatus == GL_TRUE) - { - return GL_TRUE; - } - - mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE); - return mStatus; - } - - case GL_FENCE_CONDITION_NV: - return mCondition; - - default: UNREACHABLE(); return 0; - } + return mFence->finishFence(&mStatus); } -FenceSync::FenceSync(rx::Renderer *renderer, GLuint id) - : RefCountObject(id) +FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id) + : RefCountObject(id), + mFence(impl), + mCondition(GL_NONE) { - mFence = renderer->createFence(); - - LARGE_INTEGER counterFreqency = { 0 }; - BOOL success = QueryPerformanceFrequency(&counterFreqency); - UNUSED_ASSERTION_VARIABLE(success); - ASSERT(success); - - mCounterFrequency = counterFreqency.QuadPart; } FenceSync::~FenceSync() { - delete mFence; + SafeDelete(mFence); } -void FenceSync::set(GLenum condition) +Error FenceSync::set(GLenum condition) { + Error error = mFence->set(); + if (error.isError()) + { + return error; + } + mCondition = condition; - mFence->set(); + return Error(GL_NO_ERROR); } -GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout) +Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) { - ASSERT(mFence->isSet()); - - bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); - - if (mFence->test(flushCommandBuffer)) - { - return GL_ALREADY_SIGNALED; - } - - if (mFence->hasError()) - { - return GL_WAIT_FAILED; - } - - if (timeout == 0) - { - return GL_TIMEOUT_EXPIRED; - } - - LARGE_INTEGER currentCounter = { 0 }; - BOOL success = QueryPerformanceCounter(¤tCounter); - UNUSED_ASSERTION_VARIABLE(success); - ASSERT(success); - - LONGLONG timeoutInSeconds = static_cast(timeout) * static_cast(1000000ll); - LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; - - while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer)) - { - Sleep(0); - BOOL success = QueryPerformanceCounter(¤tCounter); - UNUSED_ASSERTION_VARIABLE(success); - ASSERT(success); - } - - if (mFence->hasError()) - { - return GL_WAIT_FAILED; - } - - if (currentCounter.QuadPart >= endCounter) - { - return GL_TIMEOUT_EXPIRED; - } - - return GL_CONDITION_SATISFIED; + ASSERT(mCondition != GL_NONE); + return mFence->clientWait(flags, timeout, outResult); } -void FenceSync::serverWait() +Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout) { - // Because our API is currently designed to be called from a single thread, we don't need to do - // extra work for a server-side fence. GPU commands issued after the fence is created will always - // be processed after the fence is signaled. + return mFence->serverWait(flags, timeout); } -GLenum FenceSync::getStatus() const +Error FenceSync::getStatus(GLint *outResult) const { - if (mFence->test(false)) - { - // The spec does not specify any way to report errors during the status test (e.g. device lost) - // so we report the fence is unblocked in case of error or signaled. - return GL_SIGNALED; - } - - return GL_UNSIGNALED; + return mFence->getStatus(outResult); } } diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.h b/src/3rdparty/angle/src/libGLESv2/Fence.h index 291edb3de1..fd565e96a6 100644 --- a/src/3rdparty/angle/src/libGLESv2/Fence.h +++ b/src/3rdparty/angle/src/libGLESv2/Fence.h @@ -4,18 +4,21 @@ // found in the LICENSE file. // -// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension. +// Fence.h: Defines the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence +// extension and GLES3 sync objects. #ifndef LIBGLESV2_FENCE_H_ #define LIBGLESV2_FENCE_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" #include "common/RefCountObject.h" namespace rx { -class Renderer; -class FenceImpl; +class FenceNVImpl; +class FenceSyncImpl; } namespace gl @@ -24,14 +27,13 @@ namespace gl class FenceNV { public: - explicit FenceNV(rx::Renderer *renderer); + explicit FenceNV(rx::FenceNVImpl *impl); virtual ~FenceNV(); GLboolean isFence() const; - void setFence(GLenum condition); - GLboolean testFence(); - void finishFence(); - GLint getFencei(GLenum pname); + Error setFence(GLenum condition); + Error testFence(GLboolean *outResult); + Error finishFence(); GLboolean getStatus() const { return mStatus; } GLuint getCondition() const { return mCondition; } @@ -39,7 +41,9 @@ class FenceNV private: DISALLOW_COPY_AND_ASSIGN(FenceNV); - rx::FenceImpl *mFence; + rx::FenceNVImpl *mFence; + + bool mIsSet; GLboolean mStatus; GLenum mCondition; @@ -48,21 +52,20 @@ class FenceNV class FenceSync : public RefCountObject { public: - explicit FenceSync(rx::Renderer *renderer, GLuint id); + explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id); virtual ~FenceSync(); - void set(GLenum condition); - GLenum clientWait(GLbitfield flags, GLuint64 timeout); - void serverWait(); - GLenum getStatus() const; + Error set(GLenum condition); + Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult); + Error serverWait(GLbitfield flags, GLuint64 timeout); + Error getStatus(GLint *outResult) const; GLuint getCondition() const { return mCondition; } private: DISALLOW_COPY_AND_ASSIGN(FenceSync); - rx::FenceImpl *mFence; - LONGLONG mCounterFrequency; + rx::FenceSyncImpl *mFence; GLenum mCondition; }; diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp index 5b21433f90..3d57262e3c 100644 --- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp @@ -16,13 +16,18 @@ #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/renderer/RenderTarget.h" +#include "libGLESv2/renderer/RenderbufferImpl.h" +#include "libGLESv2/renderer/Workarounds.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/RenderbufferD3D.h" #include "common/utilities.h" namespace rx { -RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +// TODO: Move these functions, and the D3D-specific header inclusions above, +// to FramebufferD3D. +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT) { if (attachment->isTexture()) { @@ -31,14 +36,16 @@ RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); const gl::ImageIndex *index = attachment->getTextureImageIndex(); ASSERT(index); - return textureD3D->getRenderTarget(*index); + return textureD3D->getRenderTarget(*index, outRT); + } + else + { + gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); + ASSERT(renderbuffer); + RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation()); + *outRT = renderbufferD3D->getRenderTarget(); + return gl::Error(GL_NO_ERROR); } - - gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); - ASSERT(renderbuffer); - - // TODO: cast to RenderbufferD3D - return renderbuffer->getStorage()->getRenderTarget(); } // Note: RenderTarget serials should ideally be in the RenderTargets themselves. @@ -56,9 +63,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment) gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); ASSERT(renderbuffer); - - // TODO: cast to RenderbufferD3D - return renderbuffer->getStorage()->getSerial(); + RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation()); + return renderbufferD3D->getRenderTargetSerial(); } } @@ -66,9 +72,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment) namespace gl { -Framebuffer::Framebuffer(rx::Renderer *renderer, GLuint id) - : mRenderer(renderer), - mId(id), +Framebuffer::Framebuffer(GLuint id) + : mId(id), mReadBufferState(GL_COLOR_ATTACHMENT0_EXT), mDepthbuffer(NULL), mStencilbuffer(NULL) @@ -91,124 +96,6 @@ Framebuffer::~Framebuffer() SafeDelete(mStencilbuffer); } -FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const -{ - if (handle == 0) - { - return NULL; - } - - gl::Context *context = gl::getContext(); - - switch (type) - { - case GL_NONE: - return NULL; - - case GL_RENDERBUFFER: - return new RenderbufferAttachment(binding, context->getRenderbuffer(handle)); - - case GL_TEXTURE_2D: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_2D) - { - return new TextureAttachment(binding, texture, ImageIndex::Make2D(level)); - } - else - { - return NULL; - } - } - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP) - { - return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level)); - } - else - { - return NULL; - } - } - - case GL_TEXTURE_3D: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_3D) - { - return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer)); - } - else - { - return NULL; - } - } - - case GL_TEXTURE_2D_ARRAY: - { - Texture *texture = context->getTexture(handle); - if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY) - { - return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer)); - } - else - { - return NULL; - } - } - - default: - UNREACHABLE(); - return NULL; - } -} - -void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer) -{ - ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); - SafeDelete(mColorbuffers[colorAttachment]); - GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0; - mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer); -} - -void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer) -{ - SafeDelete(mDepthbuffer); - mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer); -} - -void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer) -{ - SafeDelete(mStencilbuffer); - mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer); -} - -void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer) -{ - FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer); - - SafeDelete(mDepthbuffer); - SafeDelete(mStencilbuffer); - - // ensure this is a legitimate depth+stencil format - if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0) - { - mDepthbuffer = attachment; - - // Make a new attachment object to ensure we do not double-delete - // See angle issue 686 - mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer); - } -} - void Framebuffer::detachTexture(GLuint textureId) { for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) @@ -382,14 +269,13 @@ bool Framebuffer::usingExtendedDrawBuffers() const return false; } -GLenum Framebuffer::completeness() const +GLenum Framebuffer::completeness(const gl::Data &data) const { int width = 0; int height = 0; unsigned int colorbufferSize = 0; int samples = -1; bool missingAttachment = true; - GLuint clientVersion = mRenderer->getCurrentClientVersion(); for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { @@ -403,8 +289,7 @@ GLenum Framebuffer::completeness() const } GLenum internalformat = colorbuffer->getInternalFormat(); - // TODO(geofflang): use context's texture caps - const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat); + const TextureCaps &formatCaps = data.textureCaps->get(internalformat); const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); if (colorbuffer->isTexture()) { @@ -443,7 +328,7 @@ GLenum Framebuffer::completeness() const // in GLES 2.0, all color attachments attachments must have the same number of bitplanes // in GLES 3.0, there is no such restriction - if (clientVersion < 3) + if (data.clientVersion < 3) { if (formatInfo.pixelBytes != colorbufferSize) { @@ -483,14 +368,12 @@ GLenum Framebuffer::completeness() const } GLenum internalformat = mDepthbuffer->getInternalFormat(); - // TODO(geofflang): use context's texture caps - const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat); + const TextureCaps &formatCaps = data.textureCaps->get(internalformat); const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); if (mDepthbuffer->isTexture()) { // depth texture attachments require OES/ANGLE_depth_texture - // TODO(geofflang): use context's extensions - if (!mRenderer->getRendererExtensions().depthTextures) + if (!data.extensions->depthTextures) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -538,15 +421,13 @@ GLenum Framebuffer::completeness() const } GLenum internalformat = mStencilbuffer->getInternalFormat(); - // TODO(geofflang): use context's texture caps - const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat); + const TextureCaps &formatCaps = data.textureCaps->get(internalformat); const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); if (mStencilbuffer->isTexture()) { // texture stencil attachments come along as part // of OES_packed_depth_stencil + OES/ANGLE_depth_texture - // TODO(geofflang): use context's extensions - if (!mRenderer->getRendererExtensions().depthTextures) + if (!data.extensions->depthTextures) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -602,42 +483,44 @@ GLenum Framebuffer::completeness() const return GL_FRAMEBUFFER_COMPLETE; } -void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments) +Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments) { GLuint maxDimension = caps.maxRenderbufferSize; - invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension); + return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension); } -void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments, - GLint x, GLint y, GLsizei width, GLsizei height) +Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) { - ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE); for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex) { GLenum attachmentTarget = attachments[attachIndex]; - gl::FramebufferAttachment *attachment = - (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() : - getAttachment(attachmentTarget); + FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() + : getAttachment(attachmentTarget); if (attachment) { - rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); - if (renderTarget) + rx::RenderTarget *renderTarget = NULL; + Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - renderTarget->invalidate(x, y, width, height); + return error; } + + renderTarget->invalidate(x, y, width, height); } } + + return Error(GL_NO_ERROR); } -DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) - : Framebuffer(renderer, 0) +DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil) + : Framebuffer(0) { - Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer); + Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0); mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer); - Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil); + Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0); // Make a new attachment objects to ensure we do not double-delete // See angle issue 686 @@ -648,9 +531,9 @@ DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colo mReadBufferState = GL_BACK; } -int Framebuffer::getSamples() const +int Framebuffer::getSamples(const gl::Data &data) const { - if (completeness() == GL_FRAMEBUFFER_COMPLETE) + if (completeness(data) == GL_FRAMEBUFFER_COMPLETE) { // for a complete framebuffer, all attachments must have the same sample count // in this case return the first nonzero sample size @@ -675,7 +558,7 @@ bool Framebuffer::hasValidDepthStencil() const mDepthbuffer->id() == mStencilbuffer->id()); } -ColorbufferInfo Framebuffer::getColorbuffersForRender() const +ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const { ColorbufferInfo colorbuffersForRender; @@ -689,18 +572,78 @@ ColorbufferInfo Framebuffer::getColorbuffersForRender() const ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment)); colorbuffersForRender.push_back(colorbuffer); } -#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED) - else + else if (!workarounds.mrtPerfWorkaround) { colorbuffersForRender.push_back(NULL); } -#endif } return colorbuffersForRender; } -GLenum DefaultFramebuffer::completeness() const +void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex) +{ + setAttachment(attachment, new TextureAttachment(attachment, texture, imageIndex)); +} + +void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer) +{ + setAttachment(attachment, new RenderbufferAttachment(attachment, renderbuffer)); +} + +void Framebuffer::setNULLAttachment(GLenum attachment) +{ + setAttachment(attachment, NULL); +} + +void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj) +{ + if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + IMPLEMENTATION_MAX_DRAW_BUFFERS)) + { + size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0; + SafeDelete(mColorbuffers[colorAttachment]); + mColorbuffers[colorAttachment] = attachmentObj; + } + else if (attachment == GL_DEPTH_ATTACHMENT) + { + SafeDelete(mDepthbuffer); + mDepthbuffer = attachmentObj; + } + else if (attachment == GL_STENCIL_ATTACHMENT) + { + SafeDelete(mStencilbuffer); + mStencilbuffer = attachmentObj; + } + else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) + { + SafeDelete(mDepthbuffer); + SafeDelete(mStencilbuffer); + + // ensure this is a legitimate depth+stencil format + if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0) + { + mDepthbuffer = attachmentObj; + + // Make a new attachment object to ensure we do not double-delete + // See angle issue 686 + if (attachmentObj->isTexture()) + { + mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(), + *attachmentObj->getTextureImageIndex()); + } + else + { + mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer()); + } + } + } + else + { + UNREACHABLE(); + } +} + +GLenum DefaultFramebuffer::completeness(const gl::Data &) const { // The default framebuffer *must* always be complete, though it may not be // subject to the same rules as application FBOs. ie, it could have 0x0 size. diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h index cc12d22953..d0fe8935ea 100644 --- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h @@ -10,41 +10,44 @@ #ifndef LIBGLESV2_FRAMEBUFFER_H_ #define LIBGLESV2_FRAMEBUFFER_H_ -#include +#include "libGLESv2/Error.h" #include "common/angleutils.h" #include "common/RefCountObject.h" -#include "constants.h" +#include "Constants.h" + +#include namespace rx { -class Renderer; +class RenderbufferImpl; +struct Workarounds; } namespace gl { class FramebufferAttachment; -class Colorbuffer; -class Depthbuffer; -class Stencilbuffer; -class DepthStencilbuffer; +class Texture; +class Renderbuffer; +struct ImageIndex; struct Caps; +struct Extensions; +class TextureCapsMap; +struct Data; typedef std::vector ColorbufferInfo; class Framebuffer { public: - Framebuffer(rx::Renderer *renderer, GLuint id); - + Framebuffer(GLuint id); virtual ~Framebuffer(); GLuint id() const { return mId; } - void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer); - void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer); - void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer); - void setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer); + void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex); + void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer); + void setNULLAttachment(GLenum attachment); void detachTexture(GLuint texture); void detachRenderbuffer(GLuint renderbuffer); @@ -66,24 +69,21 @@ class Framebuffer bool isEnabledColorAttachment(unsigned int colorAttachment) const; bool hasEnabledColorAttachment() const; bool hasStencil() const; - int getSamples() const; + int getSamples(const gl::Data &data) const; bool usingExtendedDrawBuffers() const; - virtual GLenum completeness() const; + virtual GLenum completeness(const gl::Data &data) const; bool hasValidDepthStencil() const; - void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments); - void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments, - GLint x, GLint y, GLsizei width, GLsizei height); + Error invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments); + Error invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); // Use this method to retrieve the color buffer map when doing rendering. // It will apply a workaround for poor shader performance on some systems // by compacting the list to skip NULL values. - ColorbufferInfo getColorbuffersForRender() const; + ColorbufferInfo getColorbuffersForRender(const rx::Workarounds &workarounds) const; protected: - rx::Renderer *mRenderer; - GLuint mId; FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS]; @@ -96,15 +96,15 @@ class Framebuffer private: DISALLOW_COPY_AND_ASSIGN(Framebuffer); - FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const; + void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj); }; class DefaultFramebuffer : public Framebuffer { public: - DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil); + DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil); - virtual GLenum completeness() const; + GLenum completeness(const gl::Data &data) const override; virtual FramebufferAttachment *getAttachment(GLenum attachment) const; private: @@ -118,7 +118,7 @@ namespace rx class RenderTarget; // TODO: place this in FramebufferD3D.h -RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT); unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment); } diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp index 540ede1cd2..894884a6d8 100644 --- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp +++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp @@ -187,7 +187,7 @@ GLenum RenderbufferAttachment::getActualFormat() const GLsizei RenderbufferAttachment::getSamples() const { - return mRenderbuffer->getStorage()->getSamples(); + return mRenderbuffer->getSamples(); } GLuint RenderbufferAttachment::id() const diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h index c18ef7364d..8d2dafa7ee 100644 --- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h +++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h @@ -16,13 +16,6 @@ #include "angle_gl.h" -namespace rx -{ -class Renderer; -class RenderTarget; -class TextureStorage; -} - namespace gl { class Renderbuffer; diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp index 3522b997e8..b45cd9c169 100644 --- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp @@ -48,10 +48,101 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex) return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex); } +ImageIndex ImageIndex::MakeInvalid() +{ + return ImageIndex(GL_NONE, -1, -1); +} + ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn) : type(typeIn), mipIndex(mipIndexIn), layerIndex(layerIndexIn) {} +ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(GL_TEXTURE_2D, rx::Range(minMip, maxMip), + rx::Range(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL); +} + +ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, rx::Range(minMip, maxMip), rx::Range(0, 6), NULL); +} + +ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip, + GLint minLayer, GLint maxLayer) +{ + return ImageIndexIterator(GL_TEXTURE_3D, rx::Range(minMip, maxMip), rx::Range(minLayer, maxLayer), NULL); +} + +ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip, + const GLsizei *layerCounts) +{ + return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, rx::Range(minMip, maxMip), + rx::Range(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts); +} + +ImageIndexIterator::ImageIndexIterator(GLenum type, const rx::Range &mipRange, + const rx::Range &layerRange, const GLsizei *layerCounts) + : mType(type), + mMipRange(mipRange), + mLayerRange(layerRange), + mLayerCounts(layerCounts), + mCurrentMip(mipRange.start), + mCurrentLayer(layerRange.start) +{} + +GLint ImageIndexIterator::maxLayer() const +{ + return (mLayerCounts ? static_cast(mLayerCounts[mCurrentMip]) : mLayerRange.end); +} + +ImageIndex ImageIndexIterator::next() +{ + ASSERT(hasNext()); + + ImageIndex value = current(); + + // Iterate layers in the inner loop for now. We can add switchable + // layer or mip iteration if we need it. + + if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL) + { + if (mCurrentLayer < maxLayer()-1) + { + mCurrentLayer++; + } + else if (mCurrentMip < mMipRange.end-1) + { + mCurrentMip++; + mCurrentLayer = mLayerRange.start; + } + } + else if (mCurrentMip < mMipRange.end-1) + { + mCurrentMip++; + mCurrentLayer = mLayerRange.start; + } + + return value; +} + +ImageIndex ImageIndexIterator::current() const +{ + ImageIndex value(mType, mCurrentMip, mCurrentLayer); + + if (mType == GL_TEXTURE_CUBE_MAP) + { + value.type = TextureCubeMap::layerIndexToTarget(mCurrentLayer); + } + + return value; +} + +bool ImageIndexIterator::hasNext() const +{ + return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer()); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h index 9f2df88061..8bb14fd555 100644 --- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h +++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h @@ -10,6 +10,7 @@ #define LIBGLESV2_IMAGE_INDEX_H_ #include "angle_gl.h" +#include "common/mathutil.h" namespace gl { @@ -20,6 +21,7 @@ struct ImageIndex GLint mipIndex; GLint layerIndex; + ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn); ImageIndex(const ImageIndex &other); ImageIndex &operator=(const ImageIndex &other); @@ -29,11 +31,36 @@ struct ImageIndex static ImageIndex MakeCube(GLenum target, GLint mipIndex); static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex); static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL); + static ImageIndex MakeInvalid(); static const GLint ENTIRE_LEVEL = static_cast(-1); +}; + +class ImageIndexIterator +{ + public: + static ImageIndexIterator Make2D(GLint minMip, GLint maxMip); + static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip); + static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer); + static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts); + + ImageIndex next(); + ImageIndex current() const; + bool hasNext() const; private: - ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn); + + ImageIndexIterator(GLenum type, const rx::Range &mipRange, + const rx::Range &layerRange, const GLsizei *layerCounts); + + GLint maxLayer() const; + + GLenum mType; + rx::Range mMipRange; + rx::Range mLayerRange; + const GLsizei *mLayerCounts; + GLint mCurrentMip; + GLint mCurrentLayer; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/Program.cpp b/src/3rdparty/angle/src/libGLESv2/Program.cpp index 9bfda09a64..3faa8c56f6 100644 --- a/src/3rdparty/angle/src/libGLESv2/Program.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Program.cpp @@ -244,7 +244,7 @@ void Program::bindAttributeLocation(GLuint index, const char *name) // Links the HLSL code of the vertex and pixel shader by matching up their varyings, // compiling them into binaries, determining the attribute mappings, and collecting // a list of uniforms -bool Program::link(const Caps &caps) +Error Program::link(const Data &data) { unlink(false); @@ -252,10 +252,15 @@ bool Program::link(const Caps &caps) resetUniformBlockBindings(); mProgramBinary.set(new ProgramBinary(mRenderer->createProgram())); - mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader, - mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps); + LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader, + mTransformFeedbackVaryings, mTransformFeedbackBufferMode); + if (result.error.isError()) + { + return result.error; + } - return mLinked; + mLinked = result.linkSuccess; + return gl::Error(GL_NO_ERROR); } int AttributeBindings::getAttributeBinding(const std::string &name) const @@ -303,21 +308,22 @@ ProgramBinary* Program::getProgramBinary() const return mProgramBinary.get(); } -bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length) +Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length) { unlink(false); mInfoLog.reset(); mProgramBinary.set(new ProgramBinary(mRenderer->createProgram())); - mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length); - - if (!mLinked) + LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length); + if (result.error.isError()) { mProgramBinary.set(NULL); + return result.error; } - return mLinked; + mLinked = result.linkSuccess; + return Error(GL_NO_ERROR); } void Program::release() diff --git a/src/3rdparty/angle/src/libGLESv2/Program.h b/src/3rdparty/angle/src/libGLESv2/Program.h index 6528dd1191..b92349eeef 100644 --- a/src/3rdparty/angle/src/libGLESv2/Program.h +++ b/src/3rdparty/angle/src/libGLESv2/Program.h @@ -29,6 +29,7 @@ class Renderer; namespace gl { struct Caps; +struct Data; class ResourceManager; class Shader; @@ -77,9 +78,9 @@ class Program void bindAttributeLocation(GLuint index, const char *name); - bool link(const Caps &caps); + Error link(const Data &data); bool isLinked(); - bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length); + Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length); ProgramBinary *getProgramBinary() const; int getInfoLogLength() const; diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp index 3f6d9e0ef9..6d64b38b56 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp @@ -23,13 +23,11 @@ #include "libGLESv2/Shader.h" #include "libGLESv2/Program.h" #include "libGLESv2/renderer/ProgramImpl.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/d3d/DynamicHLSL.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" -#include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/Context.h" #include "libGLESv2/Buffer.h" #include "common/blocklayout.h" +#include "common/features.h" namespace gl { @@ -37,36 +35,6 @@ namespace gl namespace { -GLenum GetTextureType(GLenum samplerType) -{ - switch (samplerType) - { - case GL_SAMPLER_2D: - case GL_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_SAMPLER_2D_SHADOW: - return GL_TEXTURE_2D; - case GL_SAMPLER_3D: - case GL_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_3D: - return GL_TEXTURE_3D; - case GL_SAMPLER_CUBE: - case GL_SAMPLER_CUBE_SHADOW: - return GL_TEXTURE_CUBE_MAP; - case GL_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - return GL_TEXTURE_CUBE_MAP; - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - return GL_TEXTURE_2D_ARRAY; - default: UNREACHABLE(); - } - - return GL_TEXTURE_2D; -} - unsigned int ParseAndStripArrayIndex(std::string* name) { unsigned int subscript = GL_INVALID_INDEX; @@ -83,52 +51,6 @@ unsigned int ParseAndStripArrayIndex(std::string* name) return subscript; } -void GetDefaultInputLayoutFromShader(const std::vector &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) -{ - size_t layoutIndex = 0; - for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) - { - ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS); - - const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex]; - - if (shaderAttr.type != GL_NONE) - { - GLenum transposedType = TransposeMatrixType(shaderAttr.type); - - for (size_t rowIndex = 0; static_cast(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++) - { - VertexFormat *defaultFormat = &inputLayout[layoutIndex]; - - defaultFormat->mType = VariableComponentType(transposedType); - defaultFormat->mNormalized = false; - defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool - defaultFormat->mComponents = VariableColumnCount(transposedType); - } - } - } -} - -std::vector GetDefaultOutputLayoutFromShader(const std::vector &shaderOutputVars) -{ - std::vector defaultPixelOutput(1); - - ASSERT(!shaderOutputVars.empty()); - defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex; - - return defaultPixelOutput; -} - -bool IsRowMajorLayout(const sh::InterfaceBlockField &var) -{ - return var.isRowMajorLayout; -} - -bool IsRowMajorLayout(const sh::ShaderVariable &var) -{ - return false; -} - } VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index) @@ -136,47 +58,6 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element { } -ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[], - const GLenum signature[], - rx::ShaderExecutable *shaderExecutable) - : mShaderExecutable(shaderExecutable) -{ - for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) - { - mInputs[attributeIndex] = inputLayout[attributeIndex]; - mSignature[attributeIndex] = signature[attributeIndex]; - } -} - -ProgramBinary::VertexExecutable::~VertexExecutable() -{ - SafeDelete(mShaderExecutable); -} - -bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const -{ - for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) - { - if (mSignature[attributeIndex] != signature[attributeIndex]) - { - return false; - } - } - - return true; -} - -ProgramBinary::PixelExecutable::PixelExecutable(const std::vector &outputSignature, rx::ShaderExecutable *shaderExecutable) - : mOutputSignature(outputSignature), - mShaderExecutable(shaderExecutable) -{ -} - -ProgramBinary::PixelExecutable::~PixelExecutable() -{ - SafeDelete(mShaderExecutable); -} - LinkedVarying::LinkedVarying() { } @@ -187,17 +68,17 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, { } +LinkResult::LinkResult(bool linkSuccess, const Error &error) + : linkSuccess(linkSuccess), + error(error) +{ +} + unsigned int ProgramBinary::mCurrentSerial = 1; ProgramBinary::ProgramBinary(rx::ProgramImpl *impl) : RefCountObject(0), mProgram(impl), - mGeometryExecutable(NULL), - mUsedVertexSamplerRange(0), - mUsedPixelSamplerRange(0), - mUsesPointSize(false), - mShaderVersion(100), - mDirtySamplerMapping(true), mValidated(false), mSerial(issueSerial()) { @@ -220,103 +101,11 @@ unsigned int ProgramBinary::getSerial() const return mSerial; } -int ProgramBinary::getShaderVersion() const -{ - return mShaderVersion; -} - unsigned int ProgramBinary::issueSerial() { return mCurrentSerial++; } -rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo) -{ - std::vector outputs; - - const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(); - - for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) - { - const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; - - if (colorbuffer) - { - outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding()); - } - else - { - outputs.push_back(GL_NONE); - } - } - - return getPixelExecutableForOutputLayout(outputs); -} - -rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector &outputSignature) -{ - for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) - { - if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature)) - { - return mPixelExecutables[executableIndex]->shaderExecutable(); - } - } - - InfoLog tempInfoLog; - rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature, - mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!pixelExecutable) - { - std::vector tempCharBuffer(tempInfoLog.getLength() + 3); - tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); - ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]); - } - else - { - mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable)); - } - - return pixelExecutable; -} - -rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) -{ - GLenum signature[MAX_VERTEX_ATTRIBS]; - mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature); - - for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) - { - if (mVertexExecutables[executableIndex]->matchesSignature(signature)) - { - return mVertexExecutables[executableIndex]->shaderExecutable(); - } - } - - InfoLog tempInfoLog; - rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes, - mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!vertexExecutable) - { - std::vector tempCharBuffer(tempInfoLog.getLength()+3); - tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); - ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); - } - else - { - mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable)); - } - - return vertexExecutable; -} - -rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const -{ - return mGeometryExecutable; -} - GLuint ProgramBinary::getAttributeLocation(const char *name) { if (name) @@ -343,157 +132,42 @@ int ProgramBinary::getSemanticIndex(int attributeIndex) // Returns one more than the highest sampler index used. GLint ProgramBinary::getUsedSamplerRange(SamplerType type) { - switch (type) - { - case SAMPLER_PIXEL: - return mUsedPixelSamplerRange; - case SAMPLER_VERTEX: - return mUsedVertexSamplerRange; - default: - UNREACHABLE(); - return 0; - } + return mProgram->getUsedSamplerRange(type); } bool ProgramBinary::usesPointSize() const { - return mUsesPointSize; -} - -bool ProgramBinary::usesPointSpriteEmulation() const -{ - return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4; -} - -bool ProgramBinary::usesGeometryShader() const -{ - return usesPointSpriteEmulation(); + return mProgram->usesPointSize(); } GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps) { - GLint logicalTextureUnit = -1; - - switch (type) - { - case SAMPLER_PIXEL: - ASSERT(samplerIndex < caps.maxTextureImageUnits); - if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active) - { - logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; - } - break; - case SAMPLER_VERTEX: - ASSERT(samplerIndex < caps.maxVertexTextureImageUnits); - if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active) - { - logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; - } - break; - default: UNREACHABLE(); - } - - if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast(caps.maxCombinedTextureImageUnits)) - { - return logicalTextureUnit; - } - - return -1; + return mProgram->getSamplerMapping(type, samplerIndex, caps); } -// Returns the texture type for a given Direct3D 9 sampler type and -// index (0-15 for the pixel shader and 0-3 for the vertex shader). GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) { - switch (type) - { - case SAMPLER_PIXEL: - ASSERT(samplerIndex < mSamplersPS.size()); - ASSERT(mSamplersPS[samplerIndex].active); - return mSamplersPS[samplerIndex].textureType; - case SAMPLER_VERTEX: - ASSERT(samplerIndex < mSamplersVS.size()); - ASSERT(mSamplersVS[samplerIndex].active); - return mSamplersVS[samplerIndex].textureType; - default: UNREACHABLE(); - } - - return GL_TEXTURE_2D; + return mProgram->getSamplerTextureType(type, samplerIndex); } GLint ProgramBinary::getUniformLocation(std::string name) { - unsigned int subscript = ParseAndStripArrayIndex(&name); - - unsigned int numUniforms = mUniformIndex.size(); - for (unsigned int location = 0; location < numUniforms; location++) - { - if (mUniformIndex[location].name == name) - { - const int index = mUniformIndex[location].index; - const bool isArray = mUniforms[index]->isArray(); - - if ((isArray && mUniformIndex[location].element == subscript) || - (subscript == GL_INVALID_INDEX)) - { - return location; - } - } - } - - return -1; + return mProgram->getUniformLocation(name); } GLuint ProgramBinary::getUniformIndex(std::string name) { - unsigned int subscript = ParseAndStripArrayIndex(&name); - - // The app is not allowed to specify array indices other than 0 for arrays of basic types - if (subscript != 0 && subscript != GL_INVALID_INDEX) - { - return GL_INVALID_INDEX; - } - - unsigned int numUniforms = mUniforms.size(); - for (unsigned int index = 0; index < numUniforms; index++) - { - if (mUniforms[index]->name == name) - { - if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX) - { - return index; - } - } - } - - return GL_INVALID_INDEX; + return mProgram->getUniformIndex(name); } GLuint ProgramBinary::getUniformBlockIndex(std::string name) { - unsigned int subscript = ParseAndStripArrayIndex(&name); - - unsigned int numUniformBlocks = mUniformBlocks.size(); - for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) - { - const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex]; - if (uniformBlock.name == name) - { - const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); - if (subscript == uniformBlock.elementIndex || arrayElementZero) - { - return blockIndex; - } - } - } - - return GL_INVALID_INDEX; + return mProgram->getUniformBlockIndex(name); } UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex) { - ASSERT(blockIndex < mUniformBlocks.size()); - return mUniformBlocks[blockIndex]; + return mProgram->getUniformBlockByIndex(blockIndex); } GLint ProgramBinary::getFragDataLocation(const char *name) const @@ -517,524 +191,129 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const size_t ProgramBinary::getTransformFeedbackVaryingCount() const { - return mTransformFeedbackLinkedVaryings.size(); + return mProgram->getTransformFeedbackLinkedVaryings().size(); } const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const { - return mTransformFeedbackLinkedVaryings[idx]; + return mProgram->getTransformFeedbackLinkedVaryings()[idx]; } GLenum ProgramBinary::getTransformFeedbackBufferMode() const { - return mTransformFeedbackBufferMode; + return mProgram->getTransformFeedbackBufferMode(); } -template -static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) -{ - ASSERT(dest != NULL); - ASSERT(dirtyFlag != NULL); - - *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); - *dest = source; +void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform1fv(location, count, v); } -template -void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType) -{ - const int components = VariableComponentCount(targetUniformType); - const GLenum targetBoolType = VariableBoolVectorType(targetUniformType); - - LinkedUniform *targetUniform = getUniformByLocation(location); - - int elementCount = targetUniform->elementCount(); - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - - if (targetUniform->type == targetUniformType) - { - T *target = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - T *dest = target + (i * 4); - const T *source = v + (i * components); - - for (int c = 0; c < components; c++) - { - SetIfDirty(dest + c, source[c], &targetUniform->dirty); - } - for (int c = components; c < 4; c++) - { - SetIfDirty(dest + c, T(0), &targetUniform->dirty); - } - } - } - else if (targetUniform->type == targetBoolType) - { - GLint *boolParams = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; - - for (int i = 0; i < count; i++) - { - GLint *dest = boolParams + (i * 4); - const T *source = v + (i * components); - - for (int c = 0; c < components; c++) - { - SetIfDirty(dest + c, (source[c] == static_cast(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); - } - for (int c = components; c < 4; c++) - { - SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty); - } - } - } - else if (IsSampler(targetUniform->type)) - { - ASSERT(targetUniformType == GL_INT); - - GLint *target = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; - - bool wasDirty = targetUniform->dirty; - - for (int i = 0; i < count; i++) - { - GLint *dest = target + (i * 4); - const GLint *source = reinterpret_cast(v) + (i * components); - - SetIfDirty(dest + 0, source[0], &targetUniform->dirty); - SetIfDirty(dest + 1, 0, &targetUniform->dirty); - SetIfDirty(dest + 2, 0, &targetUniform->dirty); - SetIfDirty(dest + 3, 0, &targetUniform->dirty); - } - - if (!wasDirty && targetUniform->dirty) - { - mDirtySamplerMapping = true; - } - } - else UNREACHABLE(); +void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform2fv(location, count, v); } -void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) -{ - setUniform(location, count, v, GL_FLOAT); +void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform3fv(location, count, v); } -void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) -{ - setUniform(location, count, v, GL_FLOAT_VEC2); +void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) { + mProgram->setUniform4fv(location, count, v); } -void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) -{ - setUniform(location, count, v, GL_FLOAT_VEC3); +void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform1iv(location, count, v); } -void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) -{ - setUniform(location, count, v, GL_FLOAT_VEC4); +void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform2iv(location, count, v); } -template -bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) -{ - bool dirty = false; - int copyWidth = std::min(targetHeight, srcWidth); - int copyHeight = std::min(targetWidth, srcHeight); - - for (int x = 0; x < copyWidth; x++) - { - for (int y = 0; y < copyHeight; y++) - { - SetIfDirty(target + (x * targetWidth + y), static_cast(value[y * srcWidth + x]), &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyWidth; y++) - { - for (int x = copyHeight; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyWidth; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - - return dirty; +void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform3iv(location, count, v); } -template -bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) -{ - bool dirty = false; - int copyWidth = std::min(targetWidth, srcWidth); - int copyHeight = std::min(targetHeight, srcHeight); - - for (int y = 0; y < copyHeight; y++) - { - for (int x = 0; x < copyWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(value[y * srcWidth + x]), &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyHeight; y++) - { - for (int x = copyWidth; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyHeight; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - - return dirty; +void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) { + mProgram->setUniform4iv(location, count, v); } -template -void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType) -{ - LinkedUniform *targetUniform = getUniformByLocation(location); - - int elementCount = targetUniform->elementCount(); - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); - const unsigned int targetMatrixStride = (4 * rows); - GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride); - - for (int i = 0; i < count; i++) - { - // Internally store matrices as transposed versions to accomodate HLSL matrix indexing - if (transpose == GL_FALSE) - { - targetUniform->dirty = transposeMatrix(target, value, 4, rows, rows, cols) || targetUniform->dirty; - } - else - { - targetUniform->dirty = expandMatrix(target, value, 4, rows, cols, rows) || targetUniform->dirty; - } - target += targetMatrixStride; - value += cols * rows; - } +void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform1uiv(location, count, v); } -void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); +void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform2uiv(location, count, v); } -void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); +void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform3uiv(location, count, v); } -void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); +void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) { + mProgram->setUniform4uiv(location, count, v); } -void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); +void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix2fv(location, count, transpose, v); } -void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); +void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix3fv(location, count, transpose, v); } -void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); +void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix4fv(location, count, transpose, v); } -void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); +void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix2x3fv(location, count, transpose, v); } -void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); +void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix2x4fv(location, count, transpose, v); } -void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); +void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix3x2fv(location, count, transpose, v); } -void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT); +void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix3x4fv(location, count, transpose, v); } -void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT_VEC2); +void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix4x2fv(location, count, transpose, v); } -void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT_VEC3); +void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + mProgram->setUniformMatrix4x3fv(location, count, transpose, v); } -void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) -{ - setUniform(location, count, v, GL_INT_VEC4); +void ProgramBinary::getUniformfv(GLint location, GLfloat *v) { + mProgram->getUniformfv(location, v); } -void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT); +void ProgramBinary::getUniformiv(GLint location, GLint *v) { + mProgram->getUniformiv(location, v); } -void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT_VEC2); -} - -void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT_VEC3); -} - -void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) -{ - setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); -} - -template -void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType) -{ - LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - if (IsMatrixType(targetUniform->type)) - { - const int rows = VariableRowCount(targetUniform->type); - const int cols = VariableColumnCount(targetUniform->type); - transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows); - } - else if (uniformType == VariableComponentType(targetUniform->type)) - { - unsigned int size = VariableComponentCount(targetUniform->type); - memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T), - size * sizeof(T)); - } - else - { - unsigned int size = VariableComponentCount(targetUniform->type); - switch (VariableComponentType(targetUniform->type)) - { - case GL_BOOL: - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = (boolParams[i] == GL_FALSE) ? static_cast(0) : static_cast(1); - } - } - break; - - case GL_FLOAT: - { - GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast(floatParams[i]); - } - } - break; - - case GL_INT: - { - GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast(intParams[i]); - } - } - break; - - case GL_UNSIGNED_INT: - { - GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast(uintParams[i]); - } - } - break; - - default: UNREACHABLE(); - } - } -} - -void ProgramBinary::getUniformfv(GLint location, GLfloat *params) -{ - getUniformv(location, params, GL_FLOAT); -} - -void ProgramBinary::getUniformiv(GLint location, GLint *params) -{ - getUniformv(location, params, GL_INT); -} - -void ProgramBinary::getUniformuiv(GLint location, GLuint *params) -{ - getUniformv(location, params, GL_UNSIGNED_INT); -} - -void ProgramBinary::dirtyAllUniforms() -{ - unsigned int numUniforms = mUniforms.size(); - for (unsigned int index = 0; index < numUniforms; index++) - { - mUniforms[index]->dirty = true; - } +void ProgramBinary::getUniformuiv(GLint location, GLuint *v) { + mProgram->getUniformuiv(location, v); } void ProgramBinary::updateSamplerMapping() { - if (!mDirtySamplerMapping) - { - return; - } - - mDirtySamplerMapping = false; - - // Retrieve sampler uniform values - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - LinkedUniform *targetUniform = mUniforms[uniformIndex]; - - if (targetUniform->dirty) - { - if (IsSampler(targetUniform->type)) - { - int count = targetUniform->elementCount(); - GLint (*v)[4] = reinterpret_cast(targetUniform->data); - - if (targetUniform->isReferencedByFragmentShader()) - { - unsigned int firstIndex = targetUniform->psRegisterIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < mSamplersPS.size()) - { - ASSERT(mSamplersPS[samplerIndex].active); - mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; - } - } - } - - if (targetUniform->isReferencedByVertexShader()) - { - unsigned int firstIndex = targetUniform->vsRegisterIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < mSamplersVS.size()) - { - ASSERT(mSamplersVS[samplerIndex].active); - mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; - } - } - } - } - } - } + return mProgram->updateSamplerMapping(); } // Applies all the uniforms set for this program object to the renderer Error ProgramBinary::applyUniforms() { - updateSamplerMapping(); - - Error error = mProgram->getRenderer()->applyUniforms(*this); - if (error.isError()) - { - return error; - } - - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - mUniforms[uniformIndex]->dirty = false; - } - - return gl::Error(GL_NO_ERROR); + return mProgram->applyUniforms(); } Error ProgramBinary::applyUniformBuffers(const std::vector boundBuffers, const Caps &caps) { - const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL}; - const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL}; - - const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers(); - const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers(); - - ASSERT(boundBuffers.size() == mUniformBlocks.size()); - - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++) - { - UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex); - gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex]; - - ASSERT(uniformBlock && uniformBuffer); - - if (uniformBuffer->getSize() < uniformBlock->dataSize) - { - // undefined behaviour - return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."); - } - - // Unnecessary to apply an unreferenced standard or shared UBO - if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader()) - { - continue; - } - - if (uniformBlock->isReferencedByVertexShader()) - { - unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS; - ASSERT(vertexUniformBuffers[registerIndex] == NULL); - ASSERT(registerIndex < caps.maxVertexUniformBlocks); - vertexUniformBuffers[registerIndex] = uniformBuffer; - } - - if (uniformBlock->isReferencedByFragmentShader()) - { - unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS; - ASSERT(fragmentUniformBuffers[registerIndex] == NULL); - ASSERT(registerIndex < caps.maxFragmentUniformBlocks); - fragmentUniformBuffers[registerIndex] = uniformBuffer; - } - } - - return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers); + return mProgram->applyUniformBuffers(boundBuffers, caps); } bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader) @@ -1082,10 +361,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade return true; } -bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length) +LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length) { -#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD - return false; +#if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_DISABLED + return LinkResult(false, Error(GL_NO_ERROR)); #else ASSERT(binaryFormat == mProgram->getBinaryFormat()); @@ -1097,7 +376,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina if (format != mProgram->getBinaryFormat()) { infoLog.append("Invalid program binary format."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } int majorVersion = stream.readInt(); @@ -1105,7 +384,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION) { infoLog.append("Invalid program binary version."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } unsigned char commitString[ANGLE_COMMIT_HASH_SIZE]; @@ -1113,250 +392,38 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0) { infoLog.append("Invalid program binary version."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } int compileFlags = stream.readInt(); if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) { infoLog.append("Mismatched compilation flags."); - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) { stream.readInt(&mLinkedAttribute[i].type); stream.readString(&mLinkedAttribute[i].name); - stream.readInt(&mShaderAttributes[i].type); - stream.readString(&mShaderAttributes[i].name); + stream.readInt(&mProgram->getShaderAttributes()[i].type); + stream.readString(&mProgram->getShaderAttributes()[i].name); stream.readInt(&mSemanticIndex[i]); } initAttributesByLayout(); - const unsigned int psSamplerCount = stream.readInt(); - for (unsigned int i = 0; i < psSamplerCount; ++i) + LinkResult result = mProgram->load(infoLog, &stream); + if (result.error.isError() || !result.linkSuccess) { - Sampler sampler; - stream.readBool(&sampler.active); - stream.readInt(&sampler.logicalTextureUnit); - stream.readInt(&sampler.textureType); - mSamplersPS.push_back(sampler); - } - const unsigned int vsSamplerCount = stream.readInt(); - for (unsigned int i = 0; i < vsSamplerCount; ++i) - { - Sampler sampler; - stream.readBool(&sampler.active); - stream.readInt(&sampler.logicalTextureUnit); - stream.readInt(&sampler.textureType); - mSamplersVS.push_back(sampler); + return result; } - stream.readInt(&mUsedVertexSamplerRange); - stream.readInt(&mUsedPixelSamplerRange); - stream.readBool(&mUsesPointSize); - stream.readInt(&mShaderVersion); - - const unsigned int uniformCount = stream.readInt(); - if (stream.error()) - { - infoLog.append("Invalid program binary."); - return false; - } - - mUniforms.resize(uniformCount); - for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) - { - GLenum type = stream.readInt(); - GLenum precision = stream.readInt(); - std::string name = stream.readString(); - unsigned int arraySize = stream.readInt(); - int blockIndex = stream.readInt(); - - int offset = stream.readInt(); - int arrayStride = stream.readInt(); - int matrixStride = stream.readInt(); - bool isRowMajorMatrix = stream.readBool(); - - const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix); - - LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo); - - stream.readInt(&uniform->psRegisterIndex); - stream.readInt(&uniform->vsRegisterIndex); - stream.readInt(&uniform->registerCount); - stream.readInt(&uniform->registerElement); - - mUniforms[uniformIndex] = uniform; - } - - unsigned int uniformBlockCount = stream.readInt(); - if (stream.error()) - { - infoLog.append("Invalid program binary."); - return false; - } - - mUniformBlocks.resize(uniformBlockCount); - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) - { - std::string name = stream.readString(); - unsigned int elementIndex = stream.readInt(); - unsigned int dataSize = stream.readInt(); - - UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize); - - stream.readInt(&uniformBlock->psRegisterIndex); - stream.readInt(&uniformBlock->vsRegisterIndex); - - unsigned int numMembers = stream.readInt(); - uniformBlock->memberUniformIndexes.resize(numMembers); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) - { - stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]); - } - - mUniformBlocks[uniformBlockIndex] = uniformBlock; - } - - const unsigned int uniformIndexCount = stream.readInt(); - if (stream.error()) - { - infoLog.append("Invalid program binary."); - return false; - } - - mUniformIndex.resize(uniformIndexCount); - for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) - { - stream.readString(&mUniformIndex[uniformIndexIndex].name); - stream.readInt(&mUniformIndex[uniformIndexIndex].element); - stream.readInt(&mUniformIndex[uniformIndexIndex].index); - } - - stream.readInt(&mTransformFeedbackBufferMode); - const unsigned int transformFeedbackVaryingCount = stream.readInt(); - mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount); - for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++) - { - LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex]; - - stream.readString(&varying.name); - stream.readInt(&varying.type); - stream.readInt(&varying.size); - stream.readString(&varying.semanticName); - stream.readInt(&varying.semanticIndex); - stream.readInt(&varying.semanticIndexCount); - } - - const unsigned int vertexShaderCount = stream.readInt(); - for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) - { - VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]; - - for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++) - { - VertexFormat *vertexInput = &inputLayout[inputIndex]; - stream.readInt(&vertexInput->mType); - stream.readInt(&vertexInput->mNormalized); - stream.readInt(&vertexInput->mComponents); - stream.readBool(&vertexInput->mPureInteger); - } - - unsigned int vertexShaderSize = stream.readInt(); - const unsigned char *vertexShaderFunction = reinterpret_cast(binary) + stream.offset(); - rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast(vertexShaderFunction), - vertexShaderSize, rx::SHADER_VERTEX, - mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - if (!shaderExecutable) - { - infoLog.append("Could not create vertex shader."); - return false; - } - - // generated converted input layout - GLenum signature[MAX_VERTEX_ATTRIBS]; - mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature); - - // add new binary - mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable)); - - stream.skip(vertexShaderSize); - } - - const size_t pixelShaderCount = stream.readInt(); - for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++) - { - const size_t outputCount = stream.readInt(); - std::vector outputs(outputCount); - for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++) - { - stream.readInt(&outputs[outputIndex]); - } - - const size_t pixelShaderSize = stream.readInt(); - const unsigned char *pixelShaderFunction = reinterpret_cast(binary) + stream.offset(); - rx::Renderer *renderer = mProgram->getRenderer(); - rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize, - rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!shaderExecutable) - { - infoLog.append("Could not create pixel shader."); - return false; - } - - // add new binary - mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable)); - - stream.skip(pixelShaderSize); - } - - unsigned int geometryShaderSize = stream.readInt(); - - if (geometryShaderSize > 0) - { - const char *geometryShaderFunction = (const char*) binary + stream.offset(); - rx::Renderer *renderer = mProgram->getRenderer(); - mGeometryExecutable = renderer->loadExecutable(reinterpret_cast(geometryShaderFunction), - geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); - - if (!mGeometryExecutable) - { - infoLog.append("Could not create geometry shader."); - return false; - } - stream.skip(geometryShaderSize); - } - - if (!mProgram->load(infoLog, &stream)) - { - return false; - } - - const char *ptr = (const char*) binary + stream.offset(); - - const GUID *binaryIdentifier = (const GUID *) ptr; - ptr += sizeof(GUID); - - GUID identifier = mProgram->getRenderer()->getAdapterIdentifier(); - if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0) - { - infoLog.append("Invalid program binary."); - return false; - } - - mProgram->initializeUniformStorage(mUniforms); - - return true; -#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD + return LinkResult(true, Error(GL_NO_ERROR)); +#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED } -bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) +Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) { if (binaryFormat) { @@ -1375,168 +442,27 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL { stream.writeInt(mLinkedAttribute[i].type); stream.writeString(mLinkedAttribute[i].name); - stream.writeInt(mShaderAttributes[i].type); - stream.writeString(mShaderAttributes[i].name); + stream.writeInt(mProgram->getShaderAttributes()[i].type); + stream.writeString(mProgram->getShaderAttributes()[i].name); stream.writeInt(mSemanticIndex[i]); } - stream.writeInt(mSamplersPS.size()); - for (unsigned int i = 0; i < mSamplersPS.size(); ++i) - { - stream.writeInt(mSamplersPS[i].active); - stream.writeInt(mSamplersPS[i].logicalTextureUnit); - stream.writeInt(mSamplersPS[i].textureType); - } - - stream.writeInt(mSamplersVS.size()); - for (unsigned int i = 0; i < mSamplersVS.size(); ++i) - { - stream.writeInt(mSamplersVS[i].active); - stream.writeInt(mSamplersVS[i].logicalTextureUnit); - stream.writeInt(mSamplersVS[i].textureType); - } - - stream.writeInt(mUsedVertexSamplerRange); - stream.writeInt(mUsedPixelSamplerRange); - stream.writeInt(mUsesPointSize); - stream.writeInt(mShaderVersion); - - stream.writeInt(mUniforms.size()); - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex) - { - const LinkedUniform &uniform = *mUniforms[uniformIndex]; - - stream.writeInt(uniform.type); - stream.writeInt(uniform.precision); - stream.writeString(uniform.name); - stream.writeInt(uniform.arraySize); - stream.writeInt(uniform.blockIndex); - - stream.writeInt(uniform.blockInfo.offset); - stream.writeInt(uniform.blockInfo.arrayStride); - stream.writeInt(uniform.blockInfo.matrixStride); - stream.writeInt(uniform.blockInfo.isRowMajorMatrix); - - stream.writeInt(uniform.psRegisterIndex); - stream.writeInt(uniform.vsRegisterIndex); - stream.writeInt(uniform.registerCount); - stream.writeInt(uniform.registerElement); - } - - stream.writeInt(mUniformBlocks.size()); - for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex) - { - const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex]; - - stream.writeString(uniformBlock.name); - stream.writeInt(uniformBlock.elementIndex); - stream.writeInt(uniformBlock.dataSize); - - stream.writeInt(uniformBlock.memberUniformIndexes.size()); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) - { - stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]); - } - - stream.writeInt(uniformBlock.psRegisterIndex); - stream.writeInt(uniformBlock.vsRegisterIndex); - } - - stream.writeInt(mUniformIndex.size()); - for (size_t i = 0; i < mUniformIndex.size(); ++i) - { - stream.writeString(mUniformIndex[i].name); - stream.writeInt(mUniformIndex[i].element); - stream.writeInt(mUniformIndex[i].index); - } - - stream.writeInt(mTransformFeedbackBufferMode); - stream.writeInt(mTransformFeedbackLinkedVaryings.size()); - for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++) - { - const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i]; - - stream.writeString(varying.name); - stream.writeInt(varying.type); - stream.writeInt(varying.size); - stream.writeString(varying.semanticName); - stream.writeInt(varying.semanticIndex); - stream.writeInt(varying.semanticIndexCount); - } - - stream.writeInt(mVertexExecutables.size()); - for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) - { - VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; - - for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) - { - const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex]; - stream.writeInt(vertexInput.mType); - stream.writeInt(vertexInput.mNormalized); - stream.writeInt(vertexInput.mComponents); - stream.writeInt(vertexInput.mPureInteger); - } - - size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); - stream.writeInt(vertexShaderSize); - - const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction(); - stream.writeBytes(vertexBlob, vertexShaderSize); - } - - stream.writeInt(mPixelExecutables.size()); - for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++) - { - PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex]; - - const std::vector outputs = pixelExecutable->outputSignature(); - stream.writeInt(outputs.size()); - for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++) - { - stream.writeInt(outputs[outputIndex]); - } - - size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength(); - stream.writeInt(pixelShaderSize); - - const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction(); - stream.writeBytes(pixelBlob, pixelShaderSize); - } - - size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; - stream.writeInt(geometryShaderSize); - - if (mGeometryExecutable != NULL && geometryShaderSize > 0) - { - const uint8_t *geometryBlob = mGeometryExecutable->getFunction(); - stream.writeBytes(geometryBlob, geometryShaderSize); - } - - if (!mProgram->save(&stream)) - { - if (length) - { - *length = 0; - } - - return false; - } - - GUID identifier = mProgram->getRenderer()->getAdapterIdentifier(); + mProgram->save(&stream); GLsizei streamLength = stream.length(); const void *streamData = stream.data(); - GLsizei totalLength = streamLength + sizeof(GUID); - if (totalLength > bufSize) + if (streamLength > bufSize) { if (length) { *length = 0; } - return false; + // TODO: This should be moved to the validation layer but computing the size of the binary before saving + // it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate + // sizes and then copy it. + return Error(GL_INVALID_OPERATION); } if (binary) @@ -1546,129 +472,197 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL memcpy(ptr, streamData, streamLength); ptr += streamLength; - memcpy(ptr, &identifier, sizeof(GUID)); - ptr += sizeof(GUID); - - ASSERT(ptr - totalLength == binary); + ASSERT(ptr - streamLength == binary); } if (length) { - *length = totalLength; + *length = streamLength; } - return true; + return Error(GL_NO_ERROR); } GLint ProgramBinary::getLength() { GLint length; - if (save(NULL, NULL, INT_MAX, &length)) - { - return length; - } - else + Error error = save(NULL, NULL, INT_MAX, &length); + if (error.isError()) { return 0; } + + return length; } -bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader, - const std::vector& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps) +LinkResult ProgramBinary::link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings, + Shader *fragmentShader, Shader *vertexShader, + const std::vector &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode) { if (!fragmentShader || !fragmentShader->isCompiled()) { - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER); if (!vertexShader || !vertexShader->isCompiled()) { - return false; + return LinkResult(false, Error(GL_NO_ERROR)); } ASSERT(vertexShader->getType() == GL_VERTEX_SHADER); reset(); - mSamplersPS.resize(caps.maxTextureImageUnits); - mSamplersVS.resize(caps.maxVertexTextureImageUnits); - - mTransformFeedbackBufferMode = transformFeedbackBufferMode; - - rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); - rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); - - mShaderVersion = vertexShaderD3D->getShaderVersion(); - int registers; std::vector linkedVaryings; - if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, ®isters, &linkedVaryings, &mOutputVariables)) + LinkResult result = mProgram->link(data, infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode, + ®isters, &linkedVaryings, &mOutputVariables); + if (result.error.isError() || !result.linkSuccess) { - return false; + return result; } - mUsesPointSize = vertexShaderD3D->usesPointSize(); - - bool success = true; - if (!linkAttributes(infoLog, attributeBindings, vertexShader)) { - success = false; + return LinkResult(false, Error(GL_NO_ERROR)); } - if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps)) + if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, *data.caps)) { - success = false; + return LinkResult(false, Error(GL_NO_ERROR)); } - // special case for gl_DepthRange, the only built-in uniform (also a struct) - if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange()) + if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, *data.caps)) { - const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo(); - - mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo)); - mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo)); - mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo)); - } - - if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps)) - { - success = false; + return LinkResult(false, Error(GL_NO_ERROR)); } if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings, - transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps)) + transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps)) { - success = false; + return LinkResult(false, Error(GL_NO_ERROR)); } - if (success) + // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called, + // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling. + result = mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers); + if (result.error.isError() || !result.linkSuccess) { - VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS]; - GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout); - rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout); + infoLog.append("Failed to create D3D shaders."); + reset(); + return result; + } - std::vector defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey()); - rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput); + return LinkResult(true, Error(GL_NO_ERROR)); +} - if (usesGeometryShader()) +bool ProgramBinary::linkUniformBlocks(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps) +{ + const std::vector &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); + const std::vector &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); + + // Check that interface blocks defined in the vertex and fragment shaders are identical + typedef std::map UniformBlockMap; + UniformBlockMap linkedUniformBlocks; + + for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) + { + const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex]; + linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; + } + + for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) + { + const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex]; + UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); + if (entry != linkedUniformBlocks.end()) { - std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D); - mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(), - rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - rx::ANGLE_D3D_WORKAROUND_NONE); - } - - if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) - { - infoLog.append("Failed to create D3D shaders."); - success = false; - reset(); + const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; + if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) + { + return false; + } } } - return success; + for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) + { + const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex]; + + // Note: shared and std140 layouts are always considered active + if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) + { + if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps)) + { + return false; + } + } + } + + for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) + { + const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex]; + + // Note: shared and std140 layouts are always considered active + if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) + { + if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps)) + { + return false; + } + } + } + + return true; +} + +bool ProgramBinary::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock) +{ + const char* blockName = vertexInterfaceBlock.name.c_str(); + + // validate blocks for the same member types + if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size()) + { + infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName); + return false; + } + + if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize) + { + infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName); + return false; + } + + if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) + { + infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); + return false; + } + + const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size(); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) + { + const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; + const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex]; + + if (vertexMember.name != fragmentMember.name) + { + infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", + blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str()); + return false; + } + + std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; + if (!gl::ProgramBinary::linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember)) + { + return false; + } + } + + return true; } // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices @@ -1688,7 +682,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; - mShaderAttributes[attributeIndex] = attribute; + mProgram->getShaderAttributes()[attributeIndex] = attribute; if (location != -1) // Set by glBindAttribLocation or by location layout qualifier { @@ -1708,7 +702,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at // In GLSL 3.00, attribute aliasing produces a link error // In GLSL 1.00, attribute aliasing is allowed - if (mShaderVersion >= 300) + if (mProgram->getShaderVersion() >= 300) { if (!linkedAttribute.name.empty()) { @@ -1856,346 +850,6 @@ bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std return true; } -bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) -{ - const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation()); - const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation()); - - const std::vector &vertexUniforms = vertexShader.getUniforms(); - const std::vector &fragmentUniforms = fragmentShader.getUniforms(); - - // Check that uniforms defined in the vertex and fragment shaders are identical - typedef std::map UniformMap; - UniformMap linkedUniforms; - - for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++) - { - const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex]; - linkedUniforms[vertexUniform.name] = &vertexUniform; - } - - for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++) - { - const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex]; - UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name); - if (entry != linkedUniforms.end()) - { - const sh::Uniform &vertexUniform = *entry->second; - const std::string &uniformName = "uniform '" + vertexUniform.name + "'"; - if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform)) - { - return false; - } - } - } - - for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) - { - const sh::Uniform &uniform = vertexUniforms[uniformIndex]; - - if (uniform.staticUse) - { - defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name)); - } - } - - for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) - { - const sh::Uniform &uniform = fragmentUniforms[uniformIndex]; - - if (uniform.staticUse) - { - defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name)); - } - } - - if (!indexUniforms(infoLog, caps)) - { - return false; - } - - mProgram->initializeUniformStorage(mUniforms); - - return true; -} - -void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister) -{ - ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader); - sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); - encoder.skipRegisters(uniformRegister); - - defineUniform(shader, uniform, uniform.name, &encoder); -} - -void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform, - const std::string &fullName, sh::HLSLBlockEncoder *encoder) -{ - if (uniform.isStruct()) - { - for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) - { - const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); - - encoder->enterAggregateType(); - - for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) - { - const sh::ShaderVariable &field = uniform.fields[fieldIndex]; - const std::string &fieldFullName = (fullName + elementString + "." + field.name); - - defineUniform(shader, field, fieldFullName, encoder); - } - - encoder->exitAggregateType(); - } - } - else // Not a struct - { - // Arrays are treated as aggregate types - if (uniform.isArray()) - { - encoder->enterAggregateType(); - } - - LinkedUniform *linkedUniform = getUniformByName(fullName); - - if (!linkedUniform) - { - linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, - -1, sh::BlockMemberInfo::getDefaultBlockInfo()); - ASSERT(linkedUniform); - linkedUniform->registerElement = encoder->getCurrentElement(); - mUniforms.push_back(linkedUniform); - } - - ASSERT(linkedUniform->registerElement == encoder->getCurrentElement()); - - if (shader == GL_FRAGMENT_SHADER) - { - linkedUniform->psRegisterIndex = encoder->getCurrentRegister(); - } - else if (shader == GL_VERTEX_SHADER) - { - linkedUniform->vsRegisterIndex = encoder->getCurrentRegister(); - } - else UNREACHABLE(); - - // Advance the uniform offset, to track registers allocation for structs - encoder->encodeType(uniform.type, uniform.arraySize, false); - - // Arrays are treated as aggregate types - if (uniform.isArray()) - { - encoder->exitAggregateType(); - } - } -} - -bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps) -{ - ASSERT(IsSampler(uniform.type)); - ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX); - - if (uniform.vsRegisterIndex != GL_INVALID_INDEX) - { - if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS, - &mUsedVertexSamplerRange)) - { - infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", - mSamplersVS.size()); - return false; - } - - unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors; - if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors) - { - infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", - caps.maxVertexUniformVectors); - return false; - } - } - - if (uniform.psRegisterIndex != GL_INVALID_INDEX) - { - if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS, - &mUsedPixelSamplerRange)) - { - infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", - mSamplersPS.size()); - return false; - } - - unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors; - if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors) - { - infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", - caps.maxFragmentUniformVectors); - return false; - } - } - - return true; -} - -bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps) -{ - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - const LinkedUniform &uniform = *mUniforms[uniformIndex]; - - if (IsSampler(uniform.type)) - { - if (!indexSamplerUniform(uniform, infoLog, caps)) - { - return false; - } - } - - for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++) - { - mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex)); - } - } - - return true; -} - -bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex, - GLenum samplerType, - unsigned int samplerCount, - std::vector &outSamplers, - GLuint *outUsedRange) -{ - unsigned int samplerIndex = startSamplerIndex; - - do - { - if (samplerIndex < outSamplers.size()) - { - Sampler& sampler = outSamplers[samplerIndex]; - sampler.active = true; - sampler.textureType = GetTextureType(samplerType); - sampler.logicalTextureUnit = 0; - *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); - } - else - { - return false; - } - - samplerIndex++; - } while (samplerIndex < startSamplerIndex + samplerCount); - - return true; -} - -bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock) -{ - const char* blockName = vertexInterfaceBlock.name.c_str(); - - // validate blocks for the same member types - if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size()) - { - infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName); - return false; - } - - if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize) - { - infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName); - return false; - } - - if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) - { - infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); - return false; - } - - const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size(); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) - { - const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; - const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex]; - - if (vertexMember.name != fragmentMember.name) - { - infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", - blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str()); - return false; - } - - std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; - if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember)) - { - return false; - } - } - - return true; -} - -bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) -{ - const std::vector &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); - const std::vector &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); - - // Check that interface blocks defined in the vertex and fragment shaders are identical - typedef std::map UniformBlockMap; - UniformBlockMap linkedUniformBlocks; - - for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex]; - linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; - } - - for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex]; - UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); - if (entry != linkedUniformBlocks.end()) - { - const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; - if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) - { - return false; - } - } - } - - for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex]; - - // Note: shared and std140 layouts are always considered active - if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) - { - if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps)) - { - return false; - } - } - } - - for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex]; - - // Note: shared and std140 layouts are always considered active - if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) - { - if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps)) - { - return false; - } - } - } - - return true; -} - bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector &linkedVaryings, const std::vector &transformFeedbackVaryingNames, GLenum transformFeedbackBufferMode, @@ -2253,142 +907,6 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons return true; } -template -void ProgramBinary::defineUniformBlockMembers(const std::vector &fields, const std::string &prefix, int blockIndex, - sh::BlockLayoutEncoder *encoder, std::vector *blockUniformIndexes, - bool inRowMajorLayout) -{ - for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++) - { - const VarT &field = fields[uniformIndex]; - const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); - - if (field.isStruct()) - { - bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); - - for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) - { - encoder->enterAggregateType(); - - const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); - defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout); - - encoder->exitAggregateType(); - } - } - else - { - bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout); - - sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); - - LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize, - blockIndex, memberInfo); - - // add to uniform list, but not index, since uniform block uniforms have no location - blockUniformIndexes->push_back(mUniforms.size()); - mUniforms.push_back(newUniform); - } - } -} - -bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps) -{ - const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation()); - - // create uniform block entries if they do not exist - if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX) - { - std::vector blockUniformIndexes; - const unsigned int blockIndex = mUniformBlocks.size(); - - // define member uniforms - sh::BlockLayoutEncoder *encoder = NULL; - - if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) - { - encoder = new sh::Std140BlockEncoder; - } - else - { - encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); - } - ASSERT(encoder); - - defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout); - - size_t dataSize = encoder->getBlockSize(); - - // create all the uniform blocks - if (interfaceBlock.arraySize > 0) - { - for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++) - { - UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize); - newUniformBlock->memberUniformIndexes = blockUniformIndexes; - mUniformBlocks.push_back(newUniformBlock); - } - } - else - { - UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize); - newUniformBlock->memberUniformIndexes = blockUniformIndexes; - mUniformBlocks.push_back(newUniformBlock); - } - } - - if (interfaceBlock.staticUse) - { - // Assign registers to the uniform blocks - const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name); - const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize); - ASSERT(blockIndex != GL_INVALID_INDEX); - ASSERT(blockIndex + elementCount <= mUniformBlocks.size()); - - unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name); - - for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++) - { - UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; - ASSERT(uniformBlock->name == interfaceBlock.name); - - if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(), - interfaceBlockRegister + uniformBlockElement, caps)) - { - return false; - } - } - } - - return true; -} - -bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps) -{ - if (shader == GL_VERTEX_SHADER) - { - uniformBlock->vsRegisterIndex = registerIndex; - if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks) - { - infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks); - return false; - } - } - else if (shader == GL_FRAGMENT_SHADER) - { - uniformBlock->psRegisterIndex = registerIndex; - if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks) - { - infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks); - return false; - } - } - else UNREACHABLE(); - - return true; -} - bool ProgramBinary::isValidated() const { return mValidated; @@ -2464,13 +982,13 @@ GLint ProgramBinary::getActiveAttributeMaxLength() const void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const { - ASSERT(index < mUniforms.size()); // index must be smaller than getActiveUniformCount() + ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount() if (bufsize > 0) { - std::string string = mUniforms[index]->name; + std::string string = mProgram->getUniforms()[index]->name; - if (mUniforms[index]->isArray()) + if (mProgram->getUniforms()[index]->isArray()) { string += "[0]"; } @@ -2484,27 +1002,27 @@ void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *len } } - *size = mUniforms[index]->elementCount(); + *size = mProgram->getUniforms()[index]->elementCount(); - *type = mUniforms[index]->type; + *type = mProgram->getUniforms()[index]->type; } GLint ProgramBinary::getActiveUniformCount() const { - return mUniforms.size(); + return mProgram->getUniforms().size(); } GLint ProgramBinary::getActiveUniformMaxLength() const { int maxLength = 0; - unsigned int numUniforms = mUniforms.size(); + unsigned int numUniforms = mProgram->getUniforms().size(); for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) { - if (!mUniforms[uniformIndex]->name.empty()) + if (!mProgram->getUniforms()[uniformIndex]->name.empty()) { - int length = (int)(mUniforms[uniformIndex]->name.length() + 1); - if (mUniforms[uniformIndex]->isArray()) + int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1); + if (mProgram->getUniforms()[uniformIndex]->isArray()) { length += 3; // Counting in "[0]". } @@ -2517,7 +1035,7 @@ GLint ProgramBinary::getActiveUniformMaxLength() const GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const { - const gl::LinkedUniform& uniform = *mUniforms[index]; + const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index]; switch (pname) { @@ -2540,34 +1058,25 @@ GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const bool ProgramBinary::isValidUniformLocation(GLint location) const { - ASSERT(rx::IsIntegerCastSafe(mUniformIndex.size())); - return (location >= 0 && location < static_cast(mUniformIndex.size())); + ASSERT(rx::IsIntegerCastSafe(mProgram->getUniformIndices().size())); + return (location >= 0 && location < static_cast(mProgram->getUniformIndices().size())); } LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const { - ASSERT(location >= 0 && static_cast(location) < mUniformIndex.size()); - return mUniforms[mUniformIndex[location].index]; + return mProgram->getUniformByLocation(location); } LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const { - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - if (mUniforms[uniformIndex]->name == name) - { - return mUniforms[uniformIndex]; - } - } - - return NULL; + return mProgram->getUniformByName(name); } void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const { - ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() + ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount() - const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; if (bufSize > 0) { @@ -2590,9 +1099,9 @@ void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const { - ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() + ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount() - const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; switch (pname) { @@ -2625,17 +1134,17 @@ void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pna GLuint ProgramBinary::getActiveUniformBlockCount() const { - return mUniformBlocks.size(); + return mProgram->getUniformBlocks().size(); } GLuint ProgramBinary::getActiveUniformBlockMaxLength() const { unsigned int maxLength = 0; - unsigned int numUniformBlocks = mUniformBlocks.size(); + unsigned int numUniformBlocks = mProgram->getUniformBlocks().size(); for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) { - const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; + const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; if (!uniformBlock.name.empty()) { const unsigned int length = uniformBlock.name.length() + 1; @@ -2665,88 +1174,7 @@ void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps) bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps) { - // if any two active samplers in a program are of different types, but refer to the same - // texture image unit, and this is the current program, then ValidateProgram will fail, and - // DrawArrays and DrawElements will issue the INVALID_OPERATION error. - updateSamplerMapping(); - - std::vector textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE); - - for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) - { - if (mSamplersPS[i].active) - { - unsigned int unit = mSamplersPS[i].logicalTextureUnit; - - if (unit >= textureUnitTypes.size()) - { - if (infoLog) - { - infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); - } - - return false; - } - - if (textureUnitTypes[unit] != GL_NONE) - { - if (mSamplersPS[i].textureType != textureUnitTypes[unit]) - { - if (infoLog) - { - infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - return false; - } - } - else - { - textureUnitTypes[unit] = mSamplersPS[i].textureType; - } - } - } - - for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) - { - if (mSamplersVS[i].active) - { - unsigned int unit = mSamplersVS[i].logicalTextureUnit; - - if (unit >= textureUnitTypes.size()) - { - if (infoLog) - { - infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); - } - - return false; - } - - if (textureUnitTypes[unit] != GL_NONE) - { - if (mSamplersVS[i].textureType != textureUnitTypes[unit]) - { - if (infoLog) - { - infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - return false; - } - } - else - { - textureUnitTypes[unit] = mSamplersVS[i].textureType; - } - } - } - - return true; -} - -ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D) -{ + return mProgram->validateSamplers(infoLog, caps); } struct AttributeSorter @@ -2795,26 +1223,6 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA void ProgramBinary::reset() { - SafeDeleteContainer(mVertexExecutables); - SafeDeleteContainer(mPixelExecutables); - - SafeDelete(mGeometryExecutable); - - mTransformFeedbackBufferMode = GL_NONE; - mTransformFeedbackLinkedVaryings.clear(); - - mSamplersPS.clear(); - mSamplersVS.clear(); - - mUsedVertexSamplerRange = 0; - mUsedPixelSamplerRange = 0; - mUsesPointSize = false; - mShaderVersion = 0; - mDirtySamplerMapping = true; - - SafeDeleteContainer(mUniforms); - SafeDeleteContainer(mUniformBlocks); - mUniformIndex.clear(); mOutputVariables.clear(); mProgram->reset(); diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h index ad470d417b..3142d66c6d 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h @@ -24,11 +24,6 @@ #include #include -// TODO(jmadill): place this in workarounds library -#define ANGLE_WORKAROUND_ENABLED 1 -#define ANGLE_WORKAROUND_DISABLED 2 -#define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED - namespace sh { class HLSLBlockEncoder; @@ -44,7 +39,6 @@ class HLSLBlockEncoder; namespace rx { class ShaderExecutable; -class Renderer; struct TranslatedAttribute; class UniformStorage; class ProgramImpl; @@ -58,6 +52,7 @@ class InfoLog; class AttributeBindings; class Buffer; class Framebuffer; +struct Data; // Struct used for correlating uniforms/elements of uniform arrays to handles struct VariableLocation @@ -91,6 +86,14 @@ struct LinkedVarying unsigned int semanticIndexCount; }; +struct LinkResult +{ + bool linkSuccess; + Error error; + + LinkResult(bool linkSuccess, const Error &error); +}; + // This is the result of linking a program. It is the state that would be passed to ProgramBinary. class ProgramBinary : public RefCountObject { @@ -101,11 +104,6 @@ class ProgramBinary : public RefCountObject rx::ProgramImpl *getImplementation() { return mProgram; } const rx::ProgramImpl *getImplementation() const { return mProgram; } - rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo); - rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector &outputLayout); - rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]); - rx::ShaderExecutable *getGeometryExecutable() const; - GLuint getAttributeLocation(const char *name); int getSemanticIndex(int attributeIndex); @@ -113,8 +111,6 @@ class ProgramBinary : public RefCountObject GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex); GLint getUsedSamplerRange(SamplerType type); bool usesPointSize() const; - bool usesPointSpriteEmulation() const; - bool usesGeometryShader() const; GLint getUniformLocation(std::string name); GLuint getUniformIndex(std::string name); @@ -145,18 +141,17 @@ class ProgramBinary : public RefCountObject void getUniformiv(GLint location, GLint *params); void getUniformuiv(GLint location, GLuint *params); - void dirtyAllUniforms(); - Error applyUniforms(); Error applyUniformBuffers(const std::vector boundBuffers, const Caps &caps); - bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length); - bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length); + LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length); + Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length); GLint getLength(); - bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader, - const std::vector& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps); - void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); + LinkResult link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings, + Shader *fragmentShader, Shader *vertexShader, + const std::vector &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode); void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; GLint getActiveAttributeCount() const; @@ -188,30 +183,23 @@ class ProgramBinary : public RefCountObject void updateSamplerMapping(); unsigned int getSerial() const; - int getShaderVersion() const; void initAttributesByLayout(); void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const; - const std::vector &getUniforms() const { return mUniforms; } - static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader); + static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); + static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); private: DISALLOW_COPY_AND_ASSIGN(ProgramBinary); - struct Sampler - { - Sampler(); - - bool active; - GLint logicalTextureUnit; - GLenum textureType; - }; - void reset(); bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader); + bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); + bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock); static bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, @@ -219,102 +207,21 @@ class ProgramBinary : public RefCountObject const sh::ShaderVariable &fragmentVariable, bool validatePrecision); - static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying); - static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); - bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); - void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister); - void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder); - bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps); - bool indexUniforms(InfoLog &infoLog, const Caps &caps); - static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, - std::vector &outSamplers, GLuint *outUsedRange); - bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock); - bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector &linkedVaryings, const std::vector &transformFeedbackVaryingNames, GLenum transformFeedbackBufferMode, std::vector *outTransformFeedbackLinkedVaryings, const Caps &caps) const; - template - void defineUniformBlockMembers(const std::vector &fields, const std::string &prefix, int blockIndex, - sh::BlockLayoutEncoder *encoder, std::vector *blockUniformIndexes, - bool inRowMajorLayout); - bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps); bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps); void defineOutputVariables(Shader *fragmentShader); - template - void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); - - template - void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); - - template - void getUniformv(GLint location, T *params, GLenum uniformType); - - class VertexExecutable - { - public: - VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS], - const GLenum signature[MAX_VERTEX_ATTRIBS], - rx::ShaderExecutable *shaderExecutable); - ~VertexExecutable(); - - bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const; - - const VertexFormat *inputs() const { return mInputs; } - const GLenum *signature() const { return mSignature; } - rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } - - private: - VertexFormat mInputs[MAX_VERTEX_ATTRIBS]; - GLenum mSignature[MAX_VERTEX_ATTRIBS]; - rx::ShaderExecutable *mShaderExecutable; - }; - - class PixelExecutable - { - public: - PixelExecutable(const std::vector &outputSignature, rx::ShaderExecutable *shaderExecutable); - ~PixelExecutable(); - - bool matchesSignature(const std::vector &signature) const { return mOutputSignature == signature; } - - const std::vector &outputSignature() const { return mOutputSignature; } - rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } - - private: - std::vector mOutputSignature; - rx::ShaderExecutable *mShaderExecutable; - }; - rx::ProgramImpl *mProgram; - std::vector mVertexExecutables; - std::vector mPixelExecutables; - - rx::ShaderExecutable *mGeometryExecutable; - sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; - sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS]; int mAttributesByLayout[MAX_VERTEX_ATTRIBS]; - GLenum mTransformFeedbackBufferMode; - std::vector mTransformFeedbackLinkedVaryings; - - std::vector mSamplersPS; - std::vector mSamplersVS; - GLuint mUsedVertexSamplerRange; - GLuint mUsedPixelSamplerRange; - bool mUsesPointSize; - int mShaderVersion; - bool mDirtySamplerMapping; - - std::vector mUniforms; - std::vector mUniformBlocks; - std::vector mUniformIndex; std::map mOutputVariables; bool mValidated; diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp index 9406fce58d..911a389dfa 100644 --- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp @@ -4,77 +4,86 @@ // found in the LICENSE file. // -// Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes -// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer -// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. +// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class, +// GL renderbuffer objects and related functionality. +// [OpenGL ES 2.0.24] section 4.4.3 page 108. #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Texture.h" #include "libGLESv2/formatutils.h" #include "libGLESv2/FramebufferAttachment.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/RenderTarget.h" +#include "libGLESv2/renderer/RenderbufferImpl.h" #include "common/utilities.h" namespace gl { -unsigned int RenderbufferStorage::mCurrentSerial = 1; - -Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage) +Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id) : RefCountObject(id), - mStorage(newStorage) + mRenderbuffer(impl) { - ASSERT(mStorage); + ASSERT(mRenderbuffer); + + mWidth = mRenderbuffer->getWidth(); + mHeight = mRenderbuffer->getHeight(); + mInternalFormat = mRenderbuffer->getInternalFormat(); + mActualFormat = mRenderbuffer->getActualFormat(); + mSamples = mRenderbuffer->getSamples(); } Renderbuffer::~Renderbuffer() { - SafeDelete(mStorage); + SafeDelete(mRenderbuffer); } -void Renderbuffer::setStorage(RenderbufferStorage *newStorage) +Error Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) { - ASSERT(newStorage); + Error error = mRenderbuffer->setStorage(width, height, internalformat, samples); + if (error.isError()) + { + return error; + } - SafeDelete(mStorage); - mStorage = newStorage; + mWidth = width; + mHeight = height; + mInternalFormat = internalformat; + mSamples = samples; + mActualFormat = mRenderbuffer->getActualFormat(); + + return Error(GL_NO_ERROR); } -RenderbufferStorage *Renderbuffer::getStorage() +rx::RenderbufferImpl *Renderbuffer::getImplementation() { - ASSERT(mStorage); - return mStorage; + ASSERT(mRenderbuffer); + return mRenderbuffer; } GLsizei Renderbuffer::getWidth() const { - ASSERT(mStorage); - return mStorage->getWidth(); + return mWidth; } GLsizei Renderbuffer::getHeight() const { - ASSERT(mStorage); - return mStorage->getHeight(); + return mHeight; } GLenum Renderbuffer::getInternalFormat() const { - ASSERT(mStorage); - return mStorage->getInternalFormat(); + return mInternalFormat; } GLenum Renderbuffer::getActualFormat() const { - ASSERT(mStorage); - return mStorage->getActualFormat(); + return mActualFormat; } GLsizei Renderbuffer::getSamples() const { - ASSERT(mStorage); - return mStorage->getSamples(); + return mSamples; } GLuint Renderbuffer::getRedSize() const @@ -107,176 +116,4 @@ GLuint Renderbuffer::getStencilSize() const return GetInternalFormatInfo(getActualFormat()).stencilBits; } -RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1)) -{ - mWidth = 0; - mHeight = 0; - mInternalFormat = GL_RGBA4; - mActualFormat = GL_RGBA8_OES; - mSamples = 0; -} - -RenderbufferStorage::~RenderbufferStorage() -{ -} - -rx::RenderTarget *RenderbufferStorage::getRenderTarget() -{ - return NULL; -} - -GLsizei RenderbufferStorage::getWidth() const -{ - return mWidth; -} - -GLsizei RenderbufferStorage::getHeight() const -{ - return mHeight; -} - -GLenum RenderbufferStorage::getInternalFormat() const -{ - return mInternalFormat; -} - -GLenum RenderbufferStorage::getActualFormat() const -{ - return mActualFormat; -} - -GLsizei RenderbufferStorage::getSamples() const -{ - return mSamples; -} - -unsigned int RenderbufferStorage::getSerial() const -{ - return mSerial; -} - -unsigned int RenderbufferStorage::issueSerials(unsigned int count) -{ - unsigned int firstSerial = mCurrentSerial; - mCurrentSerial += count; - return firstSerial; -} - -bool RenderbufferStorage::isTexture() const -{ - return false; -} - -unsigned int RenderbufferStorage::getTextureSerial() const -{ - return -1; -} - -Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) -{ - mRenderTarget = renderer->createRenderTarget(swapChain, false); - - if (mRenderTarget) - { - mWidth = mRenderTarget->getWidth(); - mHeight = mRenderTarget->getHeight(); - mInternalFormat = mRenderTarget->getInternalFormat(); - mActualFormat = mRenderTarget->getActualFormat(); - mSamples = mRenderTarget->getSamples(); - } -} - -Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL) -{ - mRenderTarget = renderer->createRenderTarget(width, height, format, samples); - - if (mRenderTarget) - { - mWidth = width; - mHeight = height; - mInternalFormat = format; - mActualFormat = mRenderTarget->getActualFormat(); - mSamples = mRenderTarget->getSamples(); - } -} - -Colorbuffer::~Colorbuffer() -{ - if (mRenderTarget) - { - delete mRenderTarget; - } -} - -rx::RenderTarget *Colorbuffer::getRenderTarget() -{ - return mRenderTarget; -} - -DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) -{ - mDepthStencil = renderer->createRenderTarget(swapChain, true); - if (mDepthStencil) - { - mWidth = mDepthStencil->getWidth(); - mHeight = mDepthStencil->getHeight(); - mInternalFormat = mDepthStencil->getInternalFormat(); - mSamples = mDepthStencil->getSamples(); - mActualFormat = mDepthStencil->getActualFormat(); - } -} - -DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) -{ - - mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples); - - mWidth = mDepthStencil->getWidth(); - mHeight = mDepthStencil->getHeight(); - mInternalFormat = GL_DEPTH24_STENCIL8_OES; - mActualFormat = mDepthStencil->getActualFormat(); - mSamples = mDepthStencil->getSamples(); -} - -DepthStencilbuffer::~DepthStencilbuffer() -{ - if (mDepthStencil) - { - delete mDepthStencil; - } -} - -rx::RenderTarget *DepthStencilbuffer::getRenderTarget() -{ - return mDepthStencil; -} - -Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples) -{ - if (mDepthStencil) - { - mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage - } -} - -Depthbuffer::~Depthbuffer() -{ -} - -Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples) -{ - if (mDepthStencil) - { - mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage - } -} - -Stencilbuffer::~Stencilbuffer() -{ -} - } diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h index 71bcb0e1f8..e9f12af3ce 100644 --- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h @@ -4,30 +4,27 @@ // found in the LICENSE file. // -// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the -// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer, -// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer -// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. +// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer. +// Implements GL renderbuffer objects and related functionality. +// [OpenGL ES 2.0.24] section 4.4.3 page 108. #ifndef LIBGLESV2_RENDERBUFFER_H_ #define LIBGLESV2_RENDERBUFFER_H_ #include "angle_gl.h" +#include "libGLESv2/Error.h" + #include "common/angleutils.h" #include "common/RefCountObject.h" namespace rx { -class Renderer; -class SwapChain; -class RenderTarget; -class TextureStorage; +class RenderbufferImpl; } namespace gl { -class RenderbufferStorage; class FramebufferAttachment; // A GL renderbuffer object is usually used as a depth or stencil buffer attachment @@ -38,11 +35,12 @@ class FramebufferAttachment; class Renderbuffer : public RefCountObject { public: - Renderbuffer(GLuint id, RenderbufferStorage *newStorage); + Renderbuffer(rx::RenderbufferImpl *impl, GLuint id); virtual ~Renderbuffer(); - void setStorage(RenderbufferStorage *newStorage); - RenderbufferStorage *getStorage(); + Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples); + + rx::RenderbufferImpl *getImplementation(); GLsizei getWidth() const; GLsizei getHeight() const; @@ -57,102 +55,15 @@ class Renderbuffer : public RefCountObject GLuint getStencilSize() const; private: - RenderbufferStorage *mStorage; -}; + DISALLOW_COPY_AND_ASSIGN(Renderbuffer); -// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage -// is called. The specific concrete type depends on whether the internal format is -// colour depth, stencil or packed depth/stencil. -class RenderbufferStorage -{ - public: - RenderbufferStorage(); + rx::RenderbufferImpl *mRenderbuffer; - virtual ~RenderbufferStorage() = 0; - - virtual rx::RenderTarget *getRenderTarget(); - - virtual GLsizei getWidth() const; - virtual GLsizei getHeight() const; - virtual GLenum getInternalFormat() const; - virtual GLenum getActualFormat() const; - virtual GLsizei getSamples() const; - - virtual unsigned int getSerial() const; - - virtual bool isTexture() const; - virtual unsigned int getTextureSerial() const; - - static unsigned int issueSerials(unsigned int count); - - protected: GLsizei mWidth; GLsizei mHeight; GLenum mInternalFormat; GLenum mActualFormat; GLsizei mSamples; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage); - - const unsigned int mSerial; - - static unsigned int mCurrentSerial; -}; - -class Colorbuffer : public RenderbufferStorage -{ - public: - Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain); - Colorbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples); - - virtual ~Colorbuffer(); - - virtual rx::RenderTarget *getRenderTarget(); - - private: - DISALLOW_COPY_AND_ASSIGN(Colorbuffer); - - rx::RenderTarget *mRenderTarget; -}; - -class DepthStencilbuffer : public RenderbufferStorage -{ - public: - DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain); - DepthStencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples); - - ~DepthStencilbuffer(); - - virtual rx::RenderTarget *getRenderTarget(); - - protected: - rx::RenderTarget *mDepthStencil; - - private: - DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer); -}; - -class Depthbuffer : public DepthStencilbuffer -{ - public: - Depthbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples); - - virtual ~Depthbuffer(); - - private: - DISALLOW_COPY_AND_ASSIGN(Depthbuffer); -}; - -class Stencilbuffer : public DepthStencilbuffer -{ - public: - Stencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples); - - virtual ~Stencilbuffer(); - - private: - DISALLOW_COPY_AND_ASSIGN(Stencilbuffer); }; } diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp index 9121de1750..38d53cad81 100644 --- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp @@ -21,9 +21,9 @@ namespace gl { ResourceManager::ResourceManager(rx::Renderer *renderer) + : mRenderer(renderer), + mRefCount(1) { - mRefCount = 1; - mRenderer = renderer; } ResourceManager::~ResourceManager() @@ -88,13 +88,13 @@ GLuint ResourceManager::createBuffer() } // Returns an unused shader/program name -GLuint ResourceManager::createShader(GLenum type) +GLuint ResourceManager::createShader(const gl::Data &data, GLenum type) { GLuint handle = mProgramShaderHandleAllocator.allocate(); if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER) { - mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle); + mShaderMap[handle] = new Shader(this, mRenderer->createShader(data, type), type, handle); } else UNREACHABLE(); @@ -146,7 +146,7 @@ GLuint ResourceManager::createFenceSync() { GLuint handle = mFenceSyncHandleAllocator.allocate(); - FenceSync *fenceSync = new FenceSync(mRenderer, handle); + FenceSync *fenceSync = new FenceSync(mRenderer->createFenceSync(), handle); fenceSync->addRef(); mFenceSyncMap[handle] = fenceSync; @@ -295,9 +295,9 @@ Texture *ResourceManager::getTexture(unsigned int handle) } } -Program *ResourceManager::getProgram(unsigned int handle) +Program *ResourceManager::getProgram(unsigned int handle) const { - ProgramMap::iterator program = mProgramMap.find(handle); + ProgramMap::const_iterator program = mProgramMap.find(handle); if (program == mProgramMap.end()) { @@ -403,7 +403,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer) { if (renderbuffer != 0 && !getRenderbuffer(renderbuffer)) { - Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0)); + Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer->createRenderbuffer(), renderbuffer); mRenderbufferMap[renderbuffer] = renderbufferObject; renderbufferObject->addRef(); } diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h index 7d53bd4854..acad29b51d 100644 --- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h +++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h @@ -32,6 +32,7 @@ class Texture; class Renderbuffer; class Sampler; class FenceSync; +struct Data; class ResourceManager { @@ -43,7 +44,7 @@ class ResourceManager void release(); GLuint createBuffer(); - GLuint createShader(GLenum type); + GLuint createShader(const gl::Data &data, GLenum type); GLuint createProgram(); GLuint createTexture(); GLuint createRenderbuffer(); @@ -60,7 +61,7 @@ class ResourceManager Buffer *getBuffer(GLuint handle); Shader *getShader(GLuint handle); - Program *getProgram(GLuint handle); + Program *getProgram(GLuint handle) const; Texture *getTexture(GLuint handle); Renderbuffer *getRenderbuffer(GLuint handle); Sampler *getSampler(GLuint handle); @@ -78,8 +79,8 @@ class ResourceManager private: DISALLOW_COPY_AND_ASSIGN(ResourceManager); - std::size_t mRefCount; rx::Renderer *mRenderer; + std::size_t mRefCount; typedef std::unordered_map BufferMap; BufferMap mBufferMap; diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp index 4cf5251ff9..1cc17a0501 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp @@ -118,9 +118,15 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer); } -void Shader::compile() +void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const { - mCompiled = mShader->compile(mSource); + std::string debugInfo(mShader->getDebugInfo()); + getSourceImpl(debugInfo, bufSize, length, buffer); +} + +void Shader::compile(const gl::Data &data) +{ + mCompiled = mShader->compile(data, mSource); } void Shader::addRef() diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h index 7ba3bd165c..904217dab8 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.h +++ b/src/3rdparty/angle/src/libGLESv2/Shader.h @@ -31,6 +31,7 @@ class ShaderImpl; namespace gl { class ResourceManager; +struct Data; struct PackedVarying : public sh::Varying { @@ -73,8 +74,9 @@ class Shader void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; int getTranslatedSourceLength() const; void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const; + void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const; - void compile(); + void compile(const gl::Data &data); bool isCompiled() const { return mCompiled; } void addRef(); diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp index 3c03b90e56..b5b62f5848 100644 --- a/src/3rdparty/angle/src/libGLESv2/State.cpp +++ b/src/3rdparty/angle/src/libGLESv2/State.cpp @@ -10,18 +10,20 @@ #include "libGLESv2/Context.h" #include "libGLESv2/Caps.h" -#include "libGLESv2/VertexArray.h" -#include "libGLESv2/Query.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" -#include "libGLESv2/renderer/RenderTarget.h" +#include "libGLESv2/Query.h" +#include "libGLESv2/VertexArray.h" #include "libGLESv2/formatutils.h" +#include "libGLESv2/renderer/RenderTarget.h" namespace gl { State::State() { + mMaxDrawBuffers = 0; + mMaxCombinedTextureImageUnits = 0; } State::~State() @@ -31,7 +33,8 @@ State::~State() void State::initialize(const Caps& caps, GLuint clientVersion) { - mContext = NULL; + mMaxDrawBuffers = caps.maxDrawBuffers; + mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; setClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -111,11 +114,15 @@ void State::initialize(const Caps& caps, GLuint clientVersion) mActiveSampler = 0; const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) + mVertexAttribCurrentValues.resize(caps.maxVertexAttributes); + for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex) { mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); } + mUniformBuffers.resize(caps.maxCombinedUniformBlocks); + mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes); + mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits); mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits); if (clientVersion >= 3) @@ -153,12 +160,6 @@ void State::reset() mSamplers[samplerIdx].set(NULL); } - const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) - { - mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); - } - mArrayBuffer.set(NULL); mRenderbuffer.set(NULL); @@ -170,15 +171,15 @@ void State::reset() } mGenericUniformBuffer.set(NULL); - for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) + mGenericTransformFeedbackBuffer.set(NULL); + for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr) { - mUniformBuffers[i].set(NULL); + bufItr->set(NULL); } - mGenericTransformFeedbackBuffer.set(NULL); - for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr) { - mTransformFeedbackBuffers[i].set(NULL); + bufItr->set(NULL); } mCopyReadBuffer.set(NULL); @@ -485,7 +486,7 @@ void State::setSampleCoverageParams(GLclampf value, bool invert) mSampleCoverageInvert = invert; } -void State::getSampleCoverageParams(GLclampf *value, bool *invert) +void State::getSampleCoverageParams(GLclampf *value, bool *invert) const { ASSERT(value != NULL && invert != NULL); @@ -612,14 +613,7 @@ void State::setSamplerTexture(GLenum type, Texture *texture) Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const { - const BindingPointer& binding = mSamplerTextures.at(type)[sampler]; - - if (binding.id() == 0) // Special case: 0 refers to default textures held by Context - { - return NULL; - } - - return binding.get(); + return mSamplerTextures.at(type)[sampler].get(); } GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const @@ -627,7 +621,7 @@ GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const return mSamplerTextures.at(type)[sampler].id(); } -void State::detachTexture(GLuint texture) +void State::detachTexture(const TextureMap &zeroTextures, GLuint texture) { // Textures have a detach method on State rather than a simple // removeBinding, because the zero/null texture objects are managed @@ -640,13 +634,15 @@ void State::detachTexture(GLuint texture) for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) { + GLenum textureType = bindingVec->first; TextureBindingVector &textureVector = bindingVec->second; for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++) { BindingPointer &binding = textureVector[textureIdx]; if (binding.id() == texture) { - binding.set(NULL); + // Zero textures are the "default" textures instead of NULL + binding.set(zeroTextures.at(textureType).get()); } } } @@ -667,6 +663,19 @@ void State::detachTexture(GLuint texture) } } +void State::initializeZeroTextures(const TextureMap &zeroTextures) +{ + for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++) + { + TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first]; + + for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit) + { + samplerTextureArray[textureUnit].set(i->second.get()); + } + } +} + void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler) { mSamplers[textureUnit].set(sampler); @@ -947,14 +956,14 @@ void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintpt GLuint State::getIndexedUniformBufferId(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); + ASSERT(static_cast(index) < mUniformBuffers.size()); return mUniformBuffers[index].id(); } Buffer *State::getIndexedUniformBuffer(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); + ASSERT(static_cast(index) < mUniformBuffers.size()); return mUniformBuffers[index].get(); } @@ -971,25 +980,30 @@ void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffe GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + ASSERT(static_cast(index) < mTransformFeedbackBuffers.size()); return mTransformFeedbackBuffers[index].id(); } Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + ASSERT(static_cast(index) < mTransformFeedbackBuffers.size()); return mTransformFeedbackBuffers[index].get(); } GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const { - ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + ASSERT(static_cast(index) < mTransformFeedbackBuffers.size()); return mTransformFeedbackBuffers[index].getOffset(); } +size_t State::getTransformFeedbackBufferIndexRange() const +{ + return mTransformFeedbackBuffers.size(); +} + void State::setCopyReadBufferBinding(Buffer *buffer) { mCopyReadBuffer.set(buffer); @@ -1033,19 +1047,19 @@ void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) void State::setVertexAttribf(GLuint index, const GLfloat values[4]) { - ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setFloatValues(values); } void State::setVertexAttribu(GLuint index, const GLuint values[4]) { - ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setUnsignedIntValues(values); } void State::setVertexAttribi(GLuint index, const GLint values[4]) { - ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setIntValues(values); } @@ -1062,15 +1076,10 @@ const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const { - ASSERT(attribNum < MAX_VERTEX_ATTRIBS); + ASSERT(static_cast(attribNum) < mVertexAttribCurrentValues.size()); return mVertexAttribCurrentValues[attribNum]; } -const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const -{ - return mVertexAttribCurrentValues; -} - const void *State::getVertexAttribPointer(unsigned int attribNum) const { return getVertexArray()->getVertexAttribute(attribNum).pointer; @@ -1180,12 +1189,12 @@ void State::getFloatv(GLenum pname, GLfloat *params) } } -void State::getIntegerv(GLenum pname, GLint *params) +void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) { if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) { unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT); - ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers); + ASSERT(colorAttachment < mMaxDrawBuffers); Framebuffer *framebuffer = mDrawFramebuffer; *params = framebuffer->getDrawBufferState(colorAttachment); return; @@ -1238,12 +1247,12 @@ void State::getIntegerv(GLenum pname, GLint *params) case GL_SAMPLES: { gl::Framebuffer *framebuffer = mDrawFramebuffer; - if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->completeness(data) == GL_FRAMEBUFFER_COMPLETE) { switch (pname) { case GL_SAMPLE_BUFFERS: - if (framebuffer->getSamples() != 0) + if (framebuffer->getSamples(data) != 0) { *params = 1; } @@ -1253,7 +1262,7 @@ void State::getIntegerv(GLenum pname, GLint *params) } break; case GL_SAMPLES: - *params = framebuffer->getSamples(); + *params = framebuffer->getSamples(data); break; } } @@ -1332,19 +1341,19 @@ void State::getIntegerv(GLenum pname, GLint *params) } break; case GL_TEXTURE_BINDING_2D: - ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id(); break; case GL_TEXTURE_BINDING_CUBE_MAP: - ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id(); break; case GL_TEXTURE_BINDING_3D: - ASSERT(mActiveSampler getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id(); break; case GL_TEXTURE_BINDING_2D_ARRAY: - ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id(); break; case GL_UNIFORM_BUFFER_BINDING: @@ -1376,13 +1385,13 @@ bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + if (static_cast(index) < mTransformFeedbackBuffers.size()) { *data = mTransformFeedbackBuffers[index].id(); } break; case GL_UNIFORM_BUFFER_BINDING: - if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + if (static_cast(index) < mUniformBuffers.size()) { *data = mUniformBuffers[index].id(); } @@ -1399,25 +1408,25 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_START: - if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + if (static_cast(index) < mTransformFeedbackBuffers.size()) { *data = mTransformFeedbackBuffers[index].getOffset(); } break; case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) + if (static_cast(index) < mTransformFeedbackBuffers.size()) { *data = mTransformFeedbackBuffers[index].getSize(); } break; case GL_UNIFORM_BUFFER_START: - if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + if (static_cast(index) < mUniformBuffers.size()) { *data = mUniformBuffers[index].getOffset(); } break; case GL_UNIFORM_BUFFER_SIZE: - if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) + if (static_cast(index) < mUniformBuffers.size()) { *data = mUniformBuffers[index].getSize(); } @@ -1433,9 +1442,9 @@ bool State::hasMappedBuffer(GLenum target) const { if (target == GL_ARRAY_BUFFER) { - for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++) + for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++) { - const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex); + const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast(attribIndex)); gl::Buffer *boundBuffer = vertexAttrib.buffer.get(); if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped()) { diff --git a/src/3rdparty/angle/src/libGLESv2/State.h b/src/3rdparty/angle/src/libGLESv2/State.h index 5f0433136c..c3e6106bd8 100644 --- a/src/3rdparty/angle/src/libGLESv2/State.h +++ b/src/3rdparty/angle/src/libGLESv2/State.h @@ -25,6 +25,9 @@ class Query; class VertexArray; class Context; struct Caps; +struct Data; + +typedef std::map< GLenum, BindingPointer > TextureMap; class State { @@ -35,8 +38,6 @@ class State void initialize(const Caps& caps, GLuint clientVersion); void reset(); - void setContext(Context *context) { mContext = context; } - // State chunk getters const RasterizerState &getRasterizerState() const; const BlendState &getBlendState() const; @@ -100,7 +101,7 @@ class State bool isSampleCoverageEnabled() const; void setSampleCoverage(bool enabled); void setSampleCoverageParams(GLclampf value, bool invert); - void getSampleCoverageParams(GLclampf *value, bool *invert); + void getSampleCoverageParams(GLclampf *value, bool *invert) const; // Scissor test state toggle & query bool isScissorTestEnabled() const; @@ -133,7 +134,8 @@ class State void setSamplerTexture(GLenum type, Texture *texture); Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const; - void detachTexture(GLuint texture); + void detachTexture(const TextureMap &zeroTextures, GLuint texture); + void initializeZeroTextures(const TextureMap &zeroTextures); // Sampler object binding manipulation void setSamplerBinding(GLuint textureUnit, Sampler *sampler); @@ -199,6 +201,7 @@ class State GLuint getIndexedTransformFeedbackBufferId(GLuint index) const; Buffer *getIndexedTransformFeedbackBuffer(GLuint index) const; GLuint getIndexedTransformFeedbackBufferOffset(GLuint index) const; + size_t getTransformFeedbackBufferIndexRange() const; // GL_COPY_[READ/WRITE]_BUFFER void setCopyReadBufferBinding(Buffer *buffer); @@ -220,7 +223,6 @@ class State bool normalized, bool pureInteger, GLsizei stride, const void *pointer); const VertexAttribute &getVertexAttribState(unsigned int attribNum) const; const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const; - const VertexAttribCurrentValueData *getVertexAttribCurrentValues() const; const void *getVertexAttribPointer(unsigned int attribNum) const; // Pixel pack state manipulation @@ -238,7 +240,7 @@ class State // State query functions void getBooleanv(GLenum pname, GLboolean *params); void getFloatv(GLenum pname, GLfloat *params); - void getIntegerv(GLenum pname, GLint *params); + void getIntegerv(const gl::Data &data, GLenum pname, GLint *params); bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); @@ -247,7 +249,9 @@ class State private: DISALLOW_COPY_AND_ASSIGN(State); - Context *mContext; + // Cached values from Context's caps + GLuint mMaxDrawBuffers; + GLuint mMaxCombinedTextureImageUnits; ColorF mColorClearValue; GLclampf mDepthClearValue; @@ -283,7 +287,8 @@ class State GLuint mCurrentProgramId; BindingPointer mCurrentProgramBinary; - VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib + typedef std::vector VertexAttribVector; + VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib VertexArray *mVertexArray; // Texture and sampler bindings @@ -300,11 +305,12 @@ class State ActiveQueryMap mActiveQueries; BindingPointer mGenericUniformBuffer; - OffsetBindingPointer mUniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; + typedef std::vector< OffsetBindingPointer > BufferVector; + BufferVector mUniformBuffers; BindingPointer mTransformFeedback; BindingPointer mGenericTransformFeedbackBuffer; - OffsetBindingPointer mTransformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + BufferVector mTransformFeedbackBuffers; BindingPointer mCopyReadBuffer; BindingPointer mCopyWriteBuffer; diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp index 3ec492de07..cd4fc4e32a 100644 --- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp @@ -47,11 +47,14 @@ bool IsPointSampled(const gl::SamplerState &samplerState) return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST)); } +unsigned int Texture::mCurrentTextureSerial = 1; + Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target) : RefCountObject(id), mTexture(impl), + mTextureSerial(issueTextureSerial()), mUsage(GL_NONE), - mImmutable(false), + mImmutableLevelCount(0), mTarget(target) { } @@ -72,16 +75,6 @@ void Texture::setUsage(GLenum usage) getImplementation()->setUsage(usage); } -void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler) -{ - *sampler = mSamplerState; - - // Offset the effective base level by the texture storage's top level - rx::TextureStorage *texture = getNativeTexture(); - int topLevel = texture ? texture->getTopLevel() : 0; - sampler->baseLevel = topLevel + mSamplerState.baseLevel; -} - GLenum Texture::getUsage() const { return mUsage; @@ -138,35 +131,35 @@ GLenum Texture::getActualFormat(const ImageIndex &index) const return image->getActualFormat(); } -rx::TextureStorage *Texture::getNativeTexture() +Error Texture::generateMipmaps() { - return getImplementation()->getNativeTexture(); + return getImplementation()->generateMipmaps(); } -void Texture::generateMipmaps() +Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { - getImplementation()->generateMipmaps(); + return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source); } -void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +unsigned int Texture::getTextureSerial() const { - getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source); + return mTextureSerial; } -unsigned int Texture::getTextureSerial() +unsigned int Texture::issueTextureSerial() { - rx::TextureStorage *texture = getNativeTexture(); - return texture ? texture->getTextureSerial() : 0; + return mCurrentTextureSerial++; } bool Texture::isImmutable() const { - return mImmutable; + return (mImmutableLevelCount > 0); } int Texture::immutableLevelCount() { - return (mImmutable ? getNativeTexture()->getLevelCount() : 0); + return mImmutableLevelCount; } int Texture::mipLevels() const @@ -226,11 +219,11 @@ GLenum Texture2D::getActualFormat(GLint level) const return GL_NONE; } -void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { releaseTexImage(); - mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels); } void Texture2D::bindTexImage(egl::Surface *surface) @@ -254,35 +247,44 @@ void Texture2D::releaseTexImage() } } -void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) +Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, + const PixelUnpackState &unpack, const void *pixels) { releaseTexImage(); - mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels); + return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels); } -void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); + return mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); } -void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels); + return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels); } -void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, + Framebuffer *source) { releaseTexImage(); - mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source); + return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source); } -void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1); + if (error.isError()) + { + return error; + } - mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1); + mImmutableLevelCount = levels; + + return Error(GL_NO_ERROR); } // Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85. @@ -359,11 +361,11 @@ bool Texture2D::isDepth(GLint level) const return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void Texture2D::generateMipmaps() +Error Texture2D::generateMipmaps() { releaseTexImage(); - mTexture->generateMipmaps(); + return mTexture->generateMipmaps(); } // Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. @@ -467,49 +469,27 @@ GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const return GL_NONE; } -void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels); } -void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels); + return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels); } -void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels); + return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); } -void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels); -} - -void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) -{ - mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels); -} - -void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) -{ - mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels); -} - -void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) -{ - mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels); -} - -void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) -{ - mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels); -} - -void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) -{ - mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels); + return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels); } // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. @@ -549,16 +529,23 @@ bool TextureCubeMap::isDepth(GLenum target, GLint level) const return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0; } -void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) +Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, + GLsizei width, GLsizei height, Framebuffer *source) { - mTexture->copyImage(target, level, format, x, y, width, height, source); + return mTexture->copyImage(target, level, format, x, y, width, height, source); } -void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) +Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1); + if (error.isError()) + { + return error; + } - mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1); + mImmutableLevelCount = levels; + + return Error(GL_NO_ERROR); } // Tests for texture sampling completeness @@ -734,31 +721,40 @@ bool Texture3D::isDepth(GLint level) const return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels); } -void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels); + return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels); } -void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); + return mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); } -void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels); } -void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth); + if (error.isError()) + { + return error; + } - mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth); + mImmutableLevelCount = levels; + + return Error(GL_NO_ERROR); } bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const @@ -892,31 +888,40 @@ bool Texture2DArray::isDepth(GLint level) const return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels); + return mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels); } -void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels); + return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels); } -void Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) +Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); + return mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels); } -void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels) { - mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels); } -void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { - mImmutable = true; + Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth); + if (error.isError()) + { + return error; + } - mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth); + mImmutableLevelCount = levels; + + return Error(GL_NO_ERROR); } bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.h b/src/3rdparty/angle/src/libGLESv2/Texture.h index ca5686fde3..66d4df8015 100644 --- a/src/3rdparty/angle/src/libGLESv2/Texture.h +++ b/src/3rdparty/angle/src/libGLESv2/Texture.h @@ -14,7 +14,7 @@ #include "common/debug.h" #include "common/RefCountObject.h" #include "libGLESv2/angletypes.h" -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "libGLESv2/renderer/TextureImpl.h" #include "libGLESv2/Caps.h" @@ -52,7 +52,6 @@ class Texture : public RefCountObject const SamplerState &getSamplerState() const { return mSamplerState; } SamplerState &getSamplerState() { return mSamplerState; } - void getSamplerStateWithNativeOffset(SamplerState *sampler); void setUsage(GLenum usage); GLenum getUsage() const; @@ -69,15 +68,16 @@ class Texture : public RefCountObject virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0; - rx::TextureStorage *getNativeTexture(); + virtual Error generateMipmaps(); - virtual void generateMipmaps(); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - unsigned int getTextureSerial(); + // Texture serials provide a unique way of identifying a Texture that isn't a raw pointer. + // "id" is not good enough, as Textures can be deleted, then re-allocated with the same id. + unsigned int getTextureSerial() const; bool isImmutable() const; - int immutableLevelCount(); + GLsizei immutableLevelCount(); rx::TextureImpl *getImplementation() { return mTexture; } const rx::TextureImpl *getImplementation() const { return mTexture; } @@ -86,17 +86,20 @@ class Texture : public RefCountObject protected: int mipLevels() const; + const rx::Image *getBaseLevelImage() const; + static unsigned int issueTextureSerial(); rx::TextureImpl *mTexture; SamplerState mSamplerState; GLenum mUsage; - bool mImmutable; + GLsizei mImmutableLevelCount; GLenum mTarget; - const rx::Image *getBaseLevelImage() const; + const unsigned int mTextureSerial; + static unsigned int mCurrentTextureSerial; private: DISALLOW_COPY_AND_ASSIGN(Texture); @@ -116,18 +119,18 @@ class Texture2D : public Texture bool isCompressed(GLint level) const; bool isDepth(GLint level) const; - void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); - void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + Error setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); - virtual void generateMipmaps(); + virtual Error generateMipmaps(); private: DISALLOW_COPY_AND_ASSIGN(Texture2D); @@ -152,19 +155,12 @@ class TextureCubeMap : public Texture bool isCompressed(GLenum target, GLint level) const; bool isDepth(GLenum target, GLint level) const; - void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - - void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); - - void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); - void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - void storage(GLsizei levels, GLenum internalformat, GLsizei size); + Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + Error storage(GLsizei levels, GLenum internalformat, GLsizei size); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; @@ -195,11 +191,11 @@ class Texture3D : public Texture bool isCompressed(GLint level) const; bool isDepth(GLint level) const; - void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; @@ -225,11 +221,11 @@ class Texture2DArray : public Texture bool isCompressed(GLint level) const; bool isDepth(GLint level) const; - void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); - void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels); + Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels); + Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const; diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.h b/src/3rdparty/angle/src/libGLESv2/VertexArray.h index 993ba042cf..a724c0be1c 100644 --- a/src/3rdparty/angle/src/libGLESv2/VertexArray.h +++ b/src/3rdparty/angle/src/libGLESv2/VertexArray.h @@ -14,14 +14,13 @@ #define LIBGLESV2_VERTEXARRAY_H_ #include "common/RefCountObject.h" -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "libGLESv2/VertexAttribute.h" #include namespace rx { -class Renderer; class VertexArrayImpl; } @@ -44,7 +43,7 @@ class VertexArray void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized, bool pureInteger, GLsizei stride, const void *pointer); - const VertexAttribute* getVertexAttributes() const { return mVertexAttributes.data(); } + const VertexAttribute* getVertexAttributes() const { return &mVertexAttributes[0]; } Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); } void setElementArrayBuffer(Buffer *buffer); GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); } diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp index bb6425df64..5a0cfc5ad9 100644 --- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp +++ b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp @@ -9,6 +9,10 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" +#include "libGLESv2/State.h" +#include "libGLESv2/VertexArray.h" + +#include namespace gl { @@ -148,16 +152,16 @@ VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueTyp void VertexFormat::GetInputLayout(VertexFormat *inputLayout, ProgramBinary *programBinary, - const VertexAttribute *attributes, - const gl::VertexAttribCurrentValueData *currentValues) + const State &state) { + const VertexAttribute *vertexAttributes = state.getVertexArray()->getVertexAttributes(); for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) { int semanticIndex = programBinary->getSemanticIndex(attributeIndex); if (semanticIndex != -1) { - inputLayout[semanticIndex] = VertexFormat(attributes[attributeIndex], currentValues[attributeIndex].Type); + inputLayout[semanticIndex] = VertexFormat(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex).Type); } } } @@ -192,4 +196,15 @@ bool VertexFormat::operator<(const VertexFormat& other) const return mPureInteger < other.mPureInteger; } +bool Box::operator==(const Box &other) const +{ + return (x == other.x && y == other.y && z == other.z && + width == other.width && height == other.height && depth == other.depth); +} + +bool Box::operator!=(const Box &other) const +{ + return !(*this == other); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h index 642a6ec266..78fe6b0e26 100644 --- a/src/3rdparty/angle/src/libGLESv2/angletypes.h +++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h @@ -9,13 +9,13 @@ #ifndef LIBGLESV2_ANGLETYPES_H_ #define LIBGLESV2_ANGLETYPES_H_ -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "common/RefCountObject.h" -#include namespace gl { class Buffer; +class State; class ProgramBinary; struct VertexAttribute; struct VertexAttribCurrentValueData; @@ -66,6 +66,8 @@ struct Box Box() : x(0), y(0), z(0), width(0), height(0), depth(0) { } Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) { } + bool operator==(const Box &other) const; + bool operator!=(const Box &other) const; }; struct Extents @@ -230,8 +232,7 @@ struct VertexFormat static void GetInputLayout(VertexFormat *inputLayout, ProgramBinary *programBinary, - const VertexAttribute *attributes, - const gl::VertexAttribCurrentValueData *currentValues); + const State& currentValues); bool operator==(const VertexFormat &other) const; bool operator!=(const VertexFormat &other) const; @@ -251,13 +252,6 @@ enum VertexConversionType VERTEX_CONVERT_BOTH = 3 }; -enum D3DWorkaroundType -{ - ANGLE_D3D_WORKAROUND_NONE, - ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION, - ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION -}; - } #endif // LIBGLESV2_ANGLETYPES_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp index 07f5d47473..587950a139 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp @@ -34,13 +34,12 @@ #include "libGLESv2/validationES3.h" #include "libGLESv2/queryconversions.h" - extern "C" { // OpenGL ES 2.0 functions -void __stdcall glActiveTexture(GLenum texture) +void GL_APIENTRY glActiveTexture(GLenum texture) { EVENT("(GLenum texture = 0x%X)", texture); @@ -57,7 +56,7 @@ void __stdcall glActiveTexture(GLenum texture) } } -void __stdcall glAttachShader(GLuint program, GLuint shader) +void GL_APIENTRY glAttachShader(GLuint program, GLuint shader) { EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); @@ -103,7 +102,7 @@ void __stdcall glAttachShader(GLuint program, GLuint shader) } } -void __stdcall glBeginQueryEXT(GLenum target, GLuint id) +void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id) { EVENT("(GLenum target = 0x%X, GLuint %d)", target, id); @@ -124,7 +123,7 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id) } } -void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) +void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) { EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); @@ -163,7 +162,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* } } -void __stdcall glBindBuffer(GLenum target, GLuint buffer) +void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer) { EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); @@ -210,7 +209,7 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer) } } -void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) +void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer) { EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); @@ -235,7 +234,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) } } -void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) +void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer) { EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); @@ -252,7 +251,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) } } -void __stdcall glBindTexture(GLenum target, GLuint texture) +void GL_APIENTRY glBindTexture(GLenum target, GLuint texture) { EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); @@ -291,7 +290,7 @@ void __stdcall glBindTexture(GLenum target, GLuint texture) } } -void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", red, green, blue, alpha); @@ -304,12 +303,12 @@ void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp } } -void __stdcall glBlendEquation(GLenum mode) +void GL_APIENTRY glBlendEquation(GLenum mode) { glBlendEquationSeparate(mode, mode); } -void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); @@ -348,12 +347,12 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) } } -void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor) +void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); } -void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", srcRGB, dstRGB, srcAlpha, dstAlpha); @@ -488,7 +487,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha } } -void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) +void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", target, size, data, usage); @@ -550,7 +549,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, } } -void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) +void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", target, offset, size, data); @@ -611,7 +610,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, } } -GLenum __stdcall glCheckFramebufferStatus(GLenum target) +GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -626,13 +625,14 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target) gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); ASSERT(framebuffer); - return framebuffer->completeness(); + + return framebuffer->completeness(context->getData()); } return 0; } -void __stdcall glClear(GLbitfield mask) +void GL_APIENTRY glClear(GLbitfield mask) { EVENT("(GLbitfield mask = 0x%X)", mask); @@ -640,8 +640,9 @@ void __stdcall glClear(GLbitfield mask) if (context) { gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); + ASSERT(framebufferObject); - if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (framebufferObject->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return; @@ -662,7 +663,7 @@ void __stdcall glClear(GLbitfield mask) } } -void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", red, green, blue, alpha); @@ -674,7 +675,7 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp } } -void __stdcall glClearDepthf(GLclampf depth) +void GL_APIENTRY glClearDepthf(GLclampf depth) { EVENT("(GLclampf depth = %f)", depth); @@ -685,7 +686,7 @@ void __stdcall glClearDepthf(GLclampf depth) } } -void __stdcall glClearStencil(GLint s) +void GL_APIENTRY glClearStencil(GLint s) { EVENT("(GLint s = %d)", s); @@ -696,7 +697,7 @@ void __stdcall glClearStencil(GLint s) } } -void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)", red, green, blue, alpha); @@ -708,7 +709,7 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo } } -void __stdcall glCompileShader(GLuint shader) +void GL_APIENTRY glCompileShader(GLuint shader) { EVENT("(GLuint shader = %d)", shader); @@ -731,11 +732,11 @@ void __stdcall glCompileShader(GLuint shader) } } - shaderObject->compile(); + shaderObject->compile(context->getData()); } } -void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, +void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " @@ -771,7 +772,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->setCompressedImage(level, internalformat, width, height, imageSize, data); + gl::Error error = texture->setCompressedImage(level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -783,7 +789,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); + gl::Error error = texture->setCompressedImage(target, level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -794,7 +805,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna } } -void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " @@ -831,7 +842,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); + gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -843,7 +859,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); + gl::Error error = texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -854,7 +875,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs } } -void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", @@ -884,7 +905,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->copyImage(level, internalformat, x, y, width, height, framebuffer); + gl::Error error = texture->copyImage(level, internalformat, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -896,7 +922,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); + gl::Error error = texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -907,7 +938,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma } } -void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", @@ -937,7 +968,12 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -949,7 +985,12 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -960,7 +1001,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL } } -GLuint __stdcall glCreateProgram(void) +GLuint GL_APIENTRY glCreateProgram(void) { EVENT("()"); @@ -973,7 +1014,7 @@ GLuint __stdcall glCreateProgram(void) return 0; } -GLuint __stdcall glCreateShader(GLenum type) +GLuint GL_APIENTRY glCreateShader(GLenum type) { EVENT("(GLenum type = 0x%X)", type); @@ -995,7 +1036,7 @@ GLuint __stdcall glCreateShader(GLenum type) return 0; } -void __stdcall glCullFace(GLenum mode) +void GL_APIENTRY glCullFace(GLenum mode) { EVENT("(GLenum mode = 0x%X)", mode); @@ -1018,7 +1059,7 @@ void __stdcall glCullFace(GLenum mode) } } -void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) +void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers) { EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); @@ -1038,7 +1079,7 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) } } -void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) +void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences) { EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); @@ -1058,7 +1099,7 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) } } -void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) +void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); @@ -1081,7 +1122,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) } } -void __stdcall glDeleteProgram(GLuint program) +void GL_APIENTRY glDeleteProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -1111,7 +1152,7 @@ void __stdcall glDeleteProgram(GLuint program) } } -void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) +void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids) { EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); @@ -1131,7 +1172,7 @@ void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) } } -void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) +void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); @@ -1151,7 +1192,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) } } -void __stdcall glDeleteShader(GLuint shader) +void GL_APIENTRY glDeleteShader(GLuint shader) { EVENT("(GLuint shader = %d)", shader); @@ -1181,7 +1222,7 @@ void __stdcall glDeleteShader(GLuint shader) } } -void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) +void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures) { EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); @@ -1204,7 +1245,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) } } -void __stdcall glDepthFunc(GLenum func) +void GL_APIENTRY glDepthFunc(GLenum func) { EVENT("(GLenum func = 0x%X)", func); @@ -1231,7 +1272,7 @@ void __stdcall glDepthFunc(GLenum func) } } -void __stdcall glDepthMask(GLboolean flag) +void GL_APIENTRY glDepthMask(GLboolean flag) { EVENT("(GLboolean flag = %u)", flag); @@ -1242,7 +1283,7 @@ void __stdcall glDepthMask(GLboolean flag) } } -void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) +void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar) { EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); @@ -1253,7 +1294,7 @@ void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) } } -void __stdcall glDetachShader(GLuint program, GLuint shader) +void GL_APIENTRY glDetachShader(GLuint program, GLuint shader) { EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); @@ -1302,7 +1343,7 @@ void __stdcall glDetachShader(GLuint program, GLuint shader) } } -void __stdcall glDisable(GLenum cap) +void GL_APIENTRY glDisable(GLenum cap) { EVENT("(GLenum cap = 0x%X)", cap); @@ -1319,7 +1360,7 @@ void __stdcall glDisable(GLenum cap) } } -void __stdcall glDisableVertexAttribArray(GLuint index) +void GL_APIENTRY glDisableVertexAttribArray(GLuint index) { EVENT("(GLuint index = %d)", index); @@ -1336,7 +1377,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index) } } -void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) +void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); @@ -1357,7 +1398,7 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) } } -void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) +void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) { EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount); @@ -1378,7 +1419,7 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun } } -void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) +void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", mode, count, type, indices); @@ -1401,7 +1442,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv } } -void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) +void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) { EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)", mode, count, type, indices, primcount); @@ -1424,7 +1465,7 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t } } -void __stdcall glEnable(GLenum cap) +void GL_APIENTRY glEnable(GLenum cap) { EVENT("(GLenum cap = 0x%X)", cap); @@ -1441,7 +1482,7 @@ void __stdcall glEnable(GLenum cap) } } -void __stdcall glEnableVertexAttribArray(GLuint index) +void GL_APIENTRY glEnableVertexAttribArray(GLuint index) { EVENT("(GLuint index = %d)", index); @@ -1458,7 +1499,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index) } } -void __stdcall glEndQueryEXT(GLenum target) +void GL_APIENTRY glEndQueryEXT(GLenum target) { EVENT("GLenum target = 0x%X)", target); @@ -1479,7 +1520,7 @@ void __stdcall glEndQueryEXT(GLenum target) } } -void __stdcall glFinishFenceNV(GLuint fence) +void GL_APIENTRY glFinishFenceNV(GLuint fence) { EVENT("(GLuint fence = %d)", fence); @@ -1504,29 +1545,39 @@ void __stdcall glFinishFenceNV(GLuint fence) } } -void __stdcall glFinish(void) +void GL_APIENTRY glFinish(void) { EVENT("()"); gl::Context *context = gl::getNonLostContext(); if (context) { - context->sync(true); + gl::Error error = context->sync(true); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glFlush(void) +void GL_APIENTRY glFlush(void) { EVENT("()"); gl::Context *context = gl::getNonLostContext(); if (context) { - context->sync(false); + gl::Error error = context->sync(false); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); @@ -1548,33 +1599,19 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); ASSERT(framebuffer); - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (renderbuffer != 0) { - unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0); + gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); + framebuffer->setRenderbufferAttachment(attachment, renderbufferObject); } else { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: - framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); - break; - case GL_STENCIL_ATTACHMENT: - framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); - break; - case GL_DEPTH_STENCIL_ATTACHMENT: - framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); - break; - default: - UNREACHABLE(); - break; - } + framebuffer->setNULLAttachment(attachment); } } } -void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); @@ -1587,31 +1624,23 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t return; } - if (texture == 0) - { - textarget = GL_NONE; - } - gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + ASSERT(framebuffer); - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (texture != 0) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0); + gl::Texture *textureObj = context->getTexture(texture); + gl::ImageIndex index(textarget, level, gl::ImageIndex::ENTIRE_LEVEL); + framebuffer->setTextureAttachment(attachment, textureObj, index); } else { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, 0); break; - case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, 0); break; - case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break; - } + framebuffer->setNULLAttachment(attachment); } } } -void __stdcall glFrontFace(GLenum mode) +void GL_APIENTRY glFrontFace(GLenum mode) { EVENT("(GLenum mode = 0x%X)", mode); @@ -1631,7 +1660,7 @@ void __stdcall glFrontFace(GLenum mode) } } -void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) +void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers) { EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); @@ -1651,7 +1680,7 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) } } -void __stdcall glGenerateMipmap(GLenum target) +void GL_APIENTRY glGenerateMipmap(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -1721,11 +1750,16 @@ void __stdcall glGenerateMipmap(GLenum target) } } - texture->generateMipmaps(); + gl::Error error = texture->generateMipmaps(); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) +void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences) { EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); @@ -1745,7 +1779,7 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) } } -void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) +void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers) { EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); @@ -1765,7 +1799,7 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) } } -void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -1785,7 +1819,7 @@ void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) } } -void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) +void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) { EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); @@ -1805,7 +1839,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) } } -void __stdcall glGenTextures(GLsizei n, GLuint* textures) +void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures) { EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); @@ -1825,7 +1859,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures) } } -void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)", @@ -1866,7 +1900,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, } } -void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) { EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", @@ -1908,7 +1942,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, } } -void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", program, maxcount, count, shaders); @@ -1942,7 +1976,7 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c } } -GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name) +GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name) { EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name); @@ -1978,7 +2012,7 @@ GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name) return -1; } -void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) +void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) { EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); @@ -2003,7 +2037,7 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) } } -void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -2056,7 +2090,7 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params } } -GLenum __stdcall glGetError(void) +GLenum GL_APIENTRY glGetError(void) { EVENT("()"); @@ -2070,7 +2104,7 @@ GLenum __stdcall glGetError(void) return GL_NO_ERROR; } -void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) +void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) { EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params); @@ -2094,19 +2128,40 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) switch (pname) { case GL_FENCE_STATUS_NV: + { + // GL_NV_fence spec: + // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV + // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. + GLboolean status = GL_TRUE; + if (fenceObject->getStatus() != GL_TRUE) + { + gl::Error error = fenceObject->testFence(&status); + if (error.isError()) + { + context->recordError(error); + return; + } + } + *params = status; + break; + } + case GL_FENCE_CONDITION_NV: - break; + { + *params = fenceObject->getCondition(); + break; + } default: - context->recordError(gl::Error(GL_INVALID_ENUM)); - return; + { + context->recordError(gl::Error(GL_INVALID_ENUM)); + return; + } } - - params[0] = fenceObject->getFencei(pname); } } -void __stdcall glGetFloatv(GLenum pname, GLfloat* params) +void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params) { EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); @@ -2131,7 +2186,7 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params) } } -void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) +void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, attachment, pname, params); @@ -2214,6 +2269,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id(); gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle); + ASSERT(framebuffer); if (framebufferHandle == 0) { @@ -2428,7 +2484,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac } } -GLenum __stdcall glGetGraphicsResetStatusEXT(void) +GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void) { EVENT("()"); @@ -2442,7 +2498,7 @@ GLenum __stdcall glGetGraphicsResetStatusEXT(void) return GL_NO_ERROR; } -void __stdcall glGetIntegerv(GLenum pname, GLint* params) +void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params) { EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); @@ -2468,7 +2524,7 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params) } } -void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) +void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params) { EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); @@ -2552,7 +2608,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) } } -void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) +void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) { EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", program, bufsize, length, infolog); @@ -2578,7 +2634,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len } } -void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) +void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) { EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params); @@ -2604,7 +2660,7 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) } } -void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) +void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) { EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); @@ -2656,7 +2712,7 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) } } -void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -2705,7 +2761,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* } } -void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) +void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params) { EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); @@ -2748,7 +2804,7 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) } } -void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) +void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) { EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", shader, bufsize, length, infolog); @@ -2774,7 +2830,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt } } -void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", shadertype, precisiontype, range, precision); @@ -2821,7 +2877,7 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp } } -void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) { EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", shader, bufsize, length, source); @@ -2847,7 +2903,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length } } -void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) { EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", shader, bufsize, length, source); @@ -2869,11 +2925,12 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, return; } - shaderObject->getTranslatedSource(bufsize, length, source); + // Only returns extra info if ANGLE_GENERATE_SHADER_DEBUG_INFO is defined + shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source); } } -const GLubyte* __stdcall glGetString(GLenum name) +const GLubyte* GL_APIENTRY glGetString(GLenum name) { EVENT("(GLenum name = 0x%X)", name); @@ -2919,7 +2976,7 @@ const GLubyte* __stdcall glGetString(GLenum name) } } -void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); @@ -3051,7 +3108,7 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) } } -void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -3098,7 +3155,7 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(gl::Error(GL_INVALID_ENUM)); return; } - *params = texture->immutableLevelCount(); + *params = static_cast(texture->immutableLevelCount()); break; case GL_TEXTURE_USAGE_ANGLE: *params = texture->getUsage(); @@ -3183,7 +3240,7 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) } } -void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) +void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) { EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)", program, location, bufSize, params); @@ -3205,7 +3262,7 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz } } -void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) +void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params) { EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); @@ -3226,7 +3283,7 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) } } -void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) +void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) { EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", program, location, bufSize, params); @@ -3248,7 +3305,7 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz } } -void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) +void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params) { EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); @@ -3269,7 +3326,7 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) } } -GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name) +GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name) { EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); @@ -3310,7 +3367,7 @@ GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name) return -1; } -void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) { EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); @@ -3344,7 +3401,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) } } -void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) +void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) { EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); @@ -3380,7 +3437,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) } } -void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) +void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) { EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); @@ -3403,7 +3460,7 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po } } -void __stdcall glHint(GLenum target, GLenum mode) +void GL_APIENTRY glHint(GLenum target, GLenum mode) { EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); @@ -3439,7 +3496,7 @@ void __stdcall glHint(GLenum target, GLenum mode) } } -GLboolean __stdcall glIsBuffer(GLuint buffer) +GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) { EVENT("(GLuint buffer = %d)", buffer); @@ -3457,7 +3514,7 @@ GLboolean __stdcall glIsBuffer(GLuint buffer) return GL_FALSE; } -GLboolean __stdcall glIsEnabled(GLenum cap) +GLboolean GL_APIENTRY glIsEnabled(GLenum cap) { EVENT("(GLenum cap = 0x%X)", cap); @@ -3476,7 +3533,7 @@ GLboolean __stdcall glIsEnabled(GLenum cap) return false; } -GLboolean __stdcall glIsFenceNV(GLuint fence) +GLboolean GL_APIENTRY glIsFenceNV(GLuint fence) { EVENT("(GLuint fence = %d)", fence); @@ -3496,7 +3553,7 @@ GLboolean __stdcall glIsFenceNV(GLuint fence) return GL_FALSE; } -GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) +GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer) { EVENT("(GLuint framebuffer = %d)", framebuffer); @@ -3514,7 +3571,7 @@ GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) return GL_FALSE; } -GLboolean __stdcall glIsProgram(GLuint program) +GLboolean GL_APIENTRY glIsProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -3532,7 +3589,7 @@ GLboolean __stdcall glIsProgram(GLuint program) return GL_FALSE; } -GLboolean __stdcall glIsQueryEXT(GLuint id) +GLboolean GL_APIENTRY glIsQueryEXT(GLuint id) { EVENT("(GLuint id = %d)", id); @@ -3545,7 +3602,7 @@ GLboolean __stdcall glIsQueryEXT(GLuint id) return GL_FALSE; } -GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) +GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer) { EVENT("(GLuint renderbuffer = %d)", renderbuffer); @@ -3563,7 +3620,7 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) return GL_FALSE; } -GLboolean __stdcall glIsShader(GLuint shader) +GLboolean GL_APIENTRY glIsShader(GLuint shader) { EVENT("(GLuint shader = %d)", shader); @@ -3581,7 +3638,7 @@ GLboolean __stdcall glIsShader(GLuint shader) return GL_FALSE; } -GLboolean __stdcall glIsTexture(GLuint texture) +GLboolean GL_APIENTRY glIsTexture(GLuint texture) { EVENT("(GLuint texture = %d)", texture); @@ -3599,7 +3656,7 @@ GLboolean __stdcall glIsTexture(GLuint texture) return GL_FALSE; } -void __stdcall glLineWidth(GLfloat width) +void GL_APIENTRY glLineWidth(GLfloat width) { EVENT("(GLfloat width = %f)", width); @@ -3616,7 +3673,7 @@ void __stdcall glLineWidth(GLfloat width) } } -void __stdcall glLinkProgram(GLuint program) +void GL_APIENTRY glLinkProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -3639,11 +3696,16 @@ void __stdcall glLinkProgram(GLuint program) } } - context->linkProgram(program); + gl::Error error = context->linkProgram(program); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glPixelStorei(GLenum pname, GLint param) +void GL_APIENTRY glPixelStorei(GLenum pname, GLint param) { EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); @@ -3699,7 +3761,7 @@ void __stdcall glPixelStorei(GLenum pname, GLint param) } } -void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) +void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units) { EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); @@ -3710,7 +3772,7 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) } } -void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, +void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data) { @@ -3742,7 +3804,7 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, } } -void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, +void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) { EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " @@ -3773,7 +3835,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, } } -void __stdcall glReleaseShaderCompiler(void) +void GL_APIENTRY glReleaseShaderCompiler(void) { EVENT("()"); @@ -3785,7 +3847,7 @@ void __stdcall glReleaseShaderCompiler(void) } } -void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, samples, internalformat, width, height); @@ -3799,16 +3861,22 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp return; } - context->setRenderbufferStorage(width, height, internalformat, samples); + gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); + gl::Error error = renderbuffer->setStorage(width, height, internalformat, samples); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height); } -void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) +void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert) { EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert); @@ -3820,7 +3888,7 @@ void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) } } -void __stdcall glSetFenceNV(GLuint fence, GLenum condition) +void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition) { EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); @@ -3841,11 +3909,16 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition) return; } - fenceObject->setFence(condition); + gl::Error error = fenceObject->setFence(condition); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); @@ -3862,7 +3935,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) } } -void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) +void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) { EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", @@ -3883,7 +3956,7 @@ void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryfor } } -void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) +void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", shader, count, string, length); @@ -3917,12 +3990,12 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* } } -void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask) +void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask) { glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); } -void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); @@ -3970,12 +4043,12 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint } } -void __stdcall glStencilMask(GLuint mask) +void GL_APIENTRY glStencilMask(GLuint mask) { glStencilMaskSeparate(GL_FRONT_AND_BACK, mask); } -void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) +void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask) { EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); @@ -4006,12 +4079,12 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) } } -void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) +void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); } -void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", face, fail, zfail, zpass); @@ -4094,7 +4167,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu } } -GLboolean __stdcall glTestFenceNV(GLuint fence) +GLboolean GL_APIENTRY glTestFenceNV(GLuint fence) { EVENT("(GLuint fence = %d)", fence); @@ -4115,13 +4188,21 @@ GLboolean __stdcall glTestFenceNV(GLuint fence) return GL_TRUE; } - return fenceObject->testFence(); + GLboolean result; + gl::Error error = fenceObject->testFence(&result); + if (error.isError()) + { + context->recordError(error); + return GL_TRUE; + } + + return result; } return GL_TRUE; } -void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, +void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " @@ -4150,51 +4231,38 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImagePosX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImageNegX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImagePosY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImageNegY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - { - gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImagePosZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); - } - break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->setImageNegZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(target, level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; + default: UNREACHABLE(); } } } -void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) +void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); @@ -4238,12 +4306,12 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) } } -void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) +void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) { glTexParameterf(target, pname, (GLfloat)*params); } -void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) +void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); @@ -4287,12 +4355,12 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) } } -void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params) +void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params) { glTexParameteri(target, pname, *params); } -void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, levels, internalformat, width, height); @@ -4323,14 +4391,24 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf case GL_TEXTURE_2D: { gl::Texture2D *texture2d = context->getTexture2D(); - texture2d->storage(levels, internalformat, width, height); + gl::Error error = texture2d->storage(levels, internalformat, width, height); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_CUBE_MAP: { gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); - textureCube->storage(levels, internalformat, width); + gl::Error error = textureCube->storage(levels, internalformat, width); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -4341,7 +4419,7 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf } } -void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, +void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " @@ -4377,7 +4455,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint case GL_TEXTURE_2D: { gl::Texture2D *texture = context->getTexture2D(); - texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -4389,7 +4472,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -4399,12 +4487,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint } } -void __stdcall glUniform1f(GLint location, GLfloat x) +void GL_APIENTRY glUniform1f(GLint location, GLfloat x) { glUniform1fv(location, 1, &x); } -void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4421,12 +4509,12 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform1i(GLint location, GLint x) +void GL_APIENTRY glUniform1i(GLint location, GLint x) { glUniform1iv(location, 1, &x); } -void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4443,14 +4531,14 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) +void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y) { GLfloat xy[2] = {x, y}; glUniform2fv(location, 1, xy); } -void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4467,14 +4555,14 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform2i(GLint location, GLint x, GLint y) +void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y) { GLint xy[2] = {x, y}; glUniform2iv(location, 1, xy); } -void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4491,14 +4579,14 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) +void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { GLfloat xyz[3] = {x, y, z}; glUniform3fv(location, 1, xyz); } -void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4515,14 +4603,14 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) +void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z) { GLint xyz[3] = {x, y, z}; glUniform3iv(location, 1, xyz); } -void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4539,14 +4627,14 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { GLfloat xyzw[4] = {x, y, z, w}; glUniform4fv(location, 1, xyzw); } -void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); @@ -4563,14 +4651,14 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) } } -void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) +void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) { GLint xyzw[4] = {x, y, z, w}; glUniform4iv(location, 1, xyzw); } -void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v) { EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); @@ -4587,7 +4675,7 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) } } -void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -4605,7 +4693,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans } } -void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -4623,7 +4711,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans } } -void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -4641,7 +4729,7 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans } } -void __stdcall glUseProgram(GLuint program) +void GL_APIENTRY glUseProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -4674,7 +4762,7 @@ void __stdcall glUseProgram(GLuint program) } } -void __stdcall glValidateProgram(GLuint program) +void GL_APIENTRY glValidateProgram(GLuint program) { EVENT("(GLuint program = %d)", program); @@ -4701,7 +4789,7 @@ void __stdcall glValidateProgram(GLuint program) } } -void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) +void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x) { EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); @@ -4719,7 +4807,7 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) } } -void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4737,7 +4825,7 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) { EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); @@ -4755,7 +4843,7 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) } } -void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4773,7 +4861,7 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) { EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); @@ -4791,7 +4879,7 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) } } -void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4809,7 +4897,7 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); @@ -4827,7 +4915,7 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G } } -void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) +void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values) { EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); @@ -4844,7 +4932,7 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) } } -void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) +void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) { EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); @@ -4861,7 +4949,7 @@ void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) } } -void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) +void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) { EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", @@ -4936,7 +5024,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo } } -void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); @@ -4955,7 +5043,7 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) // OpenGL ES 3.0 functions -void __stdcall glReadBuffer(GLenum mode) +void GL_APIENTRY glReadBuffer(GLenum mode) { EVENT("(GLenum mode = 0x%X)", mode); @@ -4973,7 +5061,7 @@ void __stdcall glReadBuffer(GLenum mode) } } -void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) +void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) { EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, " "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices); @@ -4992,7 +5080,7 @@ void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize } } -void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, " @@ -5020,14 +5108,24 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5038,7 +5136,7 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL } } -void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " @@ -5073,14 +5171,24 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5091,7 +5199,7 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint } } -void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", @@ -5129,11 +5237,16 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL return; } - texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer); + gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, " @@ -5168,14 +5281,24 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); + gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); + gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5186,7 +5309,7 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna } } -void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " @@ -5233,16 +5356,26 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs case GL_TEXTURE_3D: { gl::Texture3D *texture = context->getTexture3D(); - texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, - format, imageSize, data); + gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture = context->getTexture2DArray(); - texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, - format, imageSize, data); + gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, context->getState().getUnpackState(), data); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -5253,7 +5386,7 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs } } -void __stdcall glGenQueries(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenQueries(GLsizei n, GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -5279,7 +5412,7 @@ void __stdcall glGenQueries(GLsizei n, GLuint* ids) } } -void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids) +void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -5305,7 +5438,7 @@ void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids) } } -GLboolean __stdcall glIsQuery(GLuint id) +GLboolean GL_APIENTRY glIsQuery(GLuint id) { EVENT("(GLuint id = %u)", id); @@ -5324,7 +5457,7 @@ GLboolean __stdcall glIsQuery(GLuint id) return GL_FALSE; } -void __stdcall glBeginQuery(GLenum target, GLuint id) +void GL_APIENTRY glBeginQuery(GLenum target, GLuint id) { EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); @@ -5351,7 +5484,7 @@ void __stdcall glBeginQuery(GLenum target, GLuint id) } } -void __stdcall glEndQuery(GLenum target) +void GL_APIENTRY glEndQuery(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -5378,7 +5511,7 @@ void __stdcall glEndQuery(GLenum target) } } -void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); @@ -5410,7 +5543,7 @@ void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params) } } -void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) { EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params); @@ -5468,7 +5601,7 @@ void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) } } -GLboolean __stdcall glUnmapBuffer(GLenum target) +GLboolean GL_APIENTRY glUnmapBuffer(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -5487,7 +5620,7 @@ GLboolean __stdcall glUnmapBuffer(GLenum target) return GL_FALSE; } -void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) +void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); @@ -5504,7 +5637,7 @@ void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) } } -void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs) +void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum* bufs) { gl::Context *context = gl::getNonLostContext(); if (context) @@ -5519,7 +5652,7 @@ void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs) } } -void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5537,7 +5670,7 @@ void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5555,7 +5688,7 @@ void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5573,7 +5706,7 @@ void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5591,7 +5724,7 @@ void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5609,7 +5742,7 @@ void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); @@ -5627,7 +5760,7 @@ void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra } } -void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, " "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)", @@ -5649,12 +5782,17 @@ void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr return; } - context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mask, filter); + gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, samples, internalformat, width, height); @@ -5674,11 +5812,12 @@ void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, return; } - context->setRenderbufferStorage(width, height, internalformat, samples); + gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); + renderbuffer->setStorage(width, height, internalformat, samples); } } -void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)", target, attachment, texture, level, layer); @@ -5695,27 +5834,20 @@ void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuin gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); ASSERT(framebuffer); - gl::Texture *textureObject = context->getTexture(texture); - GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE; - - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (texture != 0) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); - framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer); + gl::Texture *textureObject = context->getTexture(texture); + gl::ImageIndex index(textureObject->getTarget(), level, layer); + framebuffer->setTextureAttachment(attachment, textureObject, index); } else { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, layer); break; - case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, layer); break; - case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break; - } + framebuffer->setNULLAttachment(attachment); } } } -GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +GLvoid* GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", target, offset, length, access); @@ -5735,7 +5867,7 @@ GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le return NULL; } -void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); @@ -5752,7 +5884,7 @@ void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip } } -void __stdcall glBindVertexArray(GLuint array) +void GL_APIENTRY glBindVertexArray(GLuint array) { EVENT("(GLuint array = %u)", array); @@ -5779,7 +5911,7 @@ void __stdcall glBindVertexArray(GLuint array) } } -void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays) +void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint* arrays) { EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays); @@ -5808,7 +5940,7 @@ void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays) } } -void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays) +void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint* arrays) { EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays); @@ -5834,7 +5966,7 @@ void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays) } } -GLboolean __stdcall glIsVertexArray(GLuint array) +GLboolean GL_APIENTRY glIsVertexArray(GLuint array) { EVENT("(GLuint array = %u)", array); @@ -5860,7 +5992,7 @@ GLboolean __stdcall glIsVertexArray(GLuint array) return GL_FALSE; } -void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data) +void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint* data) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)", target, index, data); @@ -5941,7 +6073,7 @@ void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data) } } -void __stdcall glBeginTransformFeedback(GLenum primitiveMode) +void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode) { EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode); @@ -5986,7 +6118,7 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode) } } -void __stdcall glEndTransformFeedback(void) +void GL_APIENTRY glEndTransformFeedback(void) { EVENT("(void)"); @@ -6012,7 +6144,7 @@ void __stdcall glEndTransformFeedback(void) } } -void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)", target, index, buffer, offset, size); @@ -6090,7 +6222,7 @@ void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi } } -void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer) +void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", target, index, buffer); @@ -6146,7 +6278,7 @@ void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer) } } -void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) +void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) { EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)", program, count, varyings, bufferMode); @@ -6195,7 +6327,7 @@ void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const } } -void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) +void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) { EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, " "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", @@ -6234,7 +6366,7 @@ void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsiz } } -void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) +void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) { EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)", index, size, type, stride, pointer); @@ -6304,7 +6436,7 @@ void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLs } } -void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) { EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); @@ -6346,7 +6478,7 @@ void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) } } -void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) { EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)", index, pname, params); @@ -6388,7 +6520,7 @@ void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) } } -void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) { EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", index, x, y, z, w); @@ -6413,7 +6545,7 @@ void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint } } -void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) { EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", index, x, y, z, w); @@ -6438,7 +6570,7 @@ void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GL } } -void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v) +void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint* v) { EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v); @@ -6461,7 +6593,7 @@ void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v) } } -void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v) +void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint* v) { EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v); @@ -6484,7 +6616,7 @@ void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v) } } -void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params) +void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint* params) { EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)", program, location, params); @@ -6506,7 +6638,7 @@ void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params) } } -GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name) +GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name) { EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", program, name); @@ -6547,30 +6679,30 @@ GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name) return 0; } -void __stdcall glUniform1ui(GLint location, GLuint v0) +void GL_APIENTRY glUniform1ui(GLint location, GLuint v0) { glUniform1uiv(location, 1, &v0); } -void __stdcall glUniform2ui(GLint location, GLuint v0, GLuint v1) +void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1) { const GLuint xy[] = { v0, v1 }; glUniform2uiv(location, 1, xy); } -void __stdcall glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) { const GLuint xyz[] = { v0, v1, v2 }; glUniform3uiv(location, 1, xyz); } -void __stdcall glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) { const GLuint xyzw[] = { v0, v1, v2, v3 }; glUniform4uiv(location, 1, xyzw); } -void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", location, count, value); @@ -6588,7 +6720,7 @@ void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", location, count, value); @@ -6606,7 +6738,7 @@ void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)", location, count, value); @@ -6624,7 +6756,7 @@ void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint* value) { EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", location, count, value); @@ -6642,7 +6774,7 @@ void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value) } } -void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) +void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)", buffer, drawbuffer, value); @@ -6687,7 +6819,7 @@ void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val } } -void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) +void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)", buffer, drawbuffer, value); @@ -6724,7 +6856,7 @@ void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v } } -void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) +void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)", buffer, drawbuffer, value); @@ -6769,7 +6901,7 @@ void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v } } -void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)", buffer, drawbuffer, depth, stencil); @@ -6806,7 +6938,7 @@ void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G } } -const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index) +const GLubyte* GL_APIENTRY glGetStringi(GLenum name, GLuint index) { EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index); @@ -6837,7 +6969,7 @@ const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index) return NULL; } -void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)", readTarget, writeTarget, readOffset, writeOffset, size); @@ -6851,7 +6983,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp return; } - if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget)) + if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, writeTarget)) { context->recordError(gl::Error(GL_INVALID_ENUM)); return; @@ -6881,7 +7013,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp return; } - if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size) + if (readBuffer == writeBuffer && std::abs(readOffset - writeOffset) < size) { context->recordError(gl::Error(GL_INVALID_VALUE)); return; @@ -6900,7 +7032,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp } } -void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) +void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) { EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)", program, uniformCount, uniformNames, uniformIndices); @@ -6954,7 +7086,7 @@ void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const G } } -void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) +void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) { EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, uniformCount, uniformIndices, pname, params); @@ -7034,7 +7166,7 @@ void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const } } -GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) +GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) { EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName); @@ -7075,7 +7207,7 @@ GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlo return 0; } -void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) { EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, uniformBlockIndex, pname, params); @@ -7134,7 +7266,7 @@ void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde } } -void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) +void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) { EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockIndex, bufSize, length, uniformBlockName); @@ -7176,7 +7308,7 @@ void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn } } -void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)", program, uniformBlockIndex, uniformBlockBinding); @@ -7225,7 +7357,7 @@ void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G } } -void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) +void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) { EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)", mode, first, count, instanceCount); @@ -7244,7 +7376,7 @@ void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GL } } -void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) +void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) { EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)", mode, count, type, indices, instanceCount); @@ -7263,7 +7395,7 @@ void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, } } -GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags) +GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags) { EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags); @@ -7288,13 +7420,24 @@ GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags) return 0; } - return context->createFenceSync(condition); + GLsync fenceSync = context->createFenceSync(); + + gl::FenceSync *fenceSyncObject = context->getFenceSync(fenceSync); + gl::Error error = fenceSyncObject->set(condition); + if (error.isError()) + { + context->deleteFenceSync(fenceSync); + context->recordError(error); + return NULL; + } + + return fenceSync; } return NULL; } -GLboolean __stdcall glIsSync(GLsync sync) +GLboolean GL_APIENTRY glIsSync(GLsync sync) { EVENT("(GLsync sync = 0x%0.8p)", sync); @@ -7313,7 +7456,7 @@ GLboolean __stdcall glIsSync(GLsync sync) return GL_FALSE; } -void __stdcall glDeleteSync(GLsync sync) +void GL_APIENTRY glDeleteSync(GLsync sync) { EVENT("(GLsync sync = 0x%0.8p)", sync); @@ -7336,7 +7479,7 @@ void __stdcall glDeleteSync(GLsync sync) } } -GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags, timeout); @@ -7364,13 +7507,21 @@ GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeou return GL_WAIT_FAILED; } - return fenceSync->clientWait(flags, timeout); + GLenum result = GL_WAIT_FAILED; + gl::Error error = fenceSync->clientWait(flags, timeout, &result); + if (error.isError()) + { + context->recordError(error); + return GL_WAIT_FAILED; + } + + return result; } return GL_FALSE; } -void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags, timeout); @@ -7404,11 +7555,15 @@ void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) return; } - fenceSync->serverWait(); + gl::Error error = fenceSync->serverWait(flags, timeout); + if (error.isError()) + { + context->recordError(error); + } } } -void __stdcall glGetInteger64v(GLenum pname, GLint64* params) +void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64* params) { EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", pname, params); @@ -7440,7 +7595,7 @@ void __stdcall glGetInteger64v(GLenum pname, GLint64* params) } } -void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) { EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)", sync, pname, bufSize, length, values); @@ -7471,10 +7626,20 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* switch (pname) { case GL_OBJECT_TYPE: values[0] = static_cast(GL_SYNC_FENCE); break; - case GL_SYNC_STATUS: values[0] = static_cast(fenceSync->getStatus()); break; case GL_SYNC_CONDITION: values[0] = static_cast(fenceSync->getCondition()); break; case GL_SYNC_FLAGS: values[0] = 0; break; + case GL_SYNC_STATUS: + { + gl::Error error = fenceSync->getStatus(values); + if (error.isError()) + { + context->recordError(error); + return; + } + break; + } + default: context->recordError(gl::Error(GL_INVALID_ENUM)); return; @@ -7482,7 +7647,7 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* } } -void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) +void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)", target, index, data); @@ -7558,7 +7723,7 @@ void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) } } -void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", target, pname, params); @@ -7618,7 +7783,7 @@ void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa } } -void __stdcall glGenSamplers(GLsizei count, GLuint* samplers) +void GL_APIENTRY glGenSamplers(GLsizei count, GLuint* samplers) { EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers); @@ -7644,7 +7809,7 @@ void __stdcall glGenSamplers(GLsizei count, GLuint* samplers) } } -void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers) +void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint* samplers) { EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers); @@ -7670,7 +7835,7 @@ void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers) } } -GLboolean __stdcall glIsSampler(GLuint sampler) +GLboolean GL_APIENTRY glIsSampler(GLuint sampler) { EVENT("(GLuint sampler = %u)", sampler); @@ -7689,7 +7854,7 @@ GLboolean __stdcall glIsSampler(GLuint sampler) return GL_FALSE; } -void __stdcall glBindSampler(GLuint unit, GLuint sampler) +void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler) { EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler); @@ -7718,7 +7883,7 @@ void __stdcall glBindSampler(GLuint unit, GLuint sampler) } } -void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) +void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) { EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param); @@ -7751,12 +7916,12 @@ void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) } } -void __stdcall glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) +void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) { glSamplerParameteri(sampler, pname, *param); } -void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param); @@ -7789,12 +7954,12 @@ void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) } } -void __stdcall glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) +void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) { glSamplerParameterf(sampler, pname, *param); } -void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) { EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params); @@ -7822,7 +7987,7 @@ void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* para } } -void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) { EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params); @@ -7850,7 +8015,7 @@ void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* pa } } -void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor) +void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor) { EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor); @@ -7873,7 +8038,7 @@ void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor) } } -void __stdcall glBindTransformFeedback(GLenum target, GLuint id) +void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id) { EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); @@ -7916,7 +8081,7 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id) } } -void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) +void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) { EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids); @@ -7936,7 +8101,7 @@ void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) } } -void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint* ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -7956,7 +8121,7 @@ void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids) } } -GLboolean __stdcall glIsTransformFeedback(GLuint id) +GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id) { EVENT("(GLuint id = %u)", id); @@ -7975,7 +8140,7 @@ GLboolean __stdcall glIsTransformFeedback(GLuint id) return GL_FALSE; } -void __stdcall glPauseTransformFeedback(void) +void GL_APIENTRY glPauseTransformFeedback(void) { EVENT("(void)"); @@ -8002,7 +8167,7 @@ void __stdcall glPauseTransformFeedback(void) } } -void __stdcall glResumeTransformFeedback(void) +void GL_APIENTRY glResumeTransformFeedback(void) { EVENT("(void)"); @@ -8029,7 +8194,7 @@ void __stdcall glResumeTransformFeedback(void) } } -void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) +void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) { EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)", program, bufSize, length, binaryFormat, binary); @@ -8048,7 +8213,7 @@ void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* leng } } -void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) +void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) { EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", program, binaryFormat, binary, length); @@ -8067,7 +8232,7 @@ void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid } } -void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value) +void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value) { EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", program, pname, value); @@ -8086,7 +8251,7 @@ void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value) } } -void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) +void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) { EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)", target, numAttachments, attachments); @@ -8106,14 +8271,21 @@ void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, co } gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) + ASSERT(framebuffer); + + if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE) { - framebuffer->invalidate(context->getCaps(), numAttachments, attachments); + gl::Error error = framebuffer->invalidate(context->getCaps(), numAttachments, attachments); + if (error.isError()) + { + context->recordError(error); + return; + } } } } -void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, " "GLint y = %d, GLsizei width = %d, GLsizei height = %d)", @@ -8134,14 +8306,21 @@ void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, } gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) + ASSERT(framebuffer); + + if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE) { - framebuffer->invalidateSub(context->getCaps(), numAttachments, attachments, x, y, width, height); + gl::Error error = framebuffer->invalidateSub(numAttachments, attachments, x, y, width, height); + if (error.isError()) + { + context->recordError(error); + return; + } } } } -void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, levels, internalformat, width, height); @@ -8165,14 +8344,24 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform case GL_TEXTURE_2D: { gl::Texture2D *texture2d = context->getTexture2D(); - texture2d->storage(levels, internalformat, width, height); + gl::Error error = texture2d->storage(levels, internalformat, width, height); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_CUBE_MAP: { gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); - textureCube->storage(levels, internalformat, width); + gl::Error error = textureCube->storage(levels, internalformat, width); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -8183,7 +8372,7 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform } } -void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " "GLsizei height = %d, GLsizei depth = %d)", @@ -8208,14 +8397,24 @@ void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalform case GL_TEXTURE_3D: { gl::Texture3D *texture3d = context->getTexture3D(); - texture3d->storage(levels, internalformat, width, height, depth); + gl::Error error = texture3d->storage(levels, internalformat, width, height, depth); + if (error.isError()) + { + context->recordError(error); + return; + } } break; case GL_TEXTURE_2D_ARRAY: { gl::Texture2DArray *texture2darray = context->getTexture2DArray(); - texture2darray->storage(levels, internalformat, width, height, depth); + gl::Error error = texture2darray->storage(levels, internalformat, width, height, depth); + if (error.isError()) + { + context->recordError(error); + return; + } } break; @@ -8225,7 +8424,7 @@ void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalform } } -void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) { EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, " "GLint* params = 0x%0.8p)", @@ -8281,7 +8480,7 @@ void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenu // Extension functions -void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, +void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " @@ -8299,12 +8498,17 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi return; } - context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mask, filter); + gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, +void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " @@ -8315,7 +8519,7 @@ void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat UNIMPLEMENTED(); // FIXME } -void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, +void GL_APIENTRY glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) { EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)", @@ -8340,15 +8544,16 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l return; } - if (!programBinary->save(binaryFormat, binary, bufSize, length)) + gl::Error error = programBinary->save(binaryFormat, binary, bufSize, length); + if (error.isError()) { - context->recordError(gl::Error(GL_INVALID_OPERATION)); + context->recordError(error); return; } } } -void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, +void GL_APIENTRY glProgramBinaryOES(GLuint program, GLenum binaryFormat, const void *binary, GLint length) { EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", @@ -8371,11 +8576,16 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, return; } - context->setProgramBinary(program, binaryFormat, binary, length); + gl::Error error = context->setProgramBinary(program, binaryFormat, binary, length); + if (error.isError()) + { + context->recordError(error); + return; + } } } -void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) +void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs) { EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs); @@ -8388,6 +8598,8 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) return; } + ASSERT(context->getState().getDrawFramebuffer()); + if (context->getState().getDrawFramebuffer()->id() == 0) { if (n != 1) @@ -8416,6 +8628,7 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) } gl::Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + ASSERT(framebuffer); for (unsigned int colorAttachment = 0; colorAttachment < static_cast(n); colorAttachment++) { @@ -8429,7 +8642,7 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) } } -void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params) +void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, void** params) { EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); @@ -8461,7 +8674,7 @@ void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params } } -void * __stdcall glMapBufferOES(GLenum target, GLenum access) +void * GL_APIENTRY glMapBufferOES(GLenum target, GLenum access) { EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access); @@ -8507,7 +8720,7 @@ void * __stdcall glMapBufferOES(GLenum target, GLenum access) return NULL; } -GLboolean __stdcall glUnmapBufferOES(GLenum target) +GLboolean GL_APIENTRY glUnmapBufferOES(GLenum target) { EVENT("(GLenum target = 0x%X)", target); @@ -8543,7 +8756,7 @@ GLboolean __stdcall glUnmapBufferOES(GLenum target) return GL_FALSE; } -void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", target, offset, length, access); @@ -8638,7 +8851,7 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr return NULL; } -void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length) +void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length) { EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); @@ -8686,7 +8899,7 @@ void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsi } } -__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname) +__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname) { struct Extension { @@ -8744,7 +8957,7 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char * // Non-public functions used by EGL -bool __stdcall glBindTexImage(egl::Surface *surface) +bool EGLAPIENTRY glBindTexImage(egl::Surface *surface) { EVENT("(egl::Surface* surface = 0x%0.8p)", surface); diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp index 51447e273a..00f63ae079 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.cpp +++ b/src/3rdparty/angle/src/libGLESv2/main.cpp @@ -11,24 +11,42 @@ #include "common/tls.h" -#if defined(ANGLE_PLATFORM_WINRT) -__declspec(thread) -#endif -static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; +static TLSIndex currentTLS = TLS_INVALID_INDEX; namespace gl { +// TODO(kbr): figure out how these are going to be managed on +// non-Windows platforms. These routines would need to be exported +// from ANGLE and called cooperatively when users create and destroy +// threads -- or the initialization of the TLS index, and allocation +// of thread-local data, will have to be done lazily. Will have to use +// destructor function with pthread_create_key on POSIX platforms to +// clean up thread-local data. + +// Call this exactly once at process startup. +bool CreateThreadLocalIndex() +{ + currentTLS = CreateTLSIndex(); + if (currentTLS == TLS_INVALID_INDEX) + { + return false; + } + return true; +} + +// Call this exactly once at process shutdown. +void DestroyThreadLocalIndex() +{ + DestroyTLSIndex(currentTLS); + currentTLS = TLS_INVALID_INDEX; +} + +// Call this upon thread startup. Current *AllocateCurrent() { -#if defined(ANGLE_PLATFORM_WINRT) - if (currentTLS == TLS_OUT_OF_INDEXES) - { - currentTLS = CreateTLSIndex(); - } -#endif - ASSERT(currentTLS != TLS_OUT_OF_INDEXES); - if (currentTLS == TLS_OUT_OF_INDEXES) + ASSERT(currentTLS != TLS_INVALID_INDEX); + if (currentTLS == TLS_INVALID_INDEX) { return NULL; } @@ -46,14 +64,9 @@ Current *AllocateCurrent() return current; } +// Call this upon thread shutdown. void DeallocateCurrent() { -#if defined(ANGLE_PLATFORM_WINRT) - if (currentTLS == TLS_OUT_OF_INDEXES) - { - return; - } -#endif Current *current = reinterpret_cast(GetTLSValue(currentTLS)); SafeDelete(current); SetTLSValue(currentTLS, NULL); @@ -61,22 +74,21 @@ void DeallocateCurrent() } -#ifndef QT_OPENGL_ES_2_ANGLE_STATIC - +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC) extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: { -#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain - return DisableThreadLibraryCalls(instance); -#endif - currentTLS = CreateTLSIndex(); - if (currentTLS == TLS_OUT_OF_INDEXES) + if (!gl::CreateThreadLocalIndex()) { return FALSE; } + +#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS + gl::InitializeDebugAnnotations(); +#endif } // Fall through to initialize index case DLL_THREAD_ATTACH: @@ -91,9 +103,11 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved break; case DLL_PROCESS_DETACH: { -#if !defined(ANGLE_PLATFORM_WINRT) gl::DeallocateCurrent(); - DestroyTLSIndex(currentTLS); + gl::DestroyThreadLocalIndex(); + +#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS + gl::UninitializeDebugAnnotations(); #endif } break; @@ -103,8 +117,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved return TRUE; } - -#endif // !QT_OPENGL_ES_2_ANGLE_STATIC +#endif // ANGLE_PLATFORM_WINDOWS && !QT_OPENGL_ES_2_ANGLE_STATIC namespace gl { @@ -152,7 +165,7 @@ Context *getNonLostContext() { if (context->isContextLost()) { - gl::error(GL_OUT_OF_MEMORY); + context->recordError(Error(GL_OUT_OF_MEMORY, "Context has been lost.")); return NULL; } else @@ -170,32 +183,4 @@ egl::Display *getDisplay() return current->display; } -// Records an error code -void error(GLenum errorCode) -{ - gl::Context *context = glGetCurrentContext(); - context->recordError(Error(errorCode)); - - switch (errorCode) - { - case GL_INVALID_ENUM: - TRACE("\t! Error generated: invalid enum\n"); - break; - case GL_INVALID_VALUE: - TRACE("\t! Error generated: invalid value\n"); - break; - case GL_INVALID_OPERATION: - TRACE("\t! Error generated: invalid operation\n"); - break; - case GL_OUT_OF_MEMORY: - TRACE("\t! Error generated: out of memory\n"); - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - TRACE("\t! Error generated: invalid framebuffer operation\n"); - break; - default: UNREACHABLE(); - } } - -} - diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h index c30ad3375c..dff02787f5 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.h +++ b/src/3rdparty/angle/src/libGLESv2/main.h @@ -14,14 +14,11 @@ #include #include -#ifndef Sleep -#define Sleep(ms) WaitForSingleObjectEx(GetCurrentThread(), ms, FALSE) -#endif - namespace egl { class Display; class Surface; +class AttributeMap; } namespace gl @@ -40,16 +37,6 @@ Context *getContext(); Context *getNonLostContext(); egl::Display *getDisplay(); -void error(GLenum errorCode); - -template -const T &error(GLenum errorCode, const T &returnValue) -{ - error(errorCode); - - return returnValue; -} - } namespace rx @@ -64,11 +51,11 @@ gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, void glDestroyContext(gl::Context *context); void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface); gl::Context *glGetCurrentContext(); -rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType); +rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap); void glDestroyRenderer(rx::Renderer *renderer); -__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname); -bool __stdcall glBindTexImage(egl::Surface *surface); +__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname); +bool EGLAPIENTRY glBindTexImage(egl::Surface *surface); } #endif // LIBGLESV2_MAIN_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h index f0b5f02227..c031effabd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h @@ -12,6 +12,8 @@ #include "common/angleutils.h" #include "libGLESv2/Buffer.h" +#include + namespace rx { @@ -21,7 +23,6 @@ class BufferImpl virtual ~BufferImpl() { } virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0; - virtual void *getData() = 0; virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0; virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0; virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h index d54e6becd3..1dd46785d9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h @@ -4,29 +4,47 @@ // found in the LICENSE file. // -// FenceImpl.h: Defines the rx::FenceImpl class. +// FenceImpl.h: Defines the rx::FenceNVImpl and rx::FenceSyncImpl classes. #ifndef LIBGLESV2_RENDERER_FENCEIMPL_H_ #define LIBGLESV2_RENDERER_FENCEIMPL_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" +#include "angle_gl.h" + namespace rx { -class FenceImpl +class FenceNVImpl { public: - FenceImpl() { }; - virtual ~FenceImpl() { }; + FenceNVImpl() { }; + virtual ~FenceNVImpl() { }; - virtual bool isSet() const = 0; - virtual void set() = 0; - virtual bool test(bool flushCommandBuffer) = 0; - virtual bool hasError() const = 0; + virtual gl::Error set() = 0; + virtual gl::Error test(bool flushCommandBuffer, GLboolean *outFinished) = 0; + virtual gl::Error finishFence(GLboolean *outFinished) = 0; private: - DISALLOW_COPY_AND_ASSIGN(FenceImpl); + DISALLOW_COPY_AND_ASSIGN(FenceNVImpl); +}; + +class FenceSyncImpl +{ + public: + FenceSyncImpl() { }; + virtual ~FenceSyncImpl() { }; + + virtual gl::Error set() = 0; + virtual gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) = 0; + virtual gl::Error serverWait(GLbitfield flags, GLuint64 timeout) = 0; + virtual gl::Error getStatus(GLint *outResult) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(FenceSyncImpl); }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp index 370b086233..5b9b75f562 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp @@ -4,18 +4,20 @@ // found in the LICENSE file. // -// Image.h: Implements the rx::Image class, an abstract base class for the +// Image.h: Implements the rx::Image class, an abstract base class for the // renderer-specific classes which will define the interface to the underlying // surfaces or resources. #include "libGLESv2/renderer/Image.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/main.h" namespace rx { Image::Image() { - mWidth = 0; + mWidth = 0; mHeight = 0; mDepth = 0; mInternalFormat = GL_NONE; @@ -25,4 +27,20 @@ Image::Image() mDirty = false; } +gl::Error Image::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, gl::Framebuffer *source) +{ + gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer(); + ASSERT(colorbuffer); + + RenderTarget *renderTarget = NULL; + gl::Error error = GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) + { + return error; + } + + ASSERT(renderTarget); + return copy(xoffset, yoffset, zoffset, area, renderTarget); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h index 3bfc663762..9071a88c67 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// Image.h: Defines the rx::Image class, an abstract base class for the +// Image.h: Defines the rx::Image class, an abstract base class for the // renderer-specific classes which will define the interface to the underlying // surfaces or resources. @@ -12,18 +12,22 @@ #define LIBGLESV2_RENDERER_IMAGE_H_ #include "common/debug.h" +#include "libGLESv2/Error.h" #include namespace gl { class Framebuffer; +struct Rectangle; +struct ImageIndex; } namespace rx { - -class Renderer; +class RendererD3D; +class RenderTarget; +class TextureStorage; class Image { @@ -43,14 +47,17 @@ class Image void markClean() {mDirty = false;} virtual bool isDirty() const = 0; - virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0; + virtual bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0; - virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input) = 0; - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input) = 0; + virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) = 0; + virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input) = 0; - virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; + gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, gl::Framebuffer *source); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) = 0; + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, + const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0; protected: GLsizei mWidth; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp index f68ac383de..d472e1499e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp @@ -111,11 +111,7 @@ IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c) bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const { -#if defined(_MSC_VER) && _MSC_VER < 1600 - return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count); -#else return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count); -#endif } IndexRangeCache::IndexBounds::IndexBounds() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp new file mode 100644 index 0000000000..f9fcad38a4 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp @@ -0,0 +1,146 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl. + +#include "libGLESv2/renderer/ProgramImpl.h" + +#include "common/utilities.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +namespace +{ + +unsigned int ParseAndStripArrayIndex(std::string* name) +{ + unsigned int subscript = GL_INVALID_INDEX; + + // Strip any trailing array operator and retrieve the subscript + size_t open = name->find_last_of('['); + size_t close = name->find_last_of(']'); + if (open != std::string::npos && close == name->length() - 1) + { + subscript = atoi(name->substr(open + 1).c_str()); + name->erase(open); + } + + return subscript; +} + +} + +ProgramImpl::~ProgramImpl() +{ + // Ensure that reset was called by the inherited class during destruction + ASSERT(mUniformIndex.size() == 0); +} + +gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const +{ + ASSERT(location >= 0 && static_cast(location) < mUniformIndex.size()); + return mUniforms[mUniformIndex[location].index]; +} + +gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const +{ + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + if (mUniforms[uniformIndex]->name == name) + { + return mUniforms[uniformIndex]; + } + } + + return NULL; +} + +gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const +{ + ASSERT(blockIndex < mUniformBlocks.size()); + return mUniformBlocks[blockIndex]; +} + +GLint ProgramImpl::getUniformLocation(std::string name) +{ + unsigned int subscript = ParseAndStripArrayIndex(&name); + + unsigned int numUniforms = mUniformIndex.size(); + for (unsigned int location = 0; location < numUniforms; location++) + { + if (mUniformIndex[location].name == name) + { + const int index = mUniformIndex[location].index; + const bool isArray = mUniforms[index]->isArray(); + + if ((isArray && mUniformIndex[location].element == subscript) || + (subscript == GL_INVALID_INDEX)) + { + return location; + } + } + } + + return -1; +} + +GLuint ProgramImpl::getUniformIndex(std::string name) +{ + unsigned int subscript = ParseAndStripArrayIndex(&name); + + // The app is not allowed to specify array indices other than 0 for arrays of basic types + if (subscript != 0 && subscript != GL_INVALID_INDEX) + { + return GL_INVALID_INDEX; + } + + unsigned int numUniforms = mUniforms.size(); + for (unsigned int index = 0; index < numUniforms; index++) + { + if (mUniforms[index]->name == name) + { + if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX) + { + return index; + } + } + } + + return GL_INVALID_INDEX; +} + +GLuint ProgramImpl::getUniformBlockIndex(std::string name) const +{ + unsigned int subscript = ParseAndStripArrayIndex(&name); + + unsigned int numUniformBlocks = mUniformBlocks.size(); + for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) + { + const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex]; + if (uniformBlock.name == name) + { + const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); + if (subscript == uniformBlock.elementIndex || arrayElementZero) + { + return blockIndex; + } + } + } + + return GL_INVALID_INDEX; +} + +void ProgramImpl::reset() +{ + SafeDeleteContainer(mUniforms); + mUniformIndex.clear(); + SafeDeleteContainer(mUniformBlocks); + mTransformFeedbackLinkedVaryings.clear(); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h index ba0955fdf8..6aaa23cf89 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h @@ -13,44 +13,113 @@ #include "libGLESv2/BinaryStream.h" #include "libGLESv2/Constants.h" #include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Shader.h" +#include "libGLESv2/renderer/Renderer.h" + +#include namespace rx { -class DynamicHLSL; -class Renderer; - class ProgramImpl { -public: - virtual ~ProgramImpl() { } + public: + ProgramImpl() { } + virtual ~ProgramImpl(); - // TODO: Temporary interfaces to ease migration. Remove soon! - virtual Renderer *getRenderer() = 0; - virtual DynamicHLSL *getDynamicHLSL() = 0; - virtual const std::vector &getPixelShaderKey() = 0; + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getUniformIndices() const { return mUniformIndex; } + const std::vector &getUniformBlocks() const { return mUniformBlocks; } + const std::vector &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; } + const sh::Attribute *getShaderAttributes() const { return mShaderAttributes; } + + std::vector &getUniforms() { return mUniforms; } + std::vector &getUniformIndices() { return mUniformIndex; } + std::vector &getUniformBlocks() { return mUniformBlocks; } + std::vector &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; } + sh::Attribute *getShaderAttributes() { return mShaderAttributes; } + + gl::LinkedUniform *getUniformByLocation(GLint location) const; + gl::LinkedUniform *getUniformByName(const std::string &name) const; + gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const; + + GLint getUniformLocation(std::string name); + GLuint getUniformIndex(std::string name); + GLuint getUniformBlockIndex(std::string name) const; + + virtual bool usesPointSize() const = 0; + virtual int getShaderVersion() const = 0; + virtual GLenum getTransformFeedbackBufferMode() const = 0; virtual GLenum getBinaryFormat() = 0; - virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; - virtual bool save(gl::BinaryOutputStream *stream) = 0; + virtual gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; + virtual gl::Error save(gl::BinaryOutputStream *stream) = 0; - virtual rx::ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector &outputSignature, - const std::vector &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) = 0; - virtual rx::ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog, - const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], - const sh::Attribute shaderAttributes[], - const std::vector &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) = 0; + virtual gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog, + gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode, + int *registers, std::vector *linkedVaryings, + std::map *outputVariables) = 0; - virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, int *registers, - std::vector *linkedVaryings, std::map *outputVariables) = 0; + virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) = 0; + virtual void setUniform1iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform2iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform3iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform4iv(GLint location, GLsizei count, const GLint *v) = 0; + virtual void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) = 0; + virtual void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; - virtual void initializeUniformStorage(const std::vector &uniforms) = 0; + virtual void getUniformfv(GLint location, GLfloat *params) = 0; + virtual void getUniformiv(GLint location, GLint *params) = 0; + virtual void getUniformuiv(GLint location, GLuint *params) = 0; - virtual void reset() = 0; + virtual void reset(); + + // TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to + // determine if they can be removed from this interface. + virtual GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const = 0; + virtual GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const = 0; + virtual GLint getUsedSamplerRange(gl::SamplerType type) const = 0; + virtual void updateSamplerMapping() = 0; + virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0; + + virtual gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + int registers) = 0; + + virtual bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps) = 0; + virtual bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, + const gl::Caps &caps) = 0; + + virtual gl::Error applyUniforms() = 0; + virtual gl::Error applyUniformBuffers(const std::vector boundBuffers, const gl::Caps &caps) = 0; + virtual bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, + unsigned int registerIndex, const gl::Caps &caps) = 0; + + protected: + DISALLOW_COPY_AND_ASSIGN(ProgramImpl); + + std::vector mUniforms; + std::vector mUniformIndex; + std::vector mUniformBlocks; + std::vector mTransformFeedbackLinkedVaryings; + + sh::Attribute mShaderAttributes[gl::MAX_VERTEX_ATTRIBS]; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp new file mode 100644 index 0000000000..857fdc9dae --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderTarget.cpp: Implements serial handling for rx::RenderTarget + +#include "libGLESv2/renderer/RenderTarget.h" + +namespace rx +{ +unsigned int RenderTarget::mCurrentSerial = 1; + +RenderTarget::RenderTarget() + : mSerial(issueSerials(1)) +{ +} + +RenderTarget::~RenderTarget() +{ +} + +unsigned int RenderTarget::getSerial() const +{ + return mSerial; +} + +unsigned int RenderTarget::issueSerials(unsigned int count) +{ + unsigned int firstSerial = mCurrentSerial; + mCurrentSerial += count; + return firstSerial; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h index 44637ec7de..3bdfb0cc98 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h @@ -18,28 +18,22 @@ namespace rx class RenderTarget { public: - RenderTarget() - { - mWidth = 0; - mHeight = 0; - mDepth = 0; - mInternalFormat = GL_NONE; - mActualFormat = GL_NONE; - mSamples = 0; - } + RenderTarget(); + virtual ~RenderTarget(); - virtual ~RenderTarget() {}; - - GLsizei getWidth() const { return mWidth; } - GLsizei getHeight() const { return mHeight; } - GLsizei getDepth() const { return mDepth; } - GLenum getInternalFormat() const { return mInternalFormat; } - GLenum getActualFormat() const { return mActualFormat; } - GLsizei getSamples() const { return mSamples; } - gl::Extents getExtents() const { return gl::Extents(mWidth, mHeight, mDepth); } + virtual GLsizei getWidth() const = 0; + virtual GLsizei getHeight() const = 0; + virtual GLsizei getDepth() const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual GLenum getActualFormat() const = 0; + virtual GLsizei getSamples() const = 0; + gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); } virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) = 0; + virtual unsigned int getSerial() const; + static unsigned int issueSerials(unsigned int count); + struct Desc { GLsizei width; GLsizei height; @@ -47,16 +41,11 @@ class RenderTarget GLenum format; }; - protected: - GLsizei mWidth; - GLsizei mHeight; - GLsizei mDepth; - GLenum mInternalFormat; - GLenum mActualFormat; - GLsizei mSamples; - private: DISALLOW_COPY_AND_ASSIGN(RenderTarget); + + const unsigned int mSerial; + static unsigned int mCurrentSerial; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp new file mode 100644 index 0000000000..770ae8e9c6 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp @@ -0,0 +1,21 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferImpl.h: Implements the shared methods of the abstract class gl::RenderbufferImpl + +#include "libGLESv2/renderer/RenderbufferImpl.h" + +namespace rx +{ +RenderbufferImpl::RenderbufferImpl() +{ +} + +RenderbufferImpl::~RenderbufferImpl() +{ +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h new file mode 100644 index 0000000000..52e070f1d3 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h @@ -0,0 +1,41 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferImpl.h: Defines the abstract class gl::RenderbufferImpl + +#ifndef LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_ +#define LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_ + +#include "angle_gl.h" + +#include "libGLESv2/Error.h" + +#include "common/angleutils.h" + +namespace rx +{ + +class RenderbufferImpl +{ + public: + RenderbufferImpl(); + virtual ~RenderbufferImpl() = 0; + + virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) = 0; + + virtual GLsizei getWidth() const = 0; + virtual GLsizei getHeight() const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual GLenum getActualFormat() const = 0; + virtual GLsizei getSamples() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderbufferImpl); +}; + +} + +#endif // LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp index 910d0285f1..df3dae1e38 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp @@ -6,11 +6,12 @@ // Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances. -#include "libGLESv2/main.h" -#include "libGLESv2/Program.h" -#include "libGLESv2/renderer/Renderer.h" #include "common/utilities.h" -#include "libGLESv2/Shader.h" +#include "libEGL/AttributeMap.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/Renderer.h" + +#include #if defined (ANGLE_ENABLE_D3D9) #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" @@ -29,15 +30,12 @@ #define ANGLE_DEFAULT_D3D11 0 #endif -#include - namespace rx { -Renderer::Renderer(egl::Display *display) - : mDisplay(display), - mCapsInitialized(false), - mCurrentClientVersion(2) +Renderer::Renderer() + : mCapsInitialized(false), + mWorkaroundsInitialized(false) { } @@ -78,12 +76,23 @@ const gl::Extensions &Renderer::getRendererExtensions() const return mExtensions; } -typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, EGLint); +const Workarounds &Renderer::getWorkarounds() const +{ + if (!mWorkaroundsInitialized) + { + mWorkarounds = generateWorkarounds(); + mWorkaroundsInitialized = true; + } + + return mWorkarounds; +} + +typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, const egl::AttributeMap &); template -Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType) +Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attributes) { - return new RendererType(display, nativeDisplay, requestedDisplayType); + return new RendererType(display, nativeDisplay, attributes); } } @@ -91,15 +100,16 @@ Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDispl extern "C" { -rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType) +rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap) { std::vector rendererCreationFunctions; + EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + # if defined(ANGLE_ENABLE_D3D11) if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE || - requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE || - requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE) + requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) { rendererCreationFunctions.push_back(rx::CreateRenderer); } @@ -138,7 +148,7 @@ rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativ for (size_t i = 0; i < rendererCreationFunctions.size(); i++) { - rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, requestedDisplayType); + rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, attribMap); if (renderer->initialize() == EGL_SUCCESS) { return renderer; @@ -155,7 +165,8 @@ rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativ void glDestroyRenderer(rx::Renderer *renderer) { - delete renderer; + ASSERT(renderer); + SafeDelete(renderer); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h index b2249741ab..b85895a938 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h @@ -10,10 +10,13 @@ #ifndef LIBGLESV2_RENDERER_RENDERER_H_ #define LIBGLESV2_RENDERER_RENDERER_H_ -#include "libGLESv2/Uniform.h" -#include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" #include "libGLESv2/Error.h" +#include "libGLESv2/Uniform.h" +#include "libGLESv2/angletypes.h" +#include "libGLESv2/renderer/Workarounds.h" +#include "common/NativeWindow.h" +#include "common/mathutil.h" #include @@ -32,37 +35,26 @@ class Display; namespace gl { -class InfoLog; -class ProgramBinary; -struct LinkedVarying; -struct VertexAttribute; class Buffer; -class Texture; class Framebuffer; -struct VertexAttribCurrentValueData; +struct Data; } namespace rx { -class TextureStorage; -class VertexBuffer; -class IndexBuffer; class QueryImpl; -class FenceImpl; +class FenceNVImpl; +class FenceSyncImpl; class BufferImpl; class VertexArrayImpl; -class BufferStorage; -struct TranslatedIndexData; class ShaderImpl; class ProgramImpl; -class ShaderExecutable; -class SwapChain; -class RenderTarget; -class Image; -class TextureStorage; -class UniformStorage; class TextureImpl; class TransformFeedbackImpl; +class RenderbufferImpl; +struct TranslatedIndexData; +struct Workarounds; +class SwapChain; struct ConfigDesc { @@ -73,6 +65,110 @@ struct ConfigDesc bool es3Capable; }; +class Renderer +{ + public: + Renderer(); + virtual ~Renderer(); + + virtual EGLint initialize() = 0; + virtual bool resetDevice() = 0; + + virtual int generateConfigs(ConfigDesc **configDescList) = 0; + virtual void deleteConfigs(ConfigDesc *configDescList) = 0; + + virtual gl::Error sync(bool block) = 0; + + virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, + GLint first, GLsizei count, GLsizei instances) = 0; + virtual gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei instances, + const RangeUI &indexRange) = 0; + + virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0; + virtual gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0; + virtual gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0; + virtual gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values) = 0; + virtual gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0; + + virtual gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, void* pixels) = 0; + + virtual gl::Error blitFramebuffer(const gl::Data &data, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) = 0; + + // TODO(jmadill): caps? and virtual for egl::Display + virtual bool getShareHandleSupport() const = 0; + virtual bool getPostSubBufferSupport() const = 0; + + // Shader creation + virtual ShaderImpl *createShader(const gl::Data &data, GLenum type) = 0; + virtual ProgramImpl *createProgram() = 0; + + // Shader operations + virtual void releaseShaderCompiler() = 0; + + // Texture creation + virtual TextureImpl *createTexture(GLenum target) = 0; + + // Renderbuffer creation + virtual RenderbufferImpl *createRenderbuffer() = 0; + virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth) = 0; + + // Buffer creation + virtual BufferImpl *createBuffer() = 0; + + // Vertex Array creation + virtual VertexArrayImpl *createVertexArray() = 0; + + // Query and Fence creation + virtual QueryImpl *createQuery(GLenum type) = 0; + virtual FenceNVImpl *createFenceNV() = 0; + virtual FenceSyncImpl *createFenceSync() = 0; + + // Transform Feedback creation + virtual TransformFeedbackImpl *createTransformFeedback() = 0; + + // lost device + //TODO(jmadill): investigate if this stuff is necessary in GL + virtual void notifyDeviceLost() = 0; + virtual bool isDeviceLost() = 0; + virtual bool testDeviceLost(bool notify) = 0; + virtual bool testDeviceResettable() = 0; + + virtual DWORD getAdapterVendor() const = 0; + virtual std::string getRendererDescription() const = 0; + virtual GUID getAdapterIdentifier() const = 0; + + // Renderer capabilities (virtual because of egl::Display) + virtual const gl::Caps &getRendererCaps() const; + const gl::TextureCapsMap &getRendererTextureCaps() const; + virtual const gl::Extensions &getRendererExtensions() const; + const Workarounds &getWorkarounds() const; + + // TODO(jmadill): needed by egl::Display, probably should be removed + virtual int getMajorShaderModel() const = 0; + virtual int getMinSwapInterval() const = 0; + virtual int getMaxSwapInterval() const = 0; + virtual bool getLUID(LUID *adapterLuid) const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(Renderer); + + virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0; + virtual Workarounds generateWorkarounds() const = 0; + + mutable bool mCapsInitialized; + mutable gl::Caps mCaps; + mutable gl::TextureCapsMap mTextureCaps; + mutable gl::Extensions mExtensions; + + mutable bool mWorkaroundsInitialized; + mutable Workarounds mWorkarounds; +}; + struct dx_VertexConstants { float depthRange[4]; @@ -93,176 +189,5 @@ enum ShaderType SHADER_GEOMETRY }; -class Renderer -{ - public: - explicit Renderer(egl::Display *display); - virtual ~Renderer(); - - virtual EGLint initialize() = 0; - virtual bool resetDevice() = 0; - - virtual int generateConfigs(ConfigDesc **configDescList) = 0; - virtual void deleteConfigs(ConfigDesc *configDescList) = 0; - - virtual void sync(bool block) = 0; - - virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; - - virtual gl::Error generateSwizzle(gl::Texture *texture) = 0; - virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0; - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; - - virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; - - virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0; - virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) = 0; - virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) = 0; - - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0; - virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport) = 0; - - virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer) = 0; - virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) = 0; - virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary) = 0; - virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0; - virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) = 0; - virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0; - virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0; - - virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0; - virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; - - virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0; - - virtual void markAllStateDirty() = 0; - - // lost device - virtual void notifyDeviceLost() = 0; - virtual bool isDeviceLost() = 0; - virtual bool testDeviceLost(bool notify) = 0; - virtual bool testDeviceResettable() = 0; - - // Renderer capabilities (virtual because it is used by egl::Display, do not override) - virtual const gl::Caps &getRendererCaps() const; - virtual const gl::TextureCapsMap &getRendererTextureCaps() const; - virtual const gl::Extensions &getRendererExtensions() const; - - virtual DWORD getAdapterVendor() const = 0; - virtual std::string getRendererDescription() const = 0; - virtual GUID getAdapterIdentifier() const = 0; - - virtual unsigned int getReservedVertexUniformVectors() const = 0; - virtual unsigned int getReservedFragmentUniformVectors() const = 0; - virtual unsigned int getReservedVertexUniformBuffers() const = 0; - virtual unsigned int getReservedFragmentUniformBuffers() const = 0; - virtual bool getShareHandleSupport() const = 0; - virtual bool getPostSubBufferSupport() const = 0; - - virtual int getMajorShaderModel() const = 0; - virtual int getMinSwapInterval() const = 0; - virtual int getMaxSwapInterval() const = 0; - - // Pixel operations - virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) = 0; - virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) = 0; - virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) = 0; - virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) = 0; - - virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0; - virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0; - virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; - virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; - - virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) = 0; - - virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0; - - // RenderTarget creation - virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0; - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples) = 0; - - // Shader creation - virtual ShaderImpl *createShader(GLenum type) = 0; - virtual ProgramImpl *createProgram() = 0; - - // Shader operations - virtual void releaseShaderCompiler() = 0; - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers) = 0; - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround) = 0; - virtual UniformStorage *createUniformStorage(size_t storageSize) = 0; - - // Image operations - virtual Image *createImage() = 0; - virtual void generateMipmap(Image *dest, Image *source) = 0; - virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0; - virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0; - virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0; - virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; - virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; - - // Texture creation - virtual TextureImpl *createTexture(GLenum target) = 0; - - // Buffer creation - virtual BufferImpl *createBuffer() = 0; - virtual VertexBuffer *createVertexBuffer() = 0; - virtual IndexBuffer *createIndexBuffer() = 0; - - // Vertex Array creation - virtual VertexArrayImpl *createVertexArray() = 0; - - // Query and Fence creation - virtual QueryImpl *createQuery(GLenum type) = 0; - virtual FenceImpl *createFence() = 0; - - // Transform Feedback creation - virtual TransformFeedbackImpl* createTransformFeedback() = 0; - - // Current GLES client version - void setCurrentClientVersion(int clientVersion) { mCurrentClientVersion = clientVersion; } - int getCurrentClientVersion() const { return mCurrentClientVersion; } - - // Buffer-to-texture and Texture-to-buffer copies - virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; - virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0; - - virtual bool getLUID(LUID *adapterLuid) const = 0; - virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0; - virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0; - - protected: - egl::Display *mDisplay; - - private: - DISALLOW_COPY_AND_ASSIGN(Renderer); - - virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0; - - mutable bool mCapsInitialized; - mutable gl::Caps mCaps; - mutable gl::TextureCapsMap mTextureCaps; - mutable gl::Extensions mExtensions; - - int mCurrentClientVersion; -}; - } #endif // LIBGLESV2_RENDERER_RENDERER_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h index f17195673d..f1a96d74fb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h @@ -40,10 +40,21 @@ class ShaderExecutable return mFunctionBuffer.size(); } + const std::string &getDebugInfo() const + { + return mDebugInfo; + } + + void appendDebugInfo(const std::string &info) + { + mDebugInfo += info; + } + private: DISALLOW_COPY_AND_ASSIGN(ShaderExecutable); std::vector mFunctionBuffer; + std::string mDebugInfo; }; class UniformStorage @@ -64,4 +75,4 @@ class UniformStorage } -#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ +#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h index de5d30e6fe..cb0d360f0b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h @@ -23,9 +23,10 @@ class ShaderImpl ShaderImpl() { } virtual ~ShaderImpl() { } - virtual bool compile(const std::string &source) = 0; + virtual bool compile(const gl::Data &data, const std::string &source) = 0; virtual const std::string &getInfoLog() const = 0; virtual const std::string &getTranslatedSource() const = 0; + virtual std::string getDebugInfo() const = 0; const std::vector &getVaryings() const { return mVaryings; } const std::vector &getUniforms() const { return mUniforms; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h index 1ec702f299..1417e0bdf6 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h @@ -11,28 +11,24 @@ #define LIBGLESV2_RENDERER_SWAPCHAIN_H_ #include "common/angleutils.h" +#include "common/NativeWindow.h" #include "common/platform.h" #include #include -#include + +#if !defined(ANGLE_FORCE_VSYNC_OFF) +#define ANGLE_FORCE_VSYNC_OFF 0 +#endif namespace rx { -enum SwapFlags -{ - SWAP_NORMAL = 0, - SWAP_ROTATE_90 = 1, - SWAP_ROTATE_270 = 2, - SWAP_ROTATE_180 = SWAP_ROTATE_90|SWAP_ROTATE_270, -}; - class SwapChain { public: - SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat) + SwapChain(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) + : mNativeWindow(nativeWindow), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat) { } @@ -40,13 +36,16 @@ class SwapChain virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0; virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) = 0; + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0; virtual void recreate() = 0; + GLenum GetBackBufferInternalFormat() const { return mBackBufferFormat; } + GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; } + virtual HANDLE getShareHandle() {return mShareHandle;}; protected: - const EGLNativeWindowType mWindow; // Window that the surface is created for. + rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. const GLenum mBackBufferFormat; const GLenum mDepthBufferFormat; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h index e3cc50d680..3e662557e4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h @@ -10,6 +10,7 @@ #define LIBGLESV2_RENDERER_TEXTUREIMPL_H_ #include "common/angleutils.h" +#include "libGLESv2/Error.h" #include "angle_gl.h" @@ -31,19 +32,12 @@ namespace rx { class Image; -class Renderer; -class TextureStorage; class TextureImpl { public: virtual ~TextureImpl() {}; - // TODO: If this methods could go away that would be ideal; - // TextureStorage should only be necessary for the D3D backend, and as such - // higher level code should not rely on it. - virtual TextureStorage *getNativeTexture() = 0; - // Deprecated in favour of the ImageIndex method virtual Image *getImage(int level, int layer) const = 0; virtual Image *getImage(const gl::ImageIndex &index) const = 0; @@ -51,15 +45,15 @@ class TextureImpl virtual void setUsage(GLenum usage) = 0; - virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0; - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0; - virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; - virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; + virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0; + virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; + virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0; + virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0; - virtual void generateMipmaps() = 0; + virtual gl::Error generateMipmaps() = 0; virtual void bindTexImage(egl::Surface *surface) = 0; virtual void releaseTexImage() = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h b/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h new file mode 100644 index 0000000000..20a166fb7a --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// angletypes.h: Workarounds for driver bugs and other issues. + +#ifndef LIBGLESV2_RENDERER_WORKAROUNDS_H_ +#define LIBGLESV2_RENDERER_WORKAROUNDS_H_ + +// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate +// independent of ANGLE's renderer. Workarounds should also be accessible +// outside of the Renderer. + +namespace rx +{ + +enum D3DWorkaroundType +{ + ANGLE_D3D_WORKAROUND_NONE, + ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION, + ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION +}; + +struct Workarounds +{ + Workarounds() + : mrtPerfWorkaround(false), + setDataFasterThanImageUpload(false) + {} + + bool mrtPerfWorkaround; + bool setDataFasterThanImageUpload; +}; + +} + +#endif // LIBGLESV2_RENDERER_WORKAROUNDS_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp index 004223d70f..aabc9f04e9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp @@ -6,7 +6,7 @@ // copyimage.cpp: Defines image copying functions -#include "libGLESv2/renderer/copyImage.h" +#include "libGLESv2/renderer/copyimage.h" namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp index a34ef03fb8..dd0d3f52ad 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp @@ -9,7 +9,6 @@ #include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/renderer/d3d/VertexBuffer.h" #include "libGLESv2/renderer/d3d/IndexBuffer.h" -#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/main.h" namespace rx @@ -37,6 +36,13 @@ BufferD3D *BufferD3D::makeBufferD3D(BufferImpl *buffer) return static_cast(buffer); } +BufferD3D *BufferD3D::makeFromBuffer(gl::Buffer *buffer) +{ + BufferImpl *impl = buffer->getImplementation(); + ASSERT(impl); + return makeBufferD3D(impl); +} + void BufferD3D::updateSerial() { mSerial = mNextSerial++; @@ -46,11 +52,11 @@ void BufferD3D::initializeStaticData() { if (!mStaticVertexBuffer) { - mStaticVertexBuffer = new rx::StaticVertexBufferInterface(getRenderer()); + mStaticVertexBuffer = new StaticVertexBufferInterface(getRenderer()); } if (!mStaticIndexBuffer) { - mStaticIndexBuffer = new rx::StaticIndexBufferInterface(getRenderer()); + mStaticIndexBuffer = new StaticIndexBufferInterface(getRenderer()); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h index 44f14cee58..1a1308c545 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h @@ -12,10 +12,11 @@ #include "libGLESv2/renderer/BufferImpl.h" #include "libGLESv2/angletypes.h" +#include + namespace rx { - -class Renderer; +class RendererD3D; class StaticIndexBufferInterface; class StaticVertexBufferInterface; @@ -26,15 +27,17 @@ class BufferD3D : public BufferImpl virtual ~BufferD3D(); static BufferD3D *makeBufferD3D(BufferImpl *buffer); + static BufferD3D *makeFromBuffer(gl::Buffer *buffer); unsigned int getSerial() const { return mSerial; } + virtual gl::Error getData(const uint8_t **outData) = 0; virtual size_t getSize() const = 0; virtual bool supportsDirectBinding() const = 0; - virtual Renderer* getRenderer() = 0; + virtual RendererD3D *getRenderer() = 0; - rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; } - rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; } + StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; } + StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; } void initializeStaticData(); void invalidateStaticData(); @@ -46,8 +49,8 @@ class BufferD3D : public BufferImpl void updateSerial(); - rx::StaticVertexBufferInterface *mStaticVertexBuffer; - rx::StaticIndexBufferInterface *mStaticIndexBuffer; + StaticVertexBufferInterface *mStaticVertexBuffer; + StaticIndexBufferInterface *mStaticIndexBuffer; unsigned int mUnmodifiedDataUse; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp index 13411ebe64..3d5bfe0cbe 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp @@ -8,10 +8,10 @@ #include "libGLESv2/renderer/d3d/DynamicHLSL.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/Shader.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/Program.h" #include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Shader.h" #include "libGLESv2/formatutils.h" #include "common/utilities.h" @@ -22,6 +22,9 @@ META_ASSERT(GL_INVALID_INDEX == UINT_MAX); using namespace gl; +namespace rx +{ + namespace { @@ -70,7 +73,7 @@ std::string HLSLTypeString(GLenum type) return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type)); } -const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector &outputVariables, +const PixelShaderOutputVariable &GetOutputAtLocation(const std::vector &outputVariables, unsigned int location) { for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex) @@ -85,15 +88,12 @@ const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector& transformFeedbackVaryings) +int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader, + ShaderD3D *vertexShader, const std::vector &transformFeedbackVaryings) { // TODO (geofflang): Use context's caps const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors; @@ -262,6 +262,13 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++) { const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex]; + + if (transformFeedbackVarying == "gl_Position" || transformFeedbackVarying == "gl_PointSize") + { + // do not pack builtin XFB varyings + continue; + } + if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end()) { bool found = false; @@ -281,7 +288,7 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad } } - if (!found && transformFeedbackVarying != "gl_Position" && transformFeedbackVarying != "gl_PointSize") + if (!found) { infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str()); return -1; @@ -400,7 +407,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s // data reinterpretation (eg for pure integer->float, float->pure integer) // TODO: issue warning with gl debug info extension, when supported if (IsMatrixType(shaderAttribute.type) || - (mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0) + (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0) { initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute); } @@ -639,7 +646,7 @@ void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, } } -void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, +void DynamicHLSL::storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector *linkedVaryings) const { const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize); @@ -662,10 +669,11 @@ void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, } } -bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing, - std::string& pixelHLSL, std::string& vertexHLSL, - rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader, - const std::vector& transformFeedbackVaryings, +bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, int registers, + const VaryingPacking packing, + std::string &pixelHLSL, std::string &vertexHLSL, + ShaderD3D *fragmentShader, ShaderD3D *vertexShader, + const std::vector &transformFeedbackVaryings, std::vector *linkedVaryings, std::map *programOutputVars, std::vector *outPixelShaderKey, @@ -691,21 +699,17 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const // Write the HLSL input/output declarations const int shaderModel = mRenderer->getMajorShaderModel(); - - // TODO (geofflang): Use context's caps - const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors; - const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0); // Two cases when writing to gl_FragColor and using ESSL 1.0: // - with a 3.0 context, the output color is copied to channel 0 // - with a 2.0 context, the output color is broadcast to all channels - const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3); - const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getRendererCaps().maxDrawBuffers : 1); + const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3); + const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1); int shaderVersion = vertexShader->getShaderVersion(); - if (registersNeeded > maxVaryingVectors) + if (static_cast(registersNeeded) > data.caps->maxVaryingVectors) { infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); return false; @@ -772,7 +776,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const for (int row = 0; row < variableRows; row++) { - int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row; + int r = varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row; vertexHLSL += " output.v" + Str(r); vertexHLSL += " = _" + varying.name; @@ -920,7 +924,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); for (int row = 0; row < variableRows; row++) { - std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row); + std::string n = Str(varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row); pixelHLSL += " _" + varying.name; if (varying.isArray()) @@ -966,7 +970,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const return true; } -void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map *programOutputVars) const +void DynamicHLSL::defineOutputVariables(ShaderD3D *fragmentShader, std::map *programOutputVars) const { const std::vector &shaderOutputVars = fragmentShader->getActiveOutputVariables(); @@ -994,14 +998,14 @@ void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map< } } -std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const +std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const { // for now we only handle point sprite emulation ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4); return generatePointSpriteHLSL(registers, fragmentShader, vertexShader); } -std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const +std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const { ASSERT(registers >= 0); ASSERT(vertexShader->mUsesPointSize); @@ -1047,7 +1051,7 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *f "void main(point GS_INPUT input[1], inout TriangleStream outStream)\n" "{\n" " GS_OUTPUT output = (GS_OUTPUT)0;\n" - " output.gl_Position = input[0].gl_Position;\n"; + " output.gl_Position = input[0].gl_Position;\n" " output.gl_PointSize = input[0].gl_PointSize;\n"; for (int r = 0; r < registers; r++) @@ -1135,7 +1139,7 @@ void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLen } else { - bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0); + bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0); signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h index f68ed98401..c46bbf6ce0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h @@ -10,18 +10,13 @@ #define LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_ #include "common/angleutils.h" -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" #include "angle_gl.h" #include #include -namespace rx -{ -class Renderer; -} - namespace sh { struct Attribute; @@ -36,11 +31,12 @@ struct LinkedVarying; struct VertexAttribute; struct VertexFormat; struct PackedVarying; +struct Data; } namespace rx { -class Renderer; +class RendererD3D; class ShaderD3D; typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4]; @@ -56,30 +52,31 @@ struct PixelShaderOutputVariable class DynamicHLSL { public: - explicit DynamicHLSL(rx::Renderer *const renderer); + explicit DynamicHLSL(RendererD3D *const renderer); - int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader, - rx::ShaderD3D *vertexShader, const std::vector& transformFeedbackVaryings); + int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader, + ShaderD3D *vertexShader, const std::vector& transformFeedbackVaryings); std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const gl::VertexFormat inputLayout[], const sh::Attribute shaderAttributes[]) const; std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector &outputVariables, bool usesFragDepth, const std::vector &outputLayout) const; - bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing, - std::string& pixelHLSL, std::string& vertexHLSL, - rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader, - const std::vector& transformFeedbackVaryings, + bool generateShaderLinkHLSL(const gl::Data &data, gl::InfoLog &infoLog, int registers, + const VaryingPacking packing, + std::string &pixelHLSL, std::string &vertexHLSL, + ShaderD3D *fragmentShader, ShaderD3D *vertexShader, + const std::vector &transformFeedbackVaryings, std::vector *linkedVaryings, std::map *programOutputVars, std::vector *outPixelShaderKey, bool *outUsesFragDepth) const; - std::string generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const; + std::string generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const; void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const; private: DISALLOW_COPY_AND_ASSIGN(DynamicHLSL); - rx::Renderer *const mRenderer; + RendererD3D *const mRenderer; struct SemanticInfo; @@ -88,10 +85,10 @@ class DynamicHLSL bool pixelShader) const; std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const; std::string generateVaryingHLSL(const ShaderD3D *shader) const; - void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector *linkedVaryings) const; + void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector *linkedVaryings) const; void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector *linkedVaryings) const; - void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map *programOutputVars) const; - std::string generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const; + void defineOutputVariables(ShaderD3D *fragmentShader, std::map *programOutputVars) const; + std::string generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const; // Prepend an underscore static std::string decorateVariable(const std::string &name); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp index d0131974ee..776d92b202 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp @@ -8,34 +8,116 @@ #include "libGLESv2/Program.h" #include "libGLESv2/main.h" +#include "common/features.h" #include "common/utilities.h" -#include "common/platform.h" - -#if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL) - -// Add define + typedefs for older MinGW-w64 headers (pre 5783) - -#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" - -HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, - const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages); -typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, - const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages); - -#endif // __MINGW32__ && !D3DCOMPILER_DLL #ifndef QT_D3DCOMPILER_DLL #define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL #endif +#ifndef D3DCOMPILE_RESERVED16 +#define D3DCOMPILE_RESERVED16 (1 << 16) +#endif +#ifndef D3DCOMPILE_RESERVED17 +#define D3DCOMPILE_RESERVED17 (1 << 17) +#endif + +// Definitions local to the translation unit +namespace +{ + +#ifdef CREATE_COMPILER_FLAG_INFO + #undef CREATE_COMPILER_FLAG_INFO +#endif + +#define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag } + +struct CompilerFlagInfo +{ + UINT mFlag; + const char *mName; +}; + +CompilerFlagInfo CompilerFlagInfos[] = +{ + // NOTE: The data below is copied from d3dcompiler.h + // If something changes there it should be changed here as well + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_DEBUG), // (1 << 0) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_VALIDATION), // (1 << 1) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_OPTIMIZATION), // (1 << 2) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_ROW_MAJOR), // (1 << 3) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR), // (1 << 4) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PARTIAL_PRECISION), // (1 << 5) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT), // (1 << 6) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT), // (1 << 7) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_NO_PRESHADER), // (1 << 8) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_AVOID_FLOW_CONTROL), // (1 << 9) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PREFER_FLOW_CONTROL), // (1 << 10) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_STRICTNESS), // (1 << 11) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY), // (1 << 12) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_IEEE_STRICTNESS), // (1 << 13) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL0), // (1 << 14) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL1), // 0 + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL2), // ((1 << 14) | (1 << 15)) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL3), // (1 << 15) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED16), // (1 << 16) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED17), // (1 << 17) + CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_WARNINGS_ARE_ERRORS) // (1 << 18) +}; + +#undef CREATE_COMPILER_FLAG_INFO + +bool IsCompilerFlagSet(UINT mask, UINT flag) +{ + bool isFlagSet = IsMaskFlagSet(mask, flag); + + switch(flag) + { + case D3DCOMPILE_OPTIMIZATION_LEVEL0: + return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL3)); + + case D3DCOMPILE_OPTIMIZATION_LEVEL1: + return (mask & D3DCOMPILE_OPTIMIZATION_LEVEL2) == UINT(0); + + case D3DCOMPILE_OPTIMIZATION_LEVEL3: + return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL0)); + + default: + return isFlagSet; + } +} + +const char *GetCompilerFlagName(UINT mask, size_t flagIx) +{ + const CompilerFlagInfo &flagInfo = CompilerFlagInfos[flagIx]; + if (IsCompilerFlagSet(mask, flagInfo.mFlag)) + { + return flagInfo.mName; + } + + return nullptr; +} + +} namespace rx { +CompileConfig::CompileConfig() + : flags(0), + name() +{ +} + +CompileConfig::CompileConfig(UINT flags, const std::string &name) + : flags(flags), + name(name) +{ +} + HLSLCompiler::HLSLCompiler() : mD3DCompilerModule(NULL), - mD3DCompileFunc(NULL) + mD3DCompileFunc(NULL), + mD3DDisassembleFunc(NULL) { } @@ -46,7 +128,7 @@ HLSLCompiler::~HLSLCompiler() bool HLSLCompiler::initialize() { -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; @@ -83,17 +165,32 @@ bool HLSLCompiler::initialize() break; } + if (!mD3DCompilerModule) + { + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. + mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL); + } + if (!mD3DCompilerModule) { ERR("No D3D compiler module found - aborting!\n"); return false; } - mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); + mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); ASSERT(mD3DCompileFunc); + + mD3DDisassembleFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DDisassemble")); + ASSERT(mD3DDisassembleFunc); + #else - mD3DCompileFunc = reinterpret_cast(&D3DCompile); + // D3D Shader compiler is linked already into this module, so the export + // can be directly assigned. + mD3DCompilerModule = NULL; + mD3DCompileFunc = reinterpret_cast(D3DCompile); + mD3DDisassembleFunc = reinterpret_cast(D3DDisassemble); #endif + return mD3DCompileFunc != NULL; } @@ -104,61 +201,133 @@ void HLSLCompiler::release() FreeLibrary(mD3DCompilerModule); mD3DCompilerModule = NULL; mD3DCompileFunc = NULL; + mD3DDisassembleFunc = NULL; } } -ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, - const UINT optimizationFlags[], const char *flagNames[], int attempts) const +gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile, + const std::vector &configs, const D3D_SHADER_MACRO *overrideMacros, + ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const { -#if !defined(ANGLE_PLATFORM_WINRT) - ASSERT(mD3DCompilerModule && mD3DCompileFunc); +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + ASSERT(mD3DCompilerModule); +#endif + ASSERT(mD3DCompileFunc); + +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + if (gl::perfActive()) + { + std::string sourcePath = getTempPath(); + std::string sourceText = FormatString("#line 2 \"%s\"\n\n%s", sourcePath.c_str(), hlsl.c_str()); + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); + } #endif - if (!hlsl) - { - return NULL; - } + const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : NULL; - pD3DCompile compileFunc = reinterpret_cast(mD3DCompileFunc); - for (int i = 0; i < attempts; ++i) + for (size_t i = 0; i < configs.size(); ++i) { ID3DBlob *errorMessage = NULL; ID3DBlob *binary = NULL; - HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage); + HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, NULL, "main", profile.c_str(), + configs[i].flags, 0, &binary, &errorMessage); if (errorMessage) { - const char *message = (const char*)errorMessage->GetBufferPointer(); - - infoLog.appendSanitized(message); - TRACE("\n%s", hlsl); - TRACE("\n%s", message); - + std::string message = reinterpret_cast(errorMessage->GetBufferPointer()); SafeRelease(errorMessage); + + infoLog.appendSanitized(message.c_str()); + TRACE("\n%s", hlsl.c_str()); + TRACE("\n%s", message.c_str()); + + if (message.find("error X3531:") != std::string::npos) // "can't unroll loops marked with loop attribute" + { + macros = NULL; // Disable [loop] and [flatten] + + // Retry without changing compiler flags + i--; + continue; + } } if (SUCCEEDED(result)) { - return (ShaderBlob*)binary; + *outCompiledBlob = binary; + +#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED + (*outDebugInfo) += "// COMPILER INPUT HLSL BEGIN\n\n" + hlsl + "\n// COMPILER INPUT HLSL END\n"; + (*outDebugInfo) += "\n\n// ASSEMBLY BEGIN\n\n"; + (*outDebugInfo) += "// Compiler configuration: " + configs[i].name + "\n// Flags:\n"; + for (size_t fIx = 0; fIx < ArraySize(CompilerFlagInfos); ++fIx) + { + const char *flagName = GetCompilerFlagName(configs[i].flags, fIx); + if (flagName != nullptr) + { + (*outDebugInfo) += std::string("// ") + flagName + "\n"; + } + } + + (*outDebugInfo) += "// Macros:\n"; + if (macros == nullptr) + { + (*outDebugInfo) += "// - : -\n"; + } + else + { + for (const D3D_SHADER_MACRO *mIt = macros; mIt->Name != nullptr; ++mIt) + { + (*outDebugInfo) += std::string("// ") + mIt->Name + " : " + mIt->Definition + "\n"; + } + } + + (*outDebugInfo) += "\n" + disassembleBinary(binary) + "\n// ASSEMBLY END\n"; +#endif + + return gl::Error(GL_NO_ERROR); } else { if (result == E_OUTOFMEMORY) { - return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL); + *outCompiledBlob = NULL; + return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result); } - infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]); + infoLog.append("Warning: D3D shader compilation failed with %s flags.", configs[i].name.c_str()); - if (i + 1 < attempts) + if (i + 1 < configs.size()) { - infoLog.append(" Retrying with %s.\n", flagNames[i + 1]); + infoLog.append(" Retrying with %s.\n", configs[i + 1].name.c_str()); } } } - return NULL; + // None of the configurations succeeded in compiling this shader but the compiler is still intact + *outCompiledBlob = NULL; + return gl::Error(GL_NO_ERROR); +} + +std::string HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary) const +{ + // Retrieve disassembly + UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING; + ID3DBlob *disassembly = NULL; + pD3DDisassemble disassembleFunc = reinterpret_cast(mD3DDisassembleFunc); + LPCVOID buffer = shaderBinary->GetBufferPointer(); + SIZE_T bufSize = shaderBinary->GetBufferSize(); + HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly); + + std::string asmSrc; + if (SUCCEEDED(result)) + { + asmSrc = reinterpret_cast(disassembly->GetBufferPointer()); + } + + SafeRelease(disassembly); + + return asmSrc; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h index 0ce9e44be5..ff56f8035a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h @@ -1,7 +1,13 @@ #ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_ #define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" +#include "common/platform.h" + +#include +#include namespace gl { @@ -11,8 +17,14 @@ class InfoLog; namespace rx { -typedef void* ShaderBlob; -typedef void(*CompileFuncPtr)(); +struct CompileConfig +{ + UINT flags; + std::string name; + + CompileConfig(); + CompileConfig(UINT flags, const std::string &name); +}; class HLSLCompiler { @@ -23,14 +35,20 @@ class HLSLCompiler bool initialize(); void release(); - ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, - const UINT optimizationFlags[], const char *flagNames[], int attempts) const; + // Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob + // even if no GL errors are returned. + gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile, + const std::vector &configs, const D3D_SHADER_MACRO *overrideMacros, + ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const; + + std::string disassembleBinary(ID3DBlob* shaderBinary) const; private: DISALLOW_COPY_AND_ASSIGN(HLSLCompiler); HMODULE mD3DCompilerModule; - CompileFuncPtr mD3DCompileFunc; + pD3DCompile mD3DCompileFunc; + pD3DDisassemble mD3DDisassembleFunc; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp index 0854b968da..12b919ab5a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp @@ -19,8 +19,8 @@ ImageD3D::ImageD3D() ImageD3D *ImageD3D::makeImageD3D(Image *img) { - ASSERT(HAS_DYNAMIC_TYPE(rx::ImageD3D*, img)); - return static_cast(img); + ASSERT(HAS_DYNAMIC_TYPE(ImageD3D*, img)); + return static_cast(img); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h index 60a6ffdf37..554ca0cee0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h @@ -17,6 +17,8 @@ namespace gl { class Framebuffer; +struct ImageIndex; +struct Box; } namespace rx @@ -33,14 +35,11 @@ class ImageD3D : public Image virtual bool isDirty() const = 0; - virtual void setManagedSurface2D(TextureStorage *storage, int level) {}; - virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {}; - virtual void setManagedSurface3D(TextureStorage *storage, int level) {}; - virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {}; - virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; - virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0; - virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0; - virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0; + virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); }; + virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) = 0; private: DISALLOW_COPY_AND_ASSIGN(ImageD3D); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp index 1dce1270d8..aa614f6cc4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp @@ -8,7 +8,7 @@ // class with derivations, classes that perform graphics API agnostic index buffer operations. #include "libGLESv2/renderer/d3d/IndexBuffer.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" namespace rx { @@ -35,7 +35,7 @@ void IndexBuffer::updateSerial() } -IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer) +IndexBufferInterface::IndexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer) { mIndexBuffer = renderer->createIndexBuffer(); @@ -130,7 +130,7 @@ gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum in } } -StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true) +StreamingIndexBufferInterface::StreamingIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, true) { } @@ -165,7 +165,7 @@ gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, G } -StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false) +StaticIndexBufferInterface::StaticIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, false) { } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h index 1bb5ae2c4a..a34d30bbf3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h @@ -16,7 +16,7 @@ namespace rx { -class Renderer; +class RendererD3D; class IndexBuffer { @@ -50,7 +50,7 @@ class IndexBuffer class IndexBufferInterface { public: - IndexBufferInterface(Renderer *renderer, bool dynamic); + IndexBufferInterface(RendererD3D *renderer, bool dynamic); virtual ~IndexBufferInterface(); virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) = 0; @@ -76,7 +76,7 @@ class IndexBufferInterface private: DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface); - rx::Renderer *const mRenderer; + RendererD3D *const mRenderer; IndexBuffer* mIndexBuffer; @@ -87,7 +87,7 @@ class IndexBufferInterface class StreamingIndexBufferInterface : public IndexBufferInterface { public: - StreamingIndexBufferInterface(Renderer *renderer); + StreamingIndexBufferInterface(RendererD3D *renderer); ~StreamingIndexBufferInterface(); virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType); @@ -96,7 +96,7 @@ class StreamingIndexBufferInterface : public IndexBufferInterface class StaticIndexBufferInterface : public IndexBufferInterface { public: - explicit StaticIndexBufferInterface(Renderer *renderer); + explicit StaticIndexBufferInterface(RendererD3D *renderer); ~StaticIndexBufferInterface(); virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp index 8d455b4bf3..eddd9de887 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp @@ -10,7 +10,7 @@ #include "libGLESv2/renderer/d3d/IndexDataManager.h" #include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/renderer/d3d/IndexBuffer.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/main.h" #include "libGLESv2/formatutils.h" @@ -57,7 +57,7 @@ static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void else UNREACHABLE(); } -IndexDataManager::IndexDataManager(Renderer *renderer) +IndexDataManager::IndexDataManager(RendererD3D *renderer) : mRenderer(renderer), mStreamingBufferShort(NULL), mStreamingBufferInt(NULL) @@ -97,7 +97,14 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf ASSERT(typeInfo.bytes * static_cast(count) + offset <= storage->getSize()); - indices = static_cast(storage->getData()) + offset; + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL; @@ -183,7 +190,16 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf return error; } - ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output); + const uint8_t *dataPointer = reinterpret_cast(indices); + if (staticBuffer) + { + error = storage->getData(&dataPointer); + if (error.isError()) + { + return error; + } + } + ConvertIndices(type, destinationIndexType, dataPointer, convertCount, output); error = indexBuffer->unmapBuffer(); if (error.isError()) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h index 6d0b89e6d4..a1aee1588b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h @@ -33,7 +33,7 @@ class StaticIndexBufferInterface; class StreamingIndexBufferInterface; class IndexBuffer; class BufferD3D; -class Renderer; +class RendererD3D; struct TranslatedIndexData { @@ -50,7 +50,7 @@ struct TranslatedIndexData class IndexDataManager { public: - explicit IndexDataManager(Renderer *renderer); + explicit IndexDataManager(RendererD3D *renderer); virtual ~IndexDataManager(); gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); @@ -60,7 +60,7 @@ class IndexDataManager DISALLOW_COPY_AND_ASSIGN(IndexDataManager); - Renderer *const mRenderer; + RendererD3D *const mRenderer; StreamingIndexBufferInterface *mStreamingBufferShort; StreamingIndexBufferInterface *mStreamingBufferInt; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp index d7d97cc2bd..75da78110e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp @@ -8,27 +8,163 @@ #include "libGLESv2/renderer/d3d/ProgramD3D.h" +#include "common/features.h" #include "common/utilities.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/Program.h" #include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/main.h" #include "libGLESv2/renderer/ShaderExecutable.h" #include "libGLESv2/renderer/d3d/DynamicHLSL.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" -#include "libGLESv2/main.h" namespace rx { -ProgramD3D::ProgramD3D(rx::Renderer *renderer) +namespace +{ + +GLenum GetTextureType(GLenum samplerType) +{ + switch (samplerType) + { + case GL_SAMPLER_2D: + case GL_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_SAMPLER_2D_SHADOW: + return GL_TEXTURE_2D; + case GL_SAMPLER_3D: + case GL_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_3D: + return GL_TEXTURE_3D; + case GL_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + return GL_TEXTURE_CUBE_MAP; + case GL_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + return GL_TEXTURE_CUBE_MAP; + case GL_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + return GL_TEXTURE_2D_ARRAY; + default: UNREACHABLE(); + } + + return GL_TEXTURE_2D; +} + +void GetDefaultInputLayoutFromShader(const std::vector &shaderAttributes, gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]) +{ + size_t layoutIndex = 0; + for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) + { + ASSERT(layoutIndex < gl::MAX_VERTEX_ATTRIBS); + + const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex]; + + if (shaderAttr.type != GL_NONE) + { + GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type); + + for (size_t rowIndex = 0; static_cast(rowIndex) < gl::VariableRowCount(transposedType); rowIndex++, layoutIndex++) + { + gl::VertexFormat *defaultFormat = &inputLayout[layoutIndex]; + + defaultFormat->mType = gl::VariableComponentType(transposedType); + defaultFormat->mNormalized = false; + defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool + defaultFormat->mComponents = gl::VariableColumnCount(transposedType); + } + } + } +} + +std::vector GetDefaultOutputLayoutFromShader(const std::vector &shaderOutputVars) +{ + std::vector defaultPixelOutput(1); + + ASSERT(!shaderOutputVars.empty()); + defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex; + + return defaultPixelOutput; +} + +bool IsRowMajorLayout(const sh::InterfaceBlockField &var) +{ + return var.isRowMajorLayout; +} + +bool IsRowMajorLayout(const sh::ShaderVariable &var) +{ + return false; +} + +} + +ProgramD3D::VertexExecutable::VertexExecutable(const gl::VertexFormat inputLayout[], + const GLenum signature[], + ShaderExecutable *shaderExecutable) + : mShaderExecutable(shaderExecutable) +{ + for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + { + mInputs[attributeIndex] = inputLayout[attributeIndex]; + mSignature[attributeIndex] = signature[attributeIndex]; + } +} + +ProgramD3D::VertexExecutable::~VertexExecutable() +{ + SafeDelete(mShaderExecutable); +} + +bool ProgramD3D::VertexExecutable::matchesSignature(const GLenum signature[]) const +{ + for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + { + if (mSignature[attributeIndex] != signature[attributeIndex]) + { + return false; + } + } + + return true; +} + +ProgramD3D::PixelExecutable::PixelExecutable(const std::vector &outputSignature, ShaderExecutable *shaderExecutable) + : mOutputSignature(outputSignature), + mShaderExecutable(shaderExecutable) +{ +} + +ProgramD3D::PixelExecutable::~PixelExecutable() +{ + SafeDelete(mShaderExecutable); +} + +ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D) +{ +} + +ProgramD3D::ProgramD3D(RendererD3D *renderer) : ProgramImpl(), mRenderer(renderer), mDynamicHLSL(NULL), - mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), - mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE), + mGeometryExecutable(NULL), + mVertexWorkarounds(ANGLE_D3D_WORKAROUND_NONE), + mPixelWorkarounds(ANGLE_D3D_WORKAROUND_NONE), + mUsesPointSize(false), mVertexUniformStorage(NULL), - mFragmentUniformStorage(NULL) + mFragmentUniformStorage(NULL), + mUsedVertexSamplerRange(0), + mUsedPixelSamplerRange(0), + mDirtySamplerMapping(true), + mShaderVersion(100) { - mDynamicHLSL = new rx::DynamicHLSL(renderer); + mDynamicHLSL = new DynamicHLSL(renderer); } ProgramD3D::~ProgramD3D() @@ -49,13 +185,344 @@ const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl) return static_cast(impl); } -bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) +bool ProgramD3D::usesPointSpriteEmulation() const { + return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; +} + +bool ProgramD3D::usesGeometryShader() const +{ + return usesPointSpriteEmulation(); +} + +GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const +{ + GLint logicalTextureUnit = -1; + + switch (type) + { + case gl::SAMPLER_PIXEL: + ASSERT(samplerIndex < caps.maxTextureImageUnits); + if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active) + { + logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; + } + break; + case gl::SAMPLER_VERTEX: + ASSERT(samplerIndex < caps.maxVertexTextureImageUnits); + if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active) + { + logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; + } + break; + default: UNREACHABLE(); + } + + if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast(caps.maxCombinedTextureImageUnits)) + { + return logicalTextureUnit; + } + + return -1; +} + +// Returns the texture type for a given Direct3D 9 sampler type and +// index (0-15 for the pixel shader and 0-3 for the vertex shader). +GLenum ProgramD3D::getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const +{ + switch (type) + { + case gl::SAMPLER_PIXEL: + ASSERT(samplerIndex < mSamplersPS.size()); + ASSERT(mSamplersPS[samplerIndex].active); + return mSamplersPS[samplerIndex].textureType; + case gl::SAMPLER_VERTEX: + ASSERT(samplerIndex < mSamplersVS.size()); + ASSERT(mSamplersVS[samplerIndex].active); + return mSamplersVS[samplerIndex].textureType; + default: UNREACHABLE(); + } + + return GL_TEXTURE_2D; +} + +GLint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const +{ + switch (type) + { + case gl::SAMPLER_PIXEL: + return mUsedPixelSamplerRange; + case gl::SAMPLER_VERTEX: + return mUsedVertexSamplerRange; + default: + UNREACHABLE(); + return 0; + } +} + +void ProgramD3D::updateSamplerMapping() +{ + if (!mDirtySamplerMapping) + { + return; + } + + mDirtySamplerMapping = false; + + // Retrieve sampler uniform values + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + gl::LinkedUniform *targetUniform = mUniforms[uniformIndex]; + + if (targetUniform->dirty) + { + if (gl::IsSampler(targetUniform->type)) + { + int count = targetUniform->elementCount(); + GLint (*v)[4] = reinterpret_cast(targetUniform->data); + + if (targetUniform->isReferencedByFragmentShader()) + { + unsigned int firstIndex = targetUniform->psRegisterIndex; + + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < mSamplersPS.size()) + { + ASSERT(mSamplersPS[samplerIndex].active); + mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; + } + } + } + + if (targetUniform->isReferencedByVertexShader()) + { + unsigned int firstIndex = targetUniform->vsRegisterIndex; + + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < mSamplersVS.size()) + { + ASSERT(mSamplersVS[samplerIndex].active); + mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; + } + } + } + } + } + } +} + +bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) +{ + // if any two active samplers in a program are of different types, but refer to the same + // texture image unit, and this is the current program, then ValidateProgram will fail, and + // DrawArrays and DrawElements will issue the INVALID_OPERATION error. + updateSamplerMapping(); + + std::vector textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE); + + for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) + { + if (mSamplersPS[i].active) + { + unsigned int unit = mSamplersPS[i].logicalTextureUnit; + + if (unit >= textureUnitTypes.size()) + { + if (infoLog) + { + infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); + } + + return false; + } + + if (textureUnitTypes[unit] != GL_NONE) + { + if (mSamplersPS[i].textureType != textureUnitTypes[unit]) + { + if (infoLog) + { + infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + + return false; + } + } + else + { + textureUnitTypes[unit] = mSamplersPS[i].textureType; + } + } + } + + for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) + { + if (mSamplersVS[i].active) + { + unsigned int unit = mSamplersVS[i].logicalTextureUnit; + + if (unit >= textureUnitTypes.size()) + { + if (infoLog) + { + infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); + } + + return false; + } + + if (textureUnitTypes[unit] != GL_NONE) + { + if (mSamplersVS[i].textureType != textureUnitTypes[unit]) + { + if (infoLog) + { + infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + + return false; + } + } + else + { + textureUnitTypes[unit] = mSamplersVS[i].textureType; + } + } + } + + return true; +} + +gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) +{ + stream->readInt(&mShaderVersion); + + const unsigned int psSamplerCount = stream->readInt(); + for (unsigned int i = 0; i < psSamplerCount; ++i) + { + Sampler sampler; + stream->readBool(&sampler.active); + stream->readInt(&sampler.logicalTextureUnit); + stream->readInt(&sampler.textureType); + mSamplersPS.push_back(sampler); + } + const unsigned int vsSamplerCount = stream->readInt(); + for (unsigned int i = 0; i < vsSamplerCount; ++i) + { + Sampler sampler; + stream->readBool(&sampler.active); + stream->readInt(&sampler.logicalTextureUnit); + stream->readInt(&sampler.textureType); + mSamplersVS.push_back(sampler); + } + + stream->readInt(&mUsedVertexSamplerRange); + stream->readInt(&mUsedPixelSamplerRange); + + const unsigned int uniformCount = stream->readInt(); + if (stream->error()) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + mUniforms.resize(uniformCount); + for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) + { + GLenum type = stream->readInt(); + GLenum precision = stream->readInt(); + std::string name = stream->readString(); + unsigned int arraySize = stream->readInt(); + int blockIndex = stream->readInt(); + + int offset = stream->readInt(); + int arrayStride = stream->readInt(); + int matrixStride = stream->readInt(); + bool isRowMajorMatrix = stream->readBool(); + + const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix); + + gl::LinkedUniform *uniform = new gl::LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo); + + stream->readInt(&uniform->psRegisterIndex); + stream->readInt(&uniform->vsRegisterIndex); + stream->readInt(&uniform->registerCount); + stream->readInt(&uniform->registerElement); + + mUniforms[uniformIndex] = uniform; + } + + const unsigned int uniformIndexCount = stream->readInt(); + if (stream->error()) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + mUniformIndex.resize(uniformIndexCount); + for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) + { + stream->readString(&mUniformIndex[uniformIndexIndex].name); + stream->readInt(&mUniformIndex[uniformIndexIndex].element); + stream->readInt(&mUniformIndex[uniformIndexIndex].index); + } + + unsigned int uniformBlockCount = stream->readInt(); + if (stream->error()) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + mUniformBlocks.resize(uniformBlockCount); + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) + { + std::string name = stream->readString(); + unsigned int elementIndex = stream->readInt(); + unsigned int dataSize = stream->readInt(); + + gl::UniformBlock *uniformBlock = new gl::UniformBlock(name, elementIndex, dataSize); + + stream->readInt(&uniformBlock->psRegisterIndex); + stream->readInt(&uniformBlock->vsRegisterIndex); + + unsigned int numMembers = stream->readInt(); + uniformBlock->memberUniformIndexes.resize(numMembers); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) + { + stream->readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]); + } + + mUniformBlocks[uniformBlockIndex] = uniformBlock; + } + + stream->readInt(&mTransformFeedbackBufferMode); + const unsigned int transformFeedbackVaryingCount = stream->readInt(); + mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount); + for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++) + { + gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex]; + + stream->readString(&varying.name); + stream->readInt(&varying.type); + stream->readInt(&varying.size); + stream->readString(&varying.semanticName); + stream->readInt(&varying.semanticIndex); + stream->readInt(&varying.semanticIndexCount); + } + stream->readString(&mVertexHLSL); stream->readInt(&mVertexWorkarounds); stream->readString(&mPixelHLSL); stream->readInt(&mPixelWorkarounds); stream->readBool(&mUsesFragDepth); + stream->readBool(&mUsesPointSize); const size_t pixelShaderKeySize = stream->readInt(); mPixelShaderKey.resize(pixelShaderKeySize); @@ -67,109 +534,513 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); } - return true; + const unsigned char* binary = reinterpret_cast(stream->data()); + + const unsigned int vertexShaderCount = stream->readInt(); + for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) + { + gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]; + + for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) + { + gl::VertexFormat *vertexInput = &inputLayout[inputIndex]; + stream->readInt(&vertexInput->mType); + stream->readInt(&vertexInput->mNormalized); + stream->readInt(&vertexInput->mComponents); + stream->readBool(&vertexInput->mPureInteger); + } + + unsigned int vertexShaderSize = stream->readInt(); + const unsigned char *vertexShaderFunction = binary + stream->offset(); + + ShaderExecutable *shaderExecutable = NULL; + gl::Error error = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize, + SHADER_VERTEX, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + &shaderExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (!shaderExecutable) + { + infoLog.append("Could not create vertex shader."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + // generated converted input layout + GLenum signature[gl::MAX_VERTEX_ATTRIBS]; + getInputLayoutSignature(inputLayout, signature); + + // add new binary + mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable)); + + stream->skip(vertexShaderSize); + } + + const size_t pixelShaderCount = stream->readInt(); + for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++) + { + const size_t outputCount = stream->readInt(); + std::vector outputs(outputCount); + for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++) + { + stream->readInt(&outputs[outputIndex]); + } + + const size_t pixelShaderSize = stream->readInt(); + const unsigned char *pixelShaderFunction = binary + stream->offset(); + ShaderExecutable *shaderExecutable = NULL; + gl::Error error = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + &shaderExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (!shaderExecutable) + { + infoLog.append("Could not create pixel shader."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + // add new binary + mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable)); + + stream->skip(pixelShaderSize); + } + + unsigned int geometryShaderSize = stream->readInt(); + + if (geometryShaderSize > 0) + { + const unsigned char *geometryShaderFunction = binary + stream->offset(); + gl::Error error = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + &mGeometryExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (!mGeometryExecutable) + { + infoLog.append("Could not create geometry shader."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + stream->skip(geometryShaderSize); + } + + GUID binaryIdentifier = {0}; + stream->readBytes(reinterpret_cast(&binaryIdentifier), sizeof(GUID)); + + GUID identifier = mRenderer->getAdapterIdentifier(); + if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0) + { + infoLog.append("Invalid program binary."); + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); + } + + initializeUniformStorage(); + + return gl::LinkResult(true, gl::Error(GL_NO_ERROR)); } -bool ProgramD3D::save(gl::BinaryOutputStream *stream) +gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) { + stream->writeInt(mShaderVersion); + + stream->writeInt(mSamplersPS.size()); + for (unsigned int i = 0; i < mSamplersPS.size(); ++i) + { + stream->writeInt(mSamplersPS[i].active); + stream->writeInt(mSamplersPS[i].logicalTextureUnit); + stream->writeInt(mSamplersPS[i].textureType); + } + + stream->writeInt(mSamplersVS.size()); + for (unsigned int i = 0; i < mSamplersVS.size(); ++i) + { + stream->writeInt(mSamplersVS[i].active); + stream->writeInt(mSamplersVS[i].logicalTextureUnit); + stream->writeInt(mSamplersVS[i].textureType); + } + + stream->writeInt(mUsedVertexSamplerRange); + stream->writeInt(mUsedPixelSamplerRange); + + stream->writeInt(mUniforms.size()); + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex) + { + const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; + + stream->writeInt(uniform.type); + stream->writeInt(uniform.precision); + stream->writeString(uniform.name); + stream->writeInt(uniform.arraySize); + stream->writeInt(uniform.blockIndex); + + stream->writeInt(uniform.blockInfo.offset); + stream->writeInt(uniform.blockInfo.arrayStride); + stream->writeInt(uniform.blockInfo.matrixStride); + stream->writeInt(uniform.blockInfo.isRowMajorMatrix); + + stream->writeInt(uniform.psRegisterIndex); + stream->writeInt(uniform.vsRegisterIndex); + stream->writeInt(uniform.registerCount); + stream->writeInt(uniform.registerElement); + } + + stream->writeInt(mUniformIndex.size()); + for (size_t i = 0; i < mUniformIndex.size(); ++i) + { + stream->writeString(mUniformIndex[i].name); + stream->writeInt(mUniformIndex[i].element); + stream->writeInt(mUniformIndex[i].index); + } + + stream->writeInt(mUniformBlocks.size()); + for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex) + { + const gl::UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex]; + + stream->writeString(uniformBlock.name); + stream->writeInt(uniformBlock.elementIndex); + stream->writeInt(uniformBlock.dataSize); + + stream->writeInt(uniformBlock.memberUniformIndexes.size()); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) + { + stream->writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]); + } + + stream->writeInt(uniformBlock.psRegisterIndex); + stream->writeInt(uniformBlock.vsRegisterIndex); + } + + stream->writeInt(mTransformFeedbackBufferMode); + stream->writeInt(mTransformFeedbackLinkedVaryings.size()); + for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++) + { + const gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i]; + + stream->writeString(varying.name); + stream->writeInt(varying.type); + stream->writeInt(varying.size); + stream->writeString(varying.semanticName); + stream->writeInt(varying.semanticIndex); + stream->writeInt(varying.semanticIndexCount); + } + stream->writeString(mVertexHLSL); stream->writeInt(mVertexWorkarounds); stream->writeString(mPixelHLSL); stream->writeInt(mPixelWorkarounds); stream->writeInt(mUsesFragDepth); + stream->writeInt(mUsesPointSize); - const std::vector &pixelShaderKey = mPixelShaderKey; + const std::vector &pixelShaderKey = mPixelShaderKey; stream->writeInt(pixelShaderKey.size()); for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++) { - const rx::PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex]; + const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex]; stream->writeInt(variable.type); stream->writeString(variable.name); stream->writeString(variable.source); stream->writeInt(variable.outputIndex); } - return true; + stream->writeInt(mVertexExecutables.size()); + for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) + { + VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; + + for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) + { + const gl::VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex]; + stream->writeInt(vertexInput.mType); + stream->writeInt(vertexInput.mNormalized); + stream->writeInt(vertexInput.mComponents); + stream->writeInt(vertexInput.mPureInteger); + } + + size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); + stream->writeInt(vertexShaderSize); + + const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction(); + stream->writeBytes(vertexBlob, vertexShaderSize); + } + + stream->writeInt(mPixelExecutables.size()); + for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++) + { + PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex]; + + const std::vector outputs = pixelExecutable->outputSignature(); + stream->writeInt(outputs.size()); + for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++) + { + stream->writeInt(outputs[outputIndex]); + } + + size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength(); + stream->writeInt(pixelShaderSize); + + const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction(); + stream->writeBytes(pixelBlob, pixelShaderSize); + } + + size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; + stream->writeInt(geometryShaderSize); + + if (mGeometryExecutable != NULL && geometryShaderSize > 0) + { + const uint8_t *geometryBlob = mGeometryExecutable->getFunction(); + stream->writeBytes(geometryBlob, geometryShaderSize); + } + + GUID binaryIdentifier = mRenderer->getAdapterIdentifier(); + stream->writeBytes(reinterpret_cast(&binaryIdentifier), sizeof(GUID)); + + return gl::Error(GL_NO_ERROR); } -rx::ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector &outputSignature, - const std::vector &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) +gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExecutable) { + std::vector outputs; + + const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(mRenderer->getWorkarounds()); + + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) + { + const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; + + if (colorbuffer) + { + outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding()); + } + else + { + outputs.push_back(GL_NONE); + } + } + + return getPixelExecutableForOutputLayout(outputs, outExecutable); +} + +gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector &outputSignature, ShaderExecutable **outExectuable) +{ + for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) + { + if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature)) + { + *outExectuable = mPixelExecutables[executableIndex]->shaderExecutable(); + return gl::Error(GL_NO_ERROR); + } + } + std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth, outputSignature); // Generate new pixel executable - rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL, - transformFeedbackLinkedVaryings, separatedOutputBuffers, - mPixelWorkarounds); + gl::InfoLog tempInfoLog; + ShaderExecutable *pixelExecutable = NULL; + gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + mPixelWorkarounds, &pixelExecutable); + if (error.isError()) + { + return error; + } - return pixelExecutable; + if (!pixelExecutable) + { + std::vector tempCharBuffer(tempInfoLog.getLength() + 3); + tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); + ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]); + } + else + { + mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable)); + } + + *outExectuable = pixelExecutable; + return gl::Error(GL_NO_ERROR); } -rx::ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog, - const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], - const sh::Attribute shaderAttributes[], - const std::vector &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers) +gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable) { + GLenum signature[gl::MAX_VERTEX_ATTRIBS]; + getInputLayoutSignature(inputLayout, signature); + + for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) + { + if (mVertexExecutables[executableIndex]->matchesSignature(signature)) + { + *outExectuable = mVertexExecutables[executableIndex]->shaderExecutable(); + return gl::Error(GL_NO_ERROR); + } + } + // Generate new dynamic layout with attribute conversions - std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes); + std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes); // Generate new vertex executable - rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(), - rx::SHADER_VERTEX, - transformFeedbackLinkedVaryings, separatedOutputBuffers, - mVertexWorkarounds); + gl::InfoLog tempInfoLog; + ShaderExecutable *vertexExecutable = NULL; + gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL, SHADER_VERTEX, + mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + mVertexWorkarounds, &vertexExecutable); + if (error.isError()) + { + return error; + } - return vertexExecutable; + if (!vertexExecutable) + { + std::vector tempCharBuffer(tempInfoLog.getLength()+3); + tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); + ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); + } + else + { + mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable)); + } + + *outExectuable = vertexExecutable; + return gl::Error(GL_NO_ERROR); } -bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, int *registers, - std::vector *linkedVaryings, std::map *outputVariables) +gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + int registers) { - rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); - rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); + ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + + gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS]; + GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout); + ShaderExecutable *defaultVertexExecutable = NULL; + gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + std::vector defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey()); + ShaderExecutable *defaultPixelExecutable = NULL; + error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + + if (usesGeometryShader()) + { + std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D); + + + error = mRenderer->compileToExecutable(infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, + (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), + ANGLE_D3D_WORKAROUND_NONE, &mGeometryExecutable); + if (error.isError()) + { + return gl::LinkResult(false, error); + } + } + +#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED + if (usesGeometryShader() && mGeometryExecutable) + { + // Geometry shaders are currently only used internally, so there is no corresponding shader object at the interface level + // For now the geometry shader debug info is pre-pended to the vertex shader, this is a bit of a clutch + vertexShaderD3D->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n"); + vertexShaderD3D->appendDebugInfo(mGeometryExecutable->getDebugInfo()); + vertexShaderD3D->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n"); + } + + if (defaultVertexExecutable) + { + vertexShaderD3D->appendDebugInfo(defaultVertexExecutable->getDebugInfo()); + } + + if (defaultPixelExecutable) + { + fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo()); + } +#endif + + bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable)); + return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR)); +} + +gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog, + gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode, + int *registers, std::vector *linkedVaryings, + std::map *outputVariables) +{ + ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); + ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); + + mSamplersPS.resize(data.caps->maxTextureImageUnits); + mSamplersVS.resize(data.caps->maxVertexTextureImageUnits); + + mTransformFeedbackBufferMode = transformFeedbackBufferMode; mPixelHLSL = fragmentShaderD3D->getTranslatedSource(); mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds(); mVertexHLSL = vertexShaderD3D->getTranslatedSource(); mVertexWorkarounds = vertexShaderD3D->getD3DWorkarounds(); + mShaderVersion = vertexShaderD3D->getShaderVersion(); // Map the varyings to the register file - rx::VaryingPacking packing = { NULL }; + VaryingPacking packing = { NULL }; *registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings); if (*registers < 0) { - return false; + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); } if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader)) { - return false; + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); } - if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL, + if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings, linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth)) { - return false; + return gl::LinkResult(false, gl::Error(GL_NO_ERROR)); } - return true; + mUsesPointSize = vertexShaderD3D->usesPointSize(); + + return gl::LinkResult(true, gl::Error(GL_NO_ERROR)); } -void ProgramD3D::initializeUniformStorage(const std::vector &uniforms) +void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const +{ + mDynamicHLSL->getInputLayoutSignature(inputLayout, signature); +} + +void ProgramD3D::initializeUniformStorage() { // Compute total default block size unsigned int vertexRegisters = 0; unsigned int fragmentRegisters = 0; - for (size_t uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++) + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) { - const gl::LinkedUniform &uniform = *uniforms[uniformIndex]; + const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; if (!gl::IsSampler(uniform.type)) { @@ -188,18 +1059,867 @@ void ProgramD3D::initializeUniformStorage(const std::vector mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u); } +gl::Error ProgramD3D::applyUniforms() +{ + updateSamplerMapping(); + + gl::Error error = mRenderer->applyUniforms(*this, mUniforms); + if (error.isError()) + { + return error; + } + + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + mUniforms[uniformIndex]->dirty = false; + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error ProgramD3D::applyUniformBuffers(const std::vector boundBuffers, const gl::Caps &caps) +{ + ASSERT(boundBuffers.size() == mUniformBlocks.size()); + + const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL}; + const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL}; + + const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers(); + const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers(); + + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++) + { + gl::UniformBlock *uniformBlock = mUniformBlocks[uniformBlockIndex]; + gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex]; + + ASSERT(uniformBlock && uniformBuffer); + + if (uniformBuffer->getSize() < uniformBlock->dataSize) + { + // undefined behaviour + return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."); + } + + // Unnecessary to apply an unreferenced standard or shared UBO + if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader()) + { + continue; + } + + if (uniformBlock->isReferencedByVertexShader()) + { + unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS; + ASSERT(vertexUniformBuffers[registerIndex] == NULL); + ASSERT(registerIndex < caps.maxVertexUniformBlocks); + vertexUniformBuffers[registerIndex] = uniformBuffer; + } + + if (uniformBlock->isReferencedByFragmentShader()) + { + unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS; + ASSERT(fragmentUniformBuffers[registerIndex] == NULL); + ASSERT(registerIndex < caps.maxFragmentUniformBlocks); + fragmentUniformBuffers[registerIndex] = uniformBuffer; + } + } + + return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers); +} + +bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, + unsigned int registerIndex, const gl::Caps &caps) +{ + if (shader == GL_VERTEX_SHADER) + { + uniformBlock->vsRegisterIndex = registerIndex; + if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks) + { + infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks); + return false; + } + } + else if (shader == GL_FRAGMENT_SHADER) + { + uniformBlock->psRegisterIndex = registerIndex; + if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks) + { + infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks); + return false; + } + } + else UNREACHABLE(); + + return true; +} + +void ProgramD3D::dirtyAllUniforms() +{ + unsigned int numUniforms = mUniforms.size(); + for (unsigned int index = 0; index < numUniforms; index++) + { + mUniforms[index]->dirty = true; + } +} + +void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) +{ + setUniform(location, count, v, GL_FLOAT); +} + +void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC2); +} + +void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC3); +} + +void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ + setUniform(location, count, v, GL_FLOAT_VEC4); +} + +void ProgramD3D::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); +} + +void ProgramD3D::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); +} + +void ProgramD3D::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); +} + +void ProgramD3D::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); +} + +void ProgramD3D::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); +} + +void ProgramD3D::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); +} + +void ProgramD3D::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); +} + +void ProgramD3D::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); +} + +void ProgramD3D::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); +} + +void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT); +} + +void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT_VEC2); +} + +void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT_VEC3); +} + +void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v) +{ + setUniform(location, count, v, GL_INT_VEC4); +} + +void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT); +} + +void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC2); +} + +void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC3); +} + +void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) +{ + setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); +} + +void ProgramD3D::getUniformfv(GLint location, GLfloat *params) +{ + getUniformv(location, params, GL_FLOAT); +} + +void ProgramD3D::getUniformiv(GLint location, GLint *params) +{ + getUniformv(location, params, GL_INT); +} + +void ProgramD3D::getUniformuiv(GLint location, GLuint *params) +{ + getUniformv(location, params, GL_UNSIGNED_INT); +} + +bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps) +{ + const ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader.getImplementation()); + const ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader.getImplementation()); + + const std::vector &vertexUniforms = vertexShader.getUniforms(); + const std::vector &fragmentUniforms = fragmentShader.getUniforms(); + + // Check that uniforms defined in the vertex and fragment shaders are identical + typedef std::map UniformMap; + UniformMap linkedUniforms; + + for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++) + { + const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex]; + linkedUniforms[vertexUniform.name] = &vertexUniform; + } + + for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++) + { + const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex]; + UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name); + if (entry != linkedUniforms.end()) + { + const sh::Uniform &vertexUniform = *entry->second; + const std::string &uniformName = "uniform '" + vertexUniform.name + "'"; + if (!gl::ProgramBinary::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform)) + { + return false; + } + } + } + + for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) + { + const sh::Uniform &uniform = vertexUniforms[uniformIndex]; + + if (uniform.staticUse) + { + defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name)); + } + } + + for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) + { + const sh::Uniform &uniform = fragmentUniforms[uniformIndex]; + + if (uniform.staticUse) + { + defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name)); + } + } + + if (!indexUniforms(infoLog, caps)) + { + return false; + } + + initializeUniformStorage(); + + // special case for gl_DepthRange, the only built-in uniform (also a struct) + if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange()) + { + const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo(); + + mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo)); + mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo)); + mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo)); + } + + return true; +} + +void ProgramD3D::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister) +{ + ShShaderOutput outputType = ShaderD3D::getCompilerOutputType(shader); + sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); + encoder.skipRegisters(uniformRegister); + + defineUniform(shader, uniform, uniform.name, &encoder); +} + +void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform, + const std::string &fullName, sh::HLSLBlockEncoder *encoder) +{ + if (uniform.isStruct()) + { + for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) + { + const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); + + encoder->enterAggregateType(); + + for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) + { + const sh::ShaderVariable &field = uniform.fields[fieldIndex]; + const std::string &fieldFullName = (fullName + elementString + "." + field.name); + + defineUniform(shader, field, fieldFullName, encoder); + } + + encoder->exitAggregateType(); + } + } + else // Not a struct + { + // Arrays are treated as aggregate types + if (uniform.isArray()) + { + encoder->enterAggregateType(); + } + + gl::LinkedUniform *linkedUniform = getUniformByName(fullName); + + if (!linkedUniform) + { + linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, + -1, sh::BlockMemberInfo::getDefaultBlockInfo()); + ASSERT(linkedUniform); + linkedUniform->registerElement = encoder->getCurrentElement(); + mUniforms.push_back(linkedUniform); + } + + ASSERT(linkedUniform->registerElement == encoder->getCurrentElement()); + + if (shader == GL_FRAGMENT_SHADER) + { + linkedUniform->psRegisterIndex = encoder->getCurrentRegister(); + } + else if (shader == GL_VERTEX_SHADER) + { + linkedUniform->vsRegisterIndex = encoder->getCurrentRegister(); + } + else UNREACHABLE(); + + // Advance the uniform offset, to track registers allocation for structs + encoder->encodeType(uniform.type, uniform.arraySize, false); + + // Arrays are treated as aggregate types + if (uniform.isArray()) + { + encoder->exitAggregateType(); + } + } +} + +template +static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) +{ + ASSERT(dest != NULL); + ASSERT(dirtyFlag != NULL); + + *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); + *dest = source; +} + +template +void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType) +{ + const int components = gl::VariableComponentCount(targetUniformType); + const GLenum targetBoolType = gl::VariableBoolVectorType(targetUniformType); + + gl::LinkedUniform *targetUniform = getUniformByLocation(location); + + int elementCount = targetUniform->elementCount(); + + count = std::min(elementCount - (int)mUniformIndex[location].element, count); + + if (targetUniform->type == targetUniformType) + { + T *target = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + T *dest = target + (i * 4); + const T *source = v + (i * components); + + for (int c = 0; c < components; c++) + { + SetIfDirty(dest + c, source[c], &targetUniform->dirty); + } + for (int c = components; c < 4; c++) + { + SetIfDirty(dest + c, T(0), &targetUniform->dirty); + } + } + } + else if (targetUniform->type == targetBoolType) + { + GLint *boolParams = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + GLint *dest = boolParams + (i * 4); + const T *source = v + (i * components); + + for (int c = 0; c < components; c++) + { + SetIfDirty(dest + c, (source[c] == static_cast(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); + } + for (int c = components; c < 4; c++) + { + SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty); + } + } + } + else if (gl::IsSampler(targetUniform->type)) + { + ASSERT(targetUniformType == GL_INT); + + GLint *target = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; + + bool wasDirty = targetUniform->dirty; + + for (int i = 0; i < count; i++) + { + GLint *dest = target + (i * 4); + const GLint *source = reinterpret_cast(v) + (i * components); + + SetIfDirty(dest + 0, source[0], &targetUniform->dirty); + SetIfDirty(dest + 1, 0, &targetUniform->dirty); + SetIfDirty(dest + 2, 0, &targetUniform->dirty); + SetIfDirty(dest + 3, 0, &targetUniform->dirty); + } + + if (!wasDirty && targetUniform->dirty) + { + mDirtySamplerMapping = true; + } + } + else UNREACHABLE(); +} + +template +bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) +{ + bool dirty = false; + int copyWidth = std::min(targetHeight, srcWidth); + int copyHeight = std::min(targetWidth, srcHeight); + + for (int x = 0; x < copyWidth; x++) + { + for (int y = 0; y < copyHeight; y++) + { + SetIfDirty(target + (x * targetWidth + y), static_cast(value[y * srcWidth + x]), &dirty); + } + } + // clear unfilled right side + for (int y = 0; y < copyWidth; y++) + { + for (int x = copyHeight; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + // clear unfilled bottom. + for (int y = copyWidth; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + + return dirty; +} + +template +bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) +{ + bool dirty = false; + int copyWidth = std::min(targetWidth, srcWidth); + int copyHeight = std::min(targetHeight, srcHeight); + + for (int y = 0; y < copyHeight; y++) + { + for (int x = 0; x < copyWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(value[y * srcWidth + x]), &dirty); + } + } + // clear unfilled right side + for (int y = 0; y < copyHeight; y++) + { + for (int x = copyWidth; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + // clear unfilled bottom. + for (int y = copyHeight; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + + return dirty; +} + +template +void ProgramD3D::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType) +{ + gl::LinkedUniform *targetUniform = getUniformByLocation(location); + + int elementCount = targetUniform->elementCount(); + + count = std::min(elementCount - (int)mUniformIndex[location].element, count); + const unsigned int targetMatrixStride = (4 * rows); + GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride); + + for (int i = 0; i < count; i++) + { + // Internally store matrices as transposed versions to accomodate HLSL matrix indexing + if (transpose == GL_FALSE) + { + targetUniform->dirty = transposeMatrix(target, value, 4, rows, rows, cols) || targetUniform->dirty; + } + else + { + targetUniform->dirty = expandMatrix(target, value, 4, rows, cols, rows) || targetUniform->dirty; + } + target += targetMatrixStride; + value += cols * rows; + } +} + +template +void ProgramD3D::getUniformv(GLint location, T *params, GLenum uniformType) +{ + gl::LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; + + if (gl::IsMatrixType(targetUniform->type)) + { + const int rows = gl::VariableRowCount(targetUniform->type); + const int cols = gl::VariableColumnCount(targetUniform->type); + transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows); + } + else if (uniformType == gl::VariableComponentType(targetUniform->type)) + { + unsigned int size = gl::VariableComponentCount(targetUniform->type); + memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T), + size * sizeof(T)); + } + else + { + unsigned int size = gl::VariableComponentCount(targetUniform->type); + switch (gl::VariableComponentType(targetUniform->type)) + { + case GL_BOOL: + { + GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = (boolParams[i] == GL_FALSE) ? static_cast(0) : static_cast(1); + } + } + break; + + case GL_FLOAT: + { + GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast(floatParams[i]); + } + } + break; + + case GL_INT: + { + GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast(intParams[i]); + } + } + break; + + case GL_UNSIGNED_INT: + { + GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4; + + for (unsigned int i = 0; i < size; i++) + { + params[i] = static_cast(uintParams[i]); + } + } + break; + + default: UNREACHABLE(); + } + } +} + +template +void ProgramD3D::defineUniformBlockMembers(const std::vector &fields, const std::string &prefix, int blockIndex, + sh::BlockLayoutEncoder *encoder, std::vector *blockUniformIndexes, + bool inRowMajorLayout) +{ + for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++) + { + const VarT &field = fields[uniformIndex]; + const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); + + if (field.isStruct()) + { + bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); + + for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) + { + encoder->enterAggregateType(); + + const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); + defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout); + + encoder->exitAggregateType(); + } + } + else + { + bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout); + + sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); + + gl::LinkedUniform *newUniform = new gl::LinkedUniform(field.type, field.precision, fieldName, field.arraySize, + blockIndex, memberInfo); + + // add to uniform list, but not index, since uniform block uniforms have no location + blockUniformIndexes->push_back(mUniforms.size()); + mUniforms.push_back(newUniform); + } + } +} + +bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, + const gl::Caps &caps) +{ + const ShaderD3D* shaderD3D = ShaderD3D::makeShaderD3D(shader.getImplementation()); + + // create uniform block entries if they do not exist + if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX) + { + std::vector blockUniformIndexes; + const unsigned int blockIndex = mUniformBlocks.size(); + + // define member uniforms + sh::BlockLayoutEncoder *encoder = NULL; + + if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) + { + encoder = new sh::Std140BlockEncoder; + } + else + { + encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); + } + ASSERT(encoder); + + defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout); + + size_t dataSize = encoder->getBlockSize(); + + // create all the uniform blocks + if (interfaceBlock.arraySize > 0) + { + for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++) + { + gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize); + newUniformBlock->memberUniformIndexes = blockUniformIndexes; + mUniformBlocks.push_back(newUniformBlock); + } + } + else + { + gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize); + newUniformBlock->memberUniformIndexes = blockUniformIndexes; + mUniformBlocks.push_back(newUniformBlock); + } + } + + if (interfaceBlock.staticUse) + { + // Assign registers to the uniform blocks + const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name); + const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize); + ASSERT(blockIndex != GL_INVALID_INDEX); + ASSERT(blockIndex + elementCount <= mUniformBlocks.size()); + + unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name); + + for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++) + { + gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; + ASSERT(uniformBlock->name == interfaceBlock.name); + + if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(), + interfaceBlockRegister + uniformBlockElement, caps)) + { + return false; + } + } + } + + return true; +} + +bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex, + GLenum samplerType, + unsigned int samplerCount, + std::vector &outSamplers, + GLuint *outUsedRange) +{ + unsigned int samplerIndex = startSamplerIndex; + + do + { + if (samplerIndex < outSamplers.size()) + { + Sampler& sampler = outSamplers[samplerIndex]; + sampler.active = true; + sampler.textureType = GetTextureType(samplerType); + sampler.logicalTextureUnit = 0; + *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); + } + else + { + return false; + } + + samplerIndex++; + } while (samplerIndex < startSamplerIndex + samplerCount); + + return true; +} + +bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps) +{ + ASSERT(gl::IsSampler(uniform.type)); + ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX); + + if (uniform.vsRegisterIndex != GL_INVALID_INDEX) + { + if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS, + &mUsedVertexSamplerRange)) + { + infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", + mSamplersVS.size()); + return false; + } + + unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors; + if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors) + { + infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", + caps.maxVertexUniformVectors); + return false; + } + } + + if (uniform.psRegisterIndex != GL_INVALID_INDEX) + { + if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS, + &mUsedPixelSamplerRange)) + { + infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", + mSamplersPS.size()); + return false; + } + + unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors; + if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors) + { + infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", + caps.maxFragmentUniformVectors); + return false; + } + } + + return true; +} + +bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) +{ + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; + + if (gl::IsSampler(uniform.type)) + { + if (!indexSamplerUniform(uniform, infoLog, caps)) + { + return false; + } + } + + for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++) + { + mUniformIndex.push_back(gl::VariableLocation(uniform.name, arrayElementIndex, uniformIndex)); + } + } + + return true; +} + void ProgramD3D::reset() { + ProgramImpl::reset(); + + SafeDeleteContainer(mVertexExecutables); + SafeDeleteContainer(mPixelExecutables); + SafeDelete(mGeometryExecutable); + + mTransformFeedbackBufferMode = GL_NONE; + mVertexHLSL.clear(); - mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; + mVertexWorkarounds = ANGLE_D3D_WORKAROUND_NONE; + mShaderVersion = 100; mPixelHLSL.clear(); - mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE; + mPixelWorkarounds = ANGLE_D3D_WORKAROUND_NONE; mUsesFragDepth = false; mPixelShaderKey.clear(); + mUsesPointSize = false; SafeDelete(mVertexUniformStorage); SafeDelete(mFragmentUniformStorage); + + mSamplersPS.clear(); + mSamplersVS.clear(); + + mUsedVertexSamplerRange = 0; + mUsedPixelSamplerRange = 0; + mDirtySamplerMapping = true; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h index d645c57daa..4baab9aa19 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h @@ -10,6 +10,7 @@ #define LIBGLESV2_RENDERER_PROGRAMD3D_H_ #include "libGLESv2/renderer/ProgramImpl.h" +#include "libGLESv2/renderer/Workarounds.h" #include #include @@ -23,63 +24,194 @@ struct VertexFormat; namespace rx { - +class RendererD3D; class UniformStorage; class ProgramD3D : public ProgramImpl { public: - ProgramD3D(rx::Renderer *renderer); + ProgramD3D(RendererD3D *renderer); virtual ~ProgramD3D(); static ProgramD3D *makeProgramD3D(ProgramImpl *impl); static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl); - Renderer *getRenderer() { return mRenderer; } - DynamicHLSL *getDynamicHLSL() { return mDynamicHLSL; } - const std::vector &getPixelShaderKey() { return mPixelShaderKey; } + const std::vector &getPixelShaderKey() { return mPixelShaderKey; } + int getShaderVersion() const { return mShaderVersion; } + GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } + + GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const; + GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const; + GLint getUsedSamplerRange(gl::SamplerType type) const; + void updateSamplerMapping(); + bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps); + + bool usesPointSize() const { return mUsesPointSize; } + bool usesPointSpriteEmulation() const; + bool usesGeometryShader() const; GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; } - bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); - bool save(gl::BinaryOutputStream *stream); + gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); + gl::Error save(gl::BinaryOutputStream *stream); - ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector &outputSignature, - const std::vector &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers); - ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog, - const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], - const sh::Attribute shaderAttributes[], - const std::vector &transformFeedbackLinkedVaryings, - bool separatedOutputBuffers); + gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExectuable); + gl::Error getPixelExecutableForOutputLayout(const std::vector &outputLayout, ShaderExecutable **outExectuable); + gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable); + ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; } - bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, int *registers, - std::vector *linkedVaryings, std::map *outputVariables); + gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, + int registers); - // D3D only - void initializeUniformStorage(const std::vector &uniforms); + gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog, + gl::Shader *fragmentShader, gl::Shader *vertexShader, + const std::vector &transformFeedbackVaryings, + GLenum transformFeedbackBufferMode, + int *registers, std::vector *linkedVaryings, + std::map *outputVariables); + + void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const; + + void initializeUniformStorage(); + gl::Error applyUniforms(); + gl::Error applyUniformBuffers(const std::vector boundBuffers, const gl::Caps &caps); + bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, + unsigned int registerIndex, const gl::Caps &caps); + void dirtyAllUniforms(); + + void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); + void setUniform1iv(GLint location, GLsizei count, const GLint *v); + void setUniform2iv(GLint location, GLsizei count, const GLint *v); + void setUniform3iv(GLint location, GLsizei count, const GLint *v); + void setUniform4iv(GLint location, GLsizei count, const GLint *v); + void setUniform1uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform2uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform3uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform4uiv(GLint location, GLsizei count, const GLuint *v); + void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + + void getUniformfv(GLint location, GLfloat *params); + void getUniformiv(GLint location, GLint *params); + void getUniformuiv(GLint location, GLuint *params); const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; } const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } + bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, + const gl::Caps &caps); + bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps); + void reset(); private: DISALLOW_COPY_AND_ASSIGN(ProgramD3D); - Renderer *mRenderer; + class VertexExecutable + { + public: + VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], + const GLenum signature[gl::MAX_VERTEX_ATTRIBS], + ShaderExecutable *shaderExecutable); + ~VertexExecutable(); + + bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const; + + const gl::VertexFormat *inputs() const { return mInputs; } + const GLenum *signature() const { return mSignature; } + ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } + + private: + gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS]; + GLenum mSignature[gl::MAX_VERTEX_ATTRIBS]; + ShaderExecutable *mShaderExecutable; + }; + + class PixelExecutable + { + public: + PixelExecutable(const std::vector &outputSignature, ShaderExecutable *shaderExecutable); + ~PixelExecutable(); + + bool matchesSignature(const std::vector &signature) const { return mOutputSignature == signature; } + + const std::vector &outputSignature() const { return mOutputSignature; } + ShaderExecutable *shaderExecutable() const { return mShaderExecutable; } + + private: + std::vector mOutputSignature; + ShaderExecutable *mShaderExecutable; + }; + + struct Sampler + { + Sampler(); + + bool active; + GLint logicalTextureUnit; + GLenum textureType; + }; + + void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister); + void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, + sh::HLSLBlockEncoder *encoder); + bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps); + bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); + static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, + std::vector &outSamplers, GLuint *outUsedRange); + + template + void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); + + template + void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); + + template + void getUniformv(GLint location, T *params, GLenum uniformType); + + template + void defineUniformBlockMembers(const std::vector &fields, const std::string &prefix, int blockIndex, + sh::BlockLayoutEncoder *encoder, std::vector *blockUniformIndexes, + bool inRowMajorLayout); + + RendererD3D *mRenderer; DynamicHLSL *mDynamicHLSL; + std::vector mVertexExecutables; + std::vector mPixelExecutables; + ShaderExecutable *mGeometryExecutable; + std::string mVertexHLSL; - rx::D3DWorkaroundType mVertexWorkarounds; + D3DWorkaroundType mVertexWorkarounds; std::string mPixelHLSL; - rx::D3DWorkaroundType mPixelWorkarounds; + D3DWorkaroundType mPixelWorkarounds; bool mUsesFragDepth; - std::vector mPixelShaderKey; + std::vector mPixelShaderKey; + + bool mUsesPointSize; UniformStorage *mVertexUniformStorage; UniformStorage *mFragmentUniformStorage; + + GLenum mTransformFeedbackBufferMode; + + std::vector mSamplersPS; + std::vector mSamplersVS; + GLuint mUsedVertexSamplerRange; + GLuint mUsedPixelSamplerRange; + bool mDirtySamplerMapping; + + int mShaderVersion; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp new file mode 100644 index 0000000000..cb4af367a2 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp @@ -0,0 +1,108 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl + + +#include "libGLESv2/renderer/d3d/RenderbufferD3D.h" + +#include "libGLESv2/renderer/d3d/RendererD3D.h" +#include "libGLESv2/renderer/RenderTarget.h" + +namespace rx +{ +RenderbufferD3D::RenderbufferD3D(RendererD3D *renderer) : mRenderer(renderer) +{ + mRenderTarget = NULL; +} + +RenderbufferD3D::~RenderbufferD3D() +{ + SafeDelete(mRenderTarget); +} + +RenderbufferD3D *RenderbufferD3D::makeRenderbufferD3D(RenderbufferImpl *renderbuffer) +{ + ASSERT(HAS_DYNAMIC_TYPE(RenderbufferD3D*, renderbuffer)); + return static_cast(renderbuffer); +} + +gl::Error RenderbufferD3D::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) +{ + // If the renderbuffer parameters are queried, the calling function + // will expect one of the valid renderbuffer formats for use in + // glRenderbufferStorage, but we should create depth and stencil buffers + // as DEPTH24_STENCIL8 + GLenum creationFormat = internalformat; + if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8) + { + creationFormat = GL_DEPTH24_STENCIL8_OES; + } + + RenderTarget *newRT = NULL; + gl::Error error = mRenderer->createRenderTarget(width, height, creationFormat, samples, &newRT); + if (error.isError()) + { + return error; + } + + SafeDelete(mRenderTarget); + mRenderTarget = newRT; + + return gl::Error(GL_NO_ERROR); +} + +gl::Error RenderbufferD3D::setStorage(SwapChain *swapChain, bool depth) +{ + RenderTarget *newRT = NULL; + gl::Error error = mRenderer->createRenderTarget(swapChain, depth, &newRT); + if (error.isError()) + { + return error; + } + + SafeDelete(mRenderTarget); + mRenderTarget = newRT; + + return gl::Error(GL_NO_ERROR); +} + +GLsizei RenderbufferD3D::getWidth() const +{ + return (mRenderTarget ? mRenderTarget->getWidth() : 0); +} + +GLsizei RenderbufferD3D::getHeight() const +{ + return (mRenderTarget ? mRenderTarget->getHeight() : 0); +} + +GLenum RenderbufferD3D::getInternalFormat() const +{ + return (mRenderTarget ? mRenderTarget->getInternalFormat() : GL_RGBA4); +} + +GLenum RenderbufferD3D::getActualFormat() const +{ + return (mRenderTarget ? mRenderTarget->getActualFormat() : GL_RGBA4); +} + +GLsizei RenderbufferD3D::getSamples() const +{ + return (mRenderTarget ? mRenderTarget->getSamples() : 0); +} + +RenderTarget *RenderbufferD3D::getRenderTarget() +{ + return mRenderTarget; +} + +unsigned int RenderbufferD3D::getRenderTargetSerial() const +{ + return (mRenderTarget ? mRenderTarget->getSerial() : 0); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h new file mode 100644 index 0000000000..9440a449f2 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h @@ -0,0 +1,51 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RenderbufferD3d.h: Defines the RenderbufferD3D class which implements RenderbufferImpl. + +#ifndef LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_ +#define LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_ + +#include "angle_gl.h" + +#include "common/angleutils.h" +#include "libGLESv2/renderer/RenderbufferImpl.h" + +namespace rx +{ +class RendererD3D; +class RenderTarget; +class SwapChain; + +class RenderbufferD3D : public RenderbufferImpl +{ + public: + RenderbufferD3D(RendererD3D *renderer); + virtual ~RenderbufferD3D(); + + static RenderbufferD3D *makeRenderbufferD3D(RenderbufferImpl *renderbuffer); + + virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) override; + gl::Error setStorage(SwapChain *swapChain, bool depth); + + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual GLenum getActualFormat() const; + virtual GLsizei getSamples() const; + + RenderTarget *getRenderTarget(); + unsigned int getRenderTargetSerial() const; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderbufferD3D); + + RendererD3D *mRenderer; + RenderTarget *mRenderTarget; +}; +} + +#endif // LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp new file mode 100644 index 0000000000..97da6da7fd --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp @@ -0,0 +1,796 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RendererD3D.cpp: Implementation of the base D3D Renderer. + +#include "libGLESv2/renderer/d3d/RendererD3D.h" + +#include "libGLESv2/renderer/d3d/IndexDataManager.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/FramebufferAttachment.h" +#include "libGLESv2/ResourceManager.h" +#include "libGLESv2/State.h" +#include "libGLESv2/VertexArray.h" +#include "libGLESv2/formatutils.h" +#include "common/utilities.h" + +namespace rx +{ + +RendererD3D::RendererD3D(egl::Display *display) + : mDisplay(display) +{ +} + +RendererD3D::~RendererD3D() +{ + for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i) + { + i->second.set(NULL); + } + mIncompleteTextures.clear(); +} + +// static +RendererD3D *RendererD3D::makeRendererD3D(Renderer *renderer) +{ + ASSERT(HAS_DYNAMIC_TYPE(RendererD3D*, renderer)); + return static_cast(renderer); +} + +gl::Error RendererD3D::drawElements(const gl::Data &data, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei instances, + const RangeUI &indexRange) +{ + ASSERT(data.state->getCurrentProgramId() != 0); + + gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary(); + programBinary->updateSamplerMapping(); + + gl::Error error = generateSwizzles(data); + if (error.isError()) + { + return error; + } + + if (!applyPrimitiveType(mode, count)) + { + return gl::Error(GL_NO_ERROR); + } + + error = applyRenderTarget(data, mode, false); + if (error.isError()) + { + return error; + } + + error = applyState(data, mode); + if (error.isError()) + { + return error; + } + + gl::VertexArray *vao = data.state->getVertexArray(); + TranslatedIndexData indexInfo; + indexInfo.indexRange = indexRange; + error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo); + if (error.isError()) + { + return error; + } + + GLsizei vertexCount = indexInfo.indexRange.length() + 1; + error = applyVertexBuffer(*data.state, indexInfo.indexRange.start, vertexCount, instances); + if (error.isError()) + { + return error; + } + + bool transformFeedbackActive = applyTransformFeedbackBuffers(data); + // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation + // layer. + ASSERT(!transformFeedbackActive); + + error = applyShaders(data, transformFeedbackActive); + if (error.isError()) + { + return error; + } + + error = applyTextures(data); + if (error.isError()) + { + return error; + } + + error = applyUniformBuffers(data); + if (error.isError()) + { + return error; + } + + if (!skipDraw(data, mode)) + { + error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error RendererD3D::drawArrays(const gl::Data &data, + GLenum mode, GLint first, + GLsizei count, GLsizei instances) +{ + ASSERT(data.state->getCurrentProgramId() != 0); + + gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary(); + programBinary->updateSamplerMapping(); + + gl::Error error = generateSwizzles(data); + if (error.isError()) + { + return error; + } + + if (!applyPrimitiveType(mode, count)) + { + return gl::Error(GL_NO_ERROR); + } + + error = applyRenderTarget(data, mode, false); + if (error.isError()) + { + return error; + } + + error = applyState(data, mode); + if (error.isError()) + { + return error; + } + + error = applyVertexBuffer(*data.state, first, count, instances); + if (error.isError()) + { + return error; + } + + bool transformFeedbackActive = applyTransformFeedbackBuffers(data); + + error = applyShaders(data, transformFeedbackActive); + if (error.isError()) + { + return error; + } + + error = applyTextures(data); + if (error.isError()) + { + return error; + } + + error = applyUniformBuffers(data); + if (error.isError()) + { + return error; + } + + if (!skipDraw(data, mode)) + { + error = drawArrays(mode, count, instances, transformFeedbackActive); + if (error.isError()) + { + return error; + } + + if (transformFeedbackActive) + { + markTransformFeedbackUsage(data); + } + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type) +{ + gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary(); + + size_t samplerRange = programBinary->getUsedSamplerRange(type); + + for (size_t i = 0; i < samplerRange; i++) + { + GLenum textureType = programBinary->getSamplerTextureType(type, i); + GLint textureUnit = programBinary->getSamplerMapping(type, i, *data.caps); + if (textureUnit != -1) + { + gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); + ASSERT(texture); + if (texture->getSamplerState().swizzleRequired()) + { + gl::Error error = generateSwizzle(texture); + if (error.isError()) + { + return error; + } + } + } + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error RendererD3D::generateSwizzles(const gl::Data &data) +{ + gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX); + if (error.isError()) + { + return error; + } + + error = generateSwizzles(data, gl::SAMPLER_PIXEL); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); +} + +// Applies the render target surface, depth stencil surface, viewport rectangle and +// scissor rectangle to the renderer +gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport) +{ + const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); + ASSERT(framebufferObject && framebufferObject->completeness(data) == GL_FRAMEBUFFER_COMPLETE); + + gl::Error error = applyRenderTarget(framebufferObject); + if (error.isError()) + { + return error; + } + + float nearZ, farZ; + data.state->getDepthRange(&nearZ, &farZ); + setViewport(data.state->getViewport(), nearZ, farZ, drawMode, + data.state->getRasterizerState().frontFace, ignoreViewport); + + setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); + + return gl::Error(GL_NO_ERROR); +} + +// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device +gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode) +{ + const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); + int samples = framebufferObject->getSamples(data); + + gl::RasterizerState rasterizer = data.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); + + gl::Error error = setRasterizerState(rasterizer); + if (error.isError()) + { + return error; + } + + unsigned int mask = 0; + if (data.state->isSampleCoverageEnabled()) + { + GLclampf coverageValue; + bool coverageInvert = false; + data.state->getSampleCoverageParams(&coverageValue, &coverageInvert); + if (coverageValue != 0) + { + float threshold = 0.5f; + + for (int i = 0; i < samples; ++i) + { + mask <<= 1; + + if ((i + 1) * coverageValue >= threshold) + { + threshold += 1.0f; + mask |= 1; + } + } + } + + if (coverageInvert) + { + mask = ~mask; + } + } + else + { + mask = 0xFFFFFFFF; + } + error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask); + if (error.isError()) + { + return error; + } + + error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(), + data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); +} + +bool RendererD3D::applyTransformFeedbackBuffers(const gl::Data &data) +{ + gl::TransformFeedback *curTransformFeedback = data.state->getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) + { + applyTransformFeedbackBuffers(*data.state); + return true; + } + else + { + return false; + } +} + +// Applies the shaders and shader constants to the Direct3D device +gl::Error RendererD3D::applyShaders(const gl::Data &data, bool transformFeedbackActive) +{ + gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary(); + + gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]; + gl::VertexFormat::GetInputLayout(inputLayout, programBinary, *data.state); + + const gl::Framebuffer *fbo = data.state->getDrawFramebuffer(); + + gl::Error error = applyShaders(programBinary, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, transformFeedbackActive); + if (error.isError()) + { + return error; + } + + return programBinary->applyUniforms(); +} + +// For each Direct3D sampler of either the pixel or vertex stage, +// looks up the corresponding OpenGL texture image unit and texture type, +// and sets the texture and its addressing/filtering state (or NULL when inactive). +gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType, + const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount) +{ + gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary(); + + size_t samplerRange = programBinary->getUsedSamplerRange(shaderType); + for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) + { + GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex); + GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, *data.caps); + if (textureUnit != -1) + { + gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); + ASSERT(texture); + gl::SamplerState sampler = texture->getSamplerState(); + + gl::Sampler *samplerObject = data.state->getSampler(textureUnit); + if (samplerObject) + { + samplerObject->getState(&sampler); + } + + // TODO: std::binary_search may become unavailable using older versions of GCC + if (texture->isSamplerComplete(sampler, *data.textureCaps, *data.extensions, data.clientVersion) && + !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial())) + { + gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler); + if (error.isError()) + { + return error; + } + + error = setTexture(shaderType, samplerIndex, texture); + if (error.isError()) + { + return error; + } + } + else + { + // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. + gl::Texture *incompleteTexture = getIncompleteTexture(textureType); + gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture); + if (error.isError()) + { + return error; + } + } + } + else + { + // No texture bound to this slot even though it is used by the shader, bind a NULL texture + gl::Error error = setTexture(shaderType, samplerIndex, NULL); + if (error.isError()) + { + return error; + } + } + } + + // Set all the remaining textures to NULL + size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits + : data.caps->maxVertexTextureImageUnits; + for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) + { + gl::Error error = setTexture(shaderType, samplerIndex, NULL); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error RendererD3D::applyTextures(const gl::Data &data) +{ + FramebufferTextureSerialArray framebufferSerials; + size_t framebufferSerialCount = getBoundFramebufferTextureSerials(data, &framebufferSerials); + + gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount); + if (error.isError()) + { + return error; + } + + error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error RendererD3D::applyUniformBuffers(const gl::Data &data) +{ + gl::Program *programObject = data.resourceManager->getProgram(data.state->getCurrentProgramId()); + gl::ProgramBinary *programBinary = programObject->getProgramBinary(); + + std::vector boundBuffers; + + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++) + { + GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex); + + if (data.state->getIndexedUniformBuffer(blockBinding)->id() == 0) + { + // undefined behaviour + return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer."); + } + else + { + gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(blockBinding); + ASSERT(uniformBuffer); + boundBuffers.push_back(uniformBuffer); + } + } + + return programBinary->applyUniformBuffers(boundBuffers, *data.caps); +} + +bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) +{ + if (drawMode == GL_POINTS) + { + // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, + // which affects varying interpolation. Since the value of gl_PointSize is + // undefined when not written, just skip drawing to avoid unexpected results. + if (!data.state->getCurrentProgramBinary()->usesPointSize()) + { + // This is stictly speaking not an error, but developers should be + // notified of risking undefined behavior. + ERR("Point rendering without writing to gl_PointSize."); + + return true; + } + } + else if (gl::IsTriangleMode(drawMode)) + { + if (data.state->getRasterizerState().cullFace && data.state->getRasterizerState().cullMode == GL_FRONT_AND_BACK) + { + return true; + } + } + + return false; +} + +void RendererD3D::markTransformFeedbackUsage(const gl::Data &data) +{ + for (size_t i = 0; i < data.caps->maxTransformFeedbackSeparateAttributes; i++) + { + gl::Buffer *buffer = data.state->getIndexedTransformFeedbackBuffer(i); + if (buffer) + { + buffer->markTransformFeedbackUsage(); + } + } +} + +size_t RendererD3D::getBoundFramebufferTextureSerials(const gl::Data &data, + FramebufferTextureSerialArray *outSerialArray) +{ + size_t serialCount = 0; + + const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++) + { + gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); + if (attachment && attachment->isTexture()) + { + gl::Texture *texture = attachment->getTexture(); + (*outSerialArray)[serialCount++] = texture->getTextureSerial(); + } + } + + gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); + if (depthStencilAttachment && depthStencilAttachment->isTexture()) + { + gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture(); + (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial(); + } + + std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount); + + return serialCount; +} + +gl::Texture *RendererD3D::getIncompleteTexture(GLenum type) +{ + if (mIncompleteTextures.find(type) == mIncompleteTextures.end()) + { + const GLubyte color[] = { 0, 0, 0, 255 }; + const gl::PixelUnpackState incompleteUnpackState(1); + + gl::Texture* t = NULL; + switch (type) + { + default: + UNREACHABLE(); + // default falls through to TEXTURE_2D + + case GL_TEXTURE_2D: + { + gl::Texture2D *incomplete2d = new gl::Texture2D(createTexture(GL_TEXTURE_2D), gl::Texture::INCOMPLETE_TEXTURE_ID); + incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + t = incomplete2d; + } + break; + + case GL_TEXTURE_CUBE_MAP: + { + gl::TextureCubeMap *incompleteCube = new gl::TextureCubeMap(createTexture(GL_TEXTURE_CUBE_MAP), gl::Texture::INCOMPLETE_TEXTURE_ID); + + incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + + t = incompleteCube; + } + break; + + case GL_TEXTURE_3D: + { + gl::Texture3D *incomplete3d = new gl::Texture3D(createTexture(GL_TEXTURE_3D), gl::Texture::INCOMPLETE_TEXTURE_ID); + incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + + t = incomplete3d; + } + break; + + case GL_TEXTURE_2D_ARRAY: + { + gl::Texture2DArray *incomplete2darray = new gl::Texture2DArray(createTexture(GL_TEXTURE_2D_ARRAY), gl::Texture::INCOMPLETE_TEXTURE_ID); + incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + + t = incomplete2darray; + } + break; + } + + mIncompleteTextures[type].set(t); + } + + return mIncompleteTextures[type].get(); +} + +gl::Error RendererD3D::clear(const gl::Data &data, GLbitfield mask) +{ + gl::ClearParameters clearParams = data.state->getClearParameters(mask); + + // Clips the clear to the scissor rectangle but not the viewport + gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true); + if (error.isError()) + { + return error; + } + + return clear(clearParams, data.state->getDrawFramebuffer()); +} + +gl::Error RendererD3D::clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values) +{ + // glClearBufferfv can be called to clear the color buffer or depth buffer + gl::ClearParameters clearParams = data.state->getClearParameters(0); + + if (buffer == GL_COLOR) + { + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast(i)); + } + clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]); + clearParams.colorClearType = GL_FLOAT; + } + + if (buffer == GL_DEPTH) + { + clearParams.clearDepth = true; + clearParams.depthClearValue = values[0]; + } + + // Clips the clear to the scissor rectangle but not the viewport + gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true); + if (error.isError()) + { + return error; + } + + return clear(clearParams, data.state->getDrawFramebuffer()); +} + +gl::Error RendererD3D::clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values) +{ + // glClearBufferuiv can only be called to clear a color buffer + gl::ClearParameters clearParams = data.state->getClearParameters(0); + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast(i)); + } + clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]); + clearParams.colorClearType = GL_UNSIGNED_INT; + + // Clips the clear to the scissor rectangle but not the viewport + gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true); + if (error.isError()) + { + return error; + } + + return clear(clearParams, data.state->getDrawFramebuffer()); +} + +gl::Error RendererD3D::clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values) +{ + // glClearBufferiv can be called to clear the color buffer or stencil buffer + gl::ClearParameters clearParams = data.state->getClearParameters(0); + + if (buffer == GL_COLOR) + { + for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) + { + clearParams.clearColor[i] = (drawbuffer == static_cast(i)); + } + clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]); + clearParams.colorClearType = GL_INT; + } + + if (buffer == GL_STENCIL) + { + clearParams.clearStencil = true; + clearParams.stencilClearValue = values[1]; + } + + // Clips the clear to the scissor rectangle but not the viewport + gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true); + if (error.isError()) + { + return error; + } + + return clear(clearParams, data.state->getDrawFramebuffer()); +} + +gl::Error RendererD3D::clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, + GLfloat depth, GLint stencil) +{ + if (data.state->isRasterizerDiscardEnabled()) + { + return gl::Error(GL_NO_ERROR); + } + + // glClearBufferfi can only be called to clear a depth stencil buffer + gl::ClearParameters clearParams = data.state->getClearParameters(0); + clearParams.clearDepth = true; + clearParams.depthClearValue = depth; + clearParams.clearStencil = true; + clearParams.stencilClearValue = stencil; + + // Clips the clear to the scissor rectangle but not the viewport + gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true); + if (error.isError()) + { + return error; + } + + return clear(clearParams, data.state->getDrawFramebuffer()); +} + +gl::Error RendererD3D::blitFramebuffer(const gl::Data &data, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + const gl::Framebuffer *readFramebuffer = data.state->getReadFramebuffer(); + const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); + + bool blitRenderTarget = false; + bool blitDepth = false; + bool blitStencil = false; + if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer()) + { + blitRenderTarget = true; + } + if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) + { + blitStencil = true; + } + if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) + { + blitDepth = true; + } + + gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); + gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); + if (blitRenderTarget || blitDepth || blitStencil) + { + const gl::Rectangle *scissor = data.state->isScissorTestEnabled() ? &data.state->getScissor() : NULL; + gl::Error error = blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor, + blitRenderTarget, blitDepth, blitStencil, filter); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error RendererD3D::readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, void* pixels) +{ + const gl::Framebuffer *framebuffer = data.state->getReadFramebuffer(); + + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type); + const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); + GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, data.state->getPackAlignment()); + + return readPixels(framebuffer, x, y, width, height, format, type, outputPitch, data.state->getPackState(), + reinterpret_cast(pixels)); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h new file mode 100644 index 0000000000..9919207667 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h @@ -0,0 +1,195 @@ + +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RendererD3D.h: Defines a back-end specific class for the DirectX renderer. + +#ifndef LIBGLESV2_RENDERER_RENDERERD3D_H_ +#define LIBGLESV2_RENDERER_RENDERERD3D_H_ + +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/Data.h" + +//FIXME(jmadill): std::array is currently prohibited by Chromium style guide +#include + +namespace gl +{ +class InfoLog; +struct LinkedVarying; +class Texture; +} + +namespace rx +{ +class TextureStorage; +class VertexBuffer; +class IndexBuffer; +class ShaderExecutable; +class SwapChain; +class RenderTarget; +class Image; +class TextureStorage; +class UniformStorage; + +class RendererD3D : public Renderer +{ + public: + explicit RendererD3D(egl::Display *display); + virtual ~RendererD3D(); + + static RendererD3D *makeRendererD3D(Renderer *renderer); + + gl::Error drawArrays(const gl::Data &data, + GLenum mode, GLint first, + GLsizei count, GLsizei instances) override; + + gl::Error drawElements(const gl::Data &data, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei instances, + const RangeUI &indexRange) override; + + gl::Error clear(const gl::Data &data, GLbitfield mask) override; + gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLfloat *values) override; + gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLuint *values) override; + gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLint *values) override; + gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override; + + gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, void* pixels) override; + + gl::Error blitFramebuffer(const gl::Data &data, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) override; + + // Direct3D Specific methods + virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; + + virtual gl::Error generateSwizzle(gl::Texture *texture) = 0; + virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0; + virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; + + virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0; + + virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0; + virtual gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask) = 0; + virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) = 0; + + virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0; + virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + bool ignoreViewport) = 0; + + virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0; + virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, + bool rasterizerDiscard, bool transformFeedbackActive) = 0; + virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector &uniformArray) = 0; + virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0; + virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) = 0; + virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0; + virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0; + + virtual void markAllStateDirty() = 0; + + virtual unsigned int getReservedVertexUniformVectors() const = 0; + virtual unsigned int getReservedFragmentUniformVectors() const = 0; + virtual unsigned int getReservedVertexUniformBuffers() const = 0; + virtual unsigned int getReservedFragmentUniformBuffers() const = 0; + virtual bool getShareHandleSupport() const = 0; + virtual bool getPostSubBufferSupport() const = 0; + + // Pixel operations + virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0; + virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0; + virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; + virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0; + + virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0; + + // RenderTarget creation + virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) = 0; + virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) = 0; + + // Shader operations + virtual void releaseShaderCompiler() = 0; + virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable) = 0; + virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable) = 0; + virtual UniformStorage *createUniformStorage(size_t storageSize) = 0; + + // Image operations + virtual Image *createImage() = 0; + virtual gl::Error generateMipmap(Image *dest, Image *source) = 0; + virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0; + virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0; + virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0; + virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; + virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; + + // Buffer-to-texture and Texture-to-buffer copies + virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; + virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0; + + virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0; + virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0; + + virtual VertexBuffer *createVertexBuffer() = 0; + virtual IndexBuffer *createIndexBuffer() = 0; + + protected: + virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0; + virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, + gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; + virtual gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) = 0; + virtual gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, + const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, + bool blitDepth, bool blitStencil, GLenum filter) = 0; + + egl::Display *mDisplay; + + private: + DISALLOW_COPY_AND_ASSIGN(RendererD3D); + + //FIXME(jmadill): std::array is currently prohibited by Chromium style guide + typedef std::array FramebufferTextureSerialArray; + + gl::Error generateSwizzles(const gl::Data &data, gl::SamplerType type); + gl::Error generateSwizzles(const gl::Data &data); + + gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport); + gl::Error applyState(const gl::Data &data, GLenum drawMode); + bool applyTransformFeedbackBuffers(const gl::Data &data); + gl::Error applyShaders(const gl::Data &data, bool transformFeedbackActive); + gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType, + const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount); + gl::Error applyTextures(const gl::Data &data); + gl::Error applyUniformBuffers(const gl::Data &data); + + bool skipDraw(const gl::Data &data, GLenum drawMode); + void markTransformFeedbackUsage(const gl::Data &data); + + size_t getBoundFramebufferTextureSerials(const gl::Data &data, + FramebufferTextureSerialArray *outSerialArray); + gl::Texture *getIncompleteTexture(GLenum type); + + gl::TextureMap mIncompleteTextures; +}; + +} + +#endif // LIBGLESV2_RENDERER_RENDERERD3D_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp index c472113eba..8a97579e16 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp @@ -6,13 +6,36 @@ // ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl. -#include "libGLESv2/renderer/d3d/ShaderD3D.h" -#include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/Shader.h" #include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" +#include "libGLESv2/renderer/d3d/ShaderD3D.h" +#include "common/features.h" #include "common/utilities.h" +// Definitions local to the translation unit +namespace +{ + +const char *GetShaderTypeString(GLenum type) +{ + switch (type) + { + case GL_VERTEX_SHADER: + return "VERTEX"; + + case GL_FRAGMENT_SHADER: + return "FRAGMENT"; + + default: + UNREACHABLE(); + return ""; + } +} + +} + namespace rx { @@ -44,13 +67,13 @@ const std::vector *GetShaderVariables(const std::vector *variableLis return variableList; } -ShaderD3D::ShaderD3D(GLenum type, rx::Renderer *renderer) +ShaderD3D::ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer) : mType(type), mRenderer(renderer), mShaderVersion(100) { uncompile(); - initializeCompiler(); + initializeCompiler(data); } ShaderD3D::~ShaderD3D() @@ -69,23 +92,28 @@ const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl) return static_cast(impl); } +std::string ShaderD3D::getDebugInfo() const +{ + return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mType) + " SHADER END\n"; +} + // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler) -void ShaderD3D::initializeCompiler() +void ShaderD3D::initializeCompiler(const gl::Data &data) { if (!mFragmentCompiler) { - int result = ShInitialize(); + bool result = ShInitialize(); if (result) { + ShShaderSpec specVersion = (data.clientVersion >= 3) ? SH_GLES3_SPEC : SH_GLES2_SPEC; ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT; ShBuiltInResources resources; ShInitBuiltInResources(&resources); - // TODO(geofflang): use context's caps - const gl::Caps &caps = mRenderer->getRendererCaps(); - const gl::Extensions &extensions = mRenderer->getRendererExtensions(); + const gl::Caps &caps = *data.caps; + const gl::Extensions &extensions = *data.extensions; resources.MaxVertexAttribs = caps.maxVertexAttributes; resources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; @@ -107,8 +135,8 @@ void ShaderD3D::initializeCompiler() resources.MinProgramTexelOffset = caps.minProgramTexelOffset; resources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; - mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); - mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources); + mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, specVersion, hlslVersion, &resources); + mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, specVersion, hlslVersion, &resources); } } } @@ -126,7 +154,7 @@ void ShaderD3D::releaseCompiler() void ShaderD3D::parseVaryings(void *compiler) { - if (!mHlsl.empty()) + if (!mHlsl.empty()) { const std::vector *varyings = ShGetVaryings(compiler); ASSERT(varyings); @@ -183,21 +211,25 @@ void ShaderD3D::uncompile() mInterfaceBlocks.clear(); mActiveAttributes.clear(); mActiveOutputVariables.clear(); + mDebugInfo.clear(); } -void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) +void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::string &source) { // ensure the compiler is loaded - initializeCompiler(); + initializeCompiler(data); int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); std::string sourcePath; + +#if !defined (ANGLE_ENABLE_WINDOWS_STORE) if (gl::perfActive()) { sourcePath = getTempPath(); writeFile(sourcePath.c_str(), source.c_str(), source.length()); compileOptions |= SH_LINE_DIRECTIVES; } +#endif int result; if (sourcePath.empty()) @@ -220,25 +252,20 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); } - size_t shaderVersion = 100; - ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion); + mShaderVersion = ShGetShaderVersion(compiler); - mShaderVersion = static_cast(shaderVersion); - - if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3) + if (mShaderVersion == 300 && data.clientVersion < 3) { mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts"; TRACE("\n%s", mInfoLog.c_str()); } else if (result) { - size_t objCodeLen = 0; - ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen); - - char* outputHLSL = new char[objCodeLen]; - ShGetObjectCode(compiler, outputHLSL); + mHlsl = ShGetObjectCode(compiler); #ifdef _DEBUG + // Prefix hlsl shader with commented out glsl shader + // Useful in diagnostics tools like pix which capture the hlsl shaders std::ostringstream hlslStream; hlslStream << "// GLSL\n"; hlslStream << "//\n"; @@ -254,14 +281,10 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } hlslStream << "\n\n"; - hlslStream << outputHLSL; + hlslStream << mHlsl; mHlsl = hlslStream.str(); -#else - mHlsl = outputHLSL; #endif - SafeDeleteArray(outputHLSL); - mUniforms = *GetShaderVariables(ShGetUniforms(compiler)); for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) @@ -271,7 +294,7 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) if (uniform.staticUse) { unsigned int index = -1; - bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index); + bool result = ShGetUniformRegister(compiler, uniform.name, &index); UNUSED_ASSERTION_VARIABLE(result); ASSERT(result); @@ -288,7 +311,7 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) if (interfaceBlock.staticUse) { unsigned int index = -1; - bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index); + bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index); UNUSED_ASSERTION_VARIABLE(result); ASSERT(result); @@ -298,24 +321,19 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source) } else { - size_t infoLogLen = 0; - ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); - - char* infoLog = new char[infoLogLen]; - ShGetInfoLog(compiler, infoLog); - mInfoLog = infoLog; + mInfoLog = ShGetInfoLog(compiler); TRACE("\n%s", mInfoLog.c_str()); } } -rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const +D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const { if (mUsesDiscardRewriting) { // ANGLE issue 486: // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization - return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION; + return ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION; } if (mUsesNestedBreak) @@ -323,10 +341,10 @@ rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const // ANGLE issue 603: // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization // We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence - return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION; + return ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION; } - return rx::ANGLE_D3D_WORKAROUND_NONE; + return ANGLE_D3D_WORKAROUND_NONE; } // true if varying x has a higher priority in packing than y @@ -387,19 +405,16 @@ ShShaderOutput ShaderD3D::getCompilerOutputType(GLenum shader) default: UNREACHABLE(); return SH_HLSL9_OUTPUT; } - size_t outputType = 0; - ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType); - - return static_cast(outputType); + return ShGetShaderOutputType(compiler); } -bool ShaderD3D::compile(const std::string &source) +bool ShaderD3D::compile(const gl::Data &data, const std::string &source) { uncompile(); void *compiler = getCompiler(); - compileToHLSL(compiler, source); + compileToHLSL(data, compiler, source); if (mType == GL_VERTEX_SHADER) { @@ -420,6 +435,15 @@ bool ShaderD3D::compile(const std::string &source) } } +#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED + mDebugInfo += std::string("// ") + GetShaderTypeString(mType) + " SHADER BEGIN\n"; + mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n"; + mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n"; + // Successive steps will append more info +#else + mDebugInfo += getTranslatedSource(); +#endif + return !getTranslatedSource().empty(); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h index 40e64cf36c..3c9aac2c12 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h @@ -10,6 +10,7 @@ #define LIBGLESV2_RENDERER_SHADERD3D_H_ #include "libGLESv2/renderer/ShaderImpl.h" +#include "libGLESv2/renderer/Workarounds.h" #include "libGLESv2/Shader.h" #include @@ -17,22 +18,23 @@ namespace rx { class DynamicHLSL; -class Renderer; +class RendererD3D; class ShaderD3D : public ShaderImpl { friend class DynamicHLSL; public: - ShaderD3D(GLenum type, rx::Renderer *renderer); + ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer); virtual ~ShaderD3D(); static ShaderD3D *makeShaderD3D(ShaderImpl *impl); static const ShaderD3D *makeShaderD3D(const ShaderImpl *impl); // ShaderImpl implementation - const std::string &getInfoLog() const { return mInfoLog; } - const std::string &getTranslatedSource() const { return mHlsl; } + virtual const std::string &getInfoLog() const { return mInfoLog; } + virtual const std::string &getTranslatedSource() const { return mHlsl; } + virtual std::string getDebugInfo() const; // D3D-specific methods virtual void uncompile(); @@ -40,8 +42,9 @@ class ShaderD3D : public ShaderImpl unsigned int getUniformRegister(const std::string &uniformName) const; unsigned int getInterfaceBlockRegister(const std::string &blockName) const; int getSemanticIndex(const std::string &attributeName) const; + void appendDebugInfo(const std::string &info) { mDebugInfo += info; } - rx::D3DWorkaroundType getD3DWorkarounds() const; + D3DWorkaroundType getD3DWorkarounds() const; int getShaderVersion() const { return mShaderVersion; } bool usesDepthRange() const { return mUsesDepthRange; } bool usesPointSize() const { return mUsesPointSize; } @@ -49,15 +52,15 @@ class ShaderD3D : public ShaderImpl static void releaseCompiler(); static ShShaderOutput getCompilerOutputType(GLenum shader); - virtual bool compile(const std::string &source); + virtual bool compile(const gl::Data &data, const std::string &source); private: DISALLOW_COPY_AND_ASSIGN(ShaderD3D); - void compileToHLSL(void *compiler, const std::string &source); + void compileToHLSL(const gl::Data &data, void *compiler, const std::string &source); void parseVaryings(void *compiler); - void initializeCompiler(); + void initializeCompiler(const gl::Data &data); void parseAttributes(void *compiler); void *getCompiler(); @@ -67,7 +70,7 @@ class ShaderD3D : public ShaderImpl static void *mVertexCompiler; GLenum mType; - rx::Renderer *mRenderer; + RendererD3D *mRenderer; int mShaderVersion; @@ -85,6 +88,7 @@ class ShaderD3D : public ShaderImpl std::string mHlsl; std::string mInfoLog; + std::string mDebugInfo; std::map mUniformRegisterMap; std::map mInterfaceBlockRegisterMap; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp index 96c84977cb..4a67701fdf 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp @@ -6,9 +6,6 @@ // TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends. -#include "libGLESv2/renderer/d3d/TextureD3D.h" -#include "libGLESv2/renderer/d3d/TextureStorage.h" -#include "libGLESv2/renderer/d3d/ImageD3D.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/Texture.h" @@ -16,7 +13,11 @@ #include "libGLESv2/formatutils.h" #include "libGLESv2/renderer/BufferImpl.h" #include "libGLESv2/renderer/RenderTarget.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/BufferD3D.h" +#include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/d3d/TextureStorage.h" +#include "libGLESv2/renderer/d3d/ImageD3D.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libEGL/Surface.h" @@ -26,16 +27,51 @@ namespace rx { +namespace +{ + +gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const void *pixels, const uint8_t **pointerOut) +{ + if (unpack.pixelBuffer.id() != 0) + { + // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported + gl::Buffer *pixelBuffer = unpack.pixelBuffer.get(); + ptrdiff_t offset = reinterpret_cast(pixels); + + // TODO: this is the only place outside of renderer that asks for a buffers raw data. + // This functionality should be moved into renderer and the getData method of BufferImpl removed. + BufferD3D *bufferD3D = BufferD3D::makeBufferD3D(pixelBuffer->getImplementation()); + ASSERT(bufferD3D); + const uint8_t *bufferData = NULL; + gl::Error error = bufferD3D->getData(&bufferData); + if (error.isError()) + { + return error; + } + + *pointerOut = bufferData + offset; + } + else + { + *pointerOut = static_cast(pixels); + } + + return gl::Error(GL_NO_ERROR); +} + bool IsRenderTargetUsage(GLenum usage) { return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); } -TextureD3D::TextureD3D(Renderer *renderer) +} + +TextureD3D::TextureD3D(RendererD3D *renderer) : mRenderer(renderer), mUsage(GL_NONE), mDirtyImages(true), - mImmutable(false) + mImmutable(false), + mTexStorage(NULL) { } @@ -54,13 +90,12 @@ TextureStorage *TextureD3D::getNativeTexture() // ensure the underlying texture is created initializeStorage(false); - TextureStorage *storage = getBaseLevelStorage(); - if (storage) + if (mTexStorage) { updateStorage(); } - return storage; + return mTexStorage; } GLint TextureD3D::getBaseLevelWidth() const @@ -90,50 +125,79 @@ GLenum TextureD3D::getBaseLevelInternalFormat() const return (baseImage ? baseImage->getInternalFormat() : GL_NONE); } -void TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image) +bool TextureD3D::shouldUseSetData(const Image *image) const { + if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload) + { + return false; + } + + gl::InternalFormat internalFormat = gl::GetInternalFormatInfo(image->getInternalFormat()); + + // We can only handle full updates for depth-stencil textures, so to avoid complications + // disable them entirely. + if (internalFormat.depthBits > 0 || internalFormat.stencilBits > 0) + { + return false; + } + + // TODO(jmadill): Handle compressed internal formats + return (mTexStorage && !internalFormat.compressed); +} + +gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index) +{ + Image *image = getImage(index); + ASSERT(image); + // No-op if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0) { - return; + return gl::Error(GL_NO_ERROR); } // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains. // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components. - const void *pixelData = pixels; - - if (unpack.pixelBuffer.id() != 0) + const uint8_t *pixelData = NULL; + gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData); + if (error.isError()) { - // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported - gl::Buffer *pixelBuffer = unpack.pixelBuffer.get(); - ptrdiff_t offset = reinterpret_cast(pixels); - // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data. - // This functionality should be moved into renderer and the getData method of BufferImpl removed. - const void *bufferData = pixelBuffer->getImplementation()->getData(); - pixelData = static_cast(bufferData) + offset; + return error; } if (pixelData != NULL) { - image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData); + gl::Error error(GL_NO_ERROR); + + if (shouldUseSetData(image)) + { + error = mTexStorage->setData(index, image, NULL, type, unpack, pixelData); + } + else + { + error = image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData); + } + + if (error.isError()) + { + return error; + } + mDirtyImages = true; } + + return gl::Error(GL_NO_ERROR); } -bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index) +gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index) { - const void *pixelData = pixels; - // CPU readback & copy where direct GPU copy is not supported - if (unpack.pixelBuffer.id() != 0) + const uint8_t *pixelData = NULL; + gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData); + if (error.isError()) { - gl::Buffer *pixelBuffer = unpack.pixelBuffer.get(); - ptrdiff_t offset = reinterpret_cast(pixels); - // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data. - // This functionality should be moved into renderer and the getData method of BufferImpl removed. - const void *bufferData = pixelBuffer->getImplementation()->getData(); - pixelData = static_cast(bufferData) + offset; + return error; } if (pixelData != NULL) @@ -141,32 +205,78 @@ bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei w Image *image = getImage(index); ASSERT(image); - image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData); + gl::Box region(xoffset, yoffset, zoffset, width, height, depth); + if (shouldUseSetData(image)) + { + return mTexStorage->setData(index, image, ®ion, type, unpack, pixelData); + } + + gl::Error error = image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, + type, pixelData); + if (error.isError()) + { + return error; + } + + error = commitRegion(index, region); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } - return true; + return gl::Error(GL_NO_ERROR); } -void TextureD3D::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image) +gl::Error TextureD3D::setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image) { - if (pixels != NULL) + // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains. + // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components. + const uint8_t *pixelData = NULL; + gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData); + if (error.isError()) { - image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels); + return error; + } + + if (pixelData != NULL) + { + gl::Error error = image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixelData); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } + + return gl::Error(GL_NO_ERROR); } -bool TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, const void *pixels, Image *image) +gl::Error TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image) { - if (pixels != NULL) + const uint8_t *pixelData = NULL; + gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData); + if (error.isError()) { - image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels); + return error; + } + + if (pixelData != NULL) + { + gl::Error error = image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixelData); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } - return true; + return gl::Error(GL_NO_ERROR); } bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat) @@ -174,21 +284,28 @@ bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum siz return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat); } -bool TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea, - GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget) +gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea, + GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget) { + // No-op if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0) { - return true; + return gl::Error(GL_NO_ERROR); } // In order to perform the fast copy through the shader, we must have the right format, and be able // to create a render target. ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat)); - ptrdiff_t offset = reinterpret_cast(pixels); + uintptr_t offset = reinterpret_cast(pixels); - return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea); + gl::Error error = mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); } GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const @@ -210,10 +327,192 @@ int TextureD3D::mipLevels() const return gl::log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1; } +TextureStorage *TextureD3D::getStorage() +{ + ASSERT(mTexStorage); + return mTexStorage; +} -TextureD3D_2D::TextureD3D_2D(Renderer *renderer) - : TextureD3D(renderer), - mTexStorage(NULL) +Image *TextureD3D::getBaseLevelImage() const +{ + return getImage(getImageIndex(0, 0)); +} + +gl::Error TextureD3D::generateMipmaps() +{ + GLint mipCount = mipLevels(); + + if (mipCount == 1) + { + return gl::Error(GL_NO_ERROR); // no-op + } + + // Set up proper mipmap chain in our Image array. + initMipmapsImages(); + + // We know that all layers have the same dimension, for the texture to be complete + GLint layerCount = static_cast(getLayerCount(0)); + + // When making mipmaps with the setData workaround enabled, the texture storage has + // the image data already. For non-render-target storage, we have to pull it out into + // an image layer. + if (mRenderer->getWorkarounds().setDataFasterThanImageUpload && mTexStorage) + { + if (!mTexStorage->isRenderTarget()) + { + // Copy from the storage mip 0 to Image mip 0 + for (GLint layer = 0; layer < layerCount; ++layer) + { + gl::ImageIndex srcIndex = getImageIndex(0, layer); + + Image *image = getImage(srcIndex); + gl::Rectangle area(0, 0, image->getWidth(), image->getHeight()); + gl::Error error = image->copy(0, 0, 0, area, srcIndex, mTexStorage); + if (error.isError()) + { + return error; + } + } + } + else + { + gl::Error error = updateStorage(); + if (error.isError()) + { + return error; + } + } + } + + bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget()); + + for (GLint layer = 0; layer < layerCount; ++layer) + { + for (GLint mip = 1; mip < mipCount; ++mip) + { + ASSERT(getLayerCount(mip) == layerCount); + + gl::ImageIndex sourceIndex = getImageIndex(mip - 1, layer); + gl::ImageIndex destIndex = getImageIndex(mip, layer); + + if (renderableStorage) + { + // GPU-side mipmapping + gl::Error error = mTexStorage->generateMipmap(sourceIndex, destIndex); + if (error.isError()) + { + return error; + } + } + else + { + // CPU-side mipmapping + gl::Error error = mRenderer->generateMipmap(getImage(destIndex), getImage(sourceIndex)); + if (error.isError()) + { + return error; + } + } + } + } + + return gl::Error(GL_NO_ERROR); +} + +bool TextureD3D::isBaseImageZeroSize() const +{ + Image *baseImage = getBaseLevelImage(); + + if (!baseImage || baseImage->getWidth() <= 0) + { + return true; + } + + if (!gl::IsCubemapTextureTarget(baseImage->getTarget()) && baseImage->getHeight() <= 0) + { + return true; + } + + if (baseImage->getTarget() == GL_TEXTURE_3D && baseImage->getDepth() <= 0) + { + return true; + } + + if (baseImage->getTarget() == GL_TEXTURE_2D_ARRAY && getLayerCount(0) <= 0) + { + return true; + } + + return false; +} + +gl::Error TextureD3D::ensureRenderTarget() +{ + gl::Error error = initializeStorage(true); + if (error.isError()) + { + return error; + } + + if (!isBaseImageZeroSize()) + { + ASSERT(mTexStorage); + if (!mTexStorage->isRenderTarget()) + { + TextureStorage *newRenderTargetStorage = NULL; + error = createCompleteStorage(true, &newRenderTargetStorage); + if (error.isError()) + { + return error; + } + + error = mTexStorage->copyToStorage(newRenderTargetStorage); + if (error.isError()) + { + SafeDelete(newRenderTargetStorage); + return error; + } + + error = setCompleteTexStorage(newRenderTargetStorage); + if (error.isError()) + { + SafeDelete(newRenderTargetStorage); + return error; + } + } + } + + return gl::Error(GL_NO_ERROR); +} + +bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const +{ + Image *image = getImage(index); + bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0))); + return (image->isRenderableFormat() && levelsComplete); +} + +gl::Error TextureD3D::commitRegion(const gl::ImageIndex &index, const gl::Box ®ion) +{ + if (mTexStorage) + { + ASSERT(isValidIndex(index)); + Image *image = getImage(index); + ImageD3D *imageD3D = ImageD3D::makeImageD3D(image); + gl::Error error = imageD3D->copyToStorage(mTexStorage, index, region); + if (error.isError()) + { + return error; + } + + image->markClean(); + } + + return gl::Error(GL_NO_ERROR); +} + +TextureD3D_2D::TextureD3D_2D(RendererD3D *renderer) + : TextureD3D(renderer) { for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) { @@ -292,7 +591,9 @@ bool TextureD3D_2D::isDepth(GLint level) const return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, + GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + const void *pixels) { ASSERT(target == GL_TEXTURE_2D && depth == 1); @@ -302,142 +603,209 @@ void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei redefineImage(level, sizedInternalFormat, width, height); + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + // Attempt a fast gpu copy of the pixel data to the surface if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level)) { - gl::ImageIndex index = gl::ImageIndex::Make2D(level); - // Will try to create RT storage if it does not exist - RenderTarget *destRenderTarget = getRenderTarget(index); + RenderTarget *destRenderTarget = NULL; + gl::Error error = getRenderTarget(index, &destRenderTarget); + if (error.isError()) + { + return error; + } + gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1); - if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget)) + error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget); + if (error.isError()) { - // Ensure we don't overwrite our newly initialized data - mImageArray[level]->markClean(); - - fastUnpacked = true; + return error; } + + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; } if (!fastUnpacked) { - TextureD3D::setImage(unpack, type, pixels, mImageArray[level]); + gl::Error error = TextureD3D::setImage(unpack, type, pixels, index); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +gl::Error TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format, + GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_2D && depth == 1); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly redefineImage(level, format, width, height); - TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]); + return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]); } -void TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0); bool fastUnpacked = false; gl::ImageIndex index = gl::ImageIndex::Make2D(level); + gl::Box destArea(xoffset, yoffset, 0, width, height, 1); if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level)) { - RenderTarget *renderTarget = getRenderTarget(index); - gl::Box destArea(xoffset, yoffset, 0, width, height, 1); - - if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget)) + RenderTarget *renderTarget = NULL; + gl::Error error = getRenderTarget(index, &renderTarget); + if (error.isError()) { - // Ensure we don't overwrite our newly initialized data - mImageArray[level]->markClean(); - - fastUnpacked = true; + return error; } + + error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget); + if (error.isError()) + { + return error; + } + + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; } - if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index)) + if (!fastUnpacked) { - commitRect(level, xoffset, yoffset, width, height); + return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, + unpack, pixels, index); } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +gl::Error TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0); - if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level])) + gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[level]); + if (error.isError()) { - commitRect(level, xoffset, yoffset, width, height); + return error; } + + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + gl::Box region(xoffset, yoffset, 0, width, height, 1); + return commitRegion(index, region); } -void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, + gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_2D); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE); redefineImage(level, sizedInternalFormat, width, height); - if (!mImageArray[level]->isRenderableFormat()) + gl::Rectangle sourceRect(x, y, width, height); + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + + if (!canCreateRenderTargetForImage(index)) { - mImageArray[level]->copy(0, 0, 0, x, y, width, height, source); + gl::Error error = mImageArray[level]->copy(0, 0, 0, sourceRect, source); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } else { - ensureRenderTarget(); + gl::Error error = ensureRenderTarget(); + if (error.isError()) + { + return error; + } + mImageArray[level]->markClean(); if (width != 0 && height != 0 && isValidLevel(level)) { - gl::Rectangle sourceRect; - sourceRect.x = x; - sourceRect.width = width; - sourceRect.y = y; - sourceRect.height = height; - - mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level); + gl::Error error = mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_2D && zoffset == 0); // can only make our texture storage to a render target if level 0 is defined (with a width & height) and // the current level we're copying to is defined (with appropriate format, width & height) - bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0); - if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) + gl::Rectangle sourceRect(x, y, width, height); + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + + if (!canCreateRenderTargetForImage(index)) { - mImageArray[level]->copy(xoffset, yoffset, 0, x, y, width, height, source); + gl::Error error = mImageArray[level]->copy(xoffset, yoffset, 0, sourceRect, source); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } else { - ensureRenderTarget(); + gl::Error error = ensureRenderTarget(); + if (error.isError()) + { + return error; + } if (isValidLevel(level)) { - updateStorageLevel(level); + error = updateStorageLevel(level); + if (error.isError()) + { + return error; + } - gl::Rectangle sourceRect; - sourceRect.x = x; - sourceRect.width = width; - sourceRect.y = y; - sourceRect.height = height; - - mRenderer->copyImage2D(source, sourceRect, - gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, - xoffset, yoffset, mTexStorage, level); + error = mRenderer->copyImage2D(source, sourceRect, + gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, + xoffset, yoffset, mTexStorage, level); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +gl::Error TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { ASSERT(target == GL_TEXTURE_2D && depth == 1); @@ -453,11 +821,20 @@ void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true); } - mImmutable = true; - + // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); TextureStorage *storage = mRenderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels); - setCompleteTexStorage(storage); + + gl::Error error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + + mImmutable = true; + + return gl::Error(GL_NO_ERROR); } void TextureD3D_2D::bindTexImage(egl::Surface *surface) @@ -489,7 +866,7 @@ void TextureD3D_2D::releaseTexImage() } } -void TextureD3D_2D::generateMipmaps() +void TextureD3D_2D::initMipmapsImages() { // Purge array levels 1 through q and reset them to represent the generated mipmap levels. int levelCount = mipLevels(); @@ -499,42 +876,32 @@ void TextureD3D_2D::generateMipmaps() std::max(getBaseLevelWidth() >> level, 1), std::max(getBaseLevelHeight() >> level, 1)); } - - if (mTexStorage && mTexStorage->isRenderTarget()) - { - mTexStorage->generateMipmaps(); - for (int level = 1; level < levelCount; level++) - { - mImageArray[level]->markClean(); - } - } - else - { - for (int level = 1; level < levelCount; level++) - { - mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]); - } - } } unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index) { ASSERT(!index.hasLayer()); - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); + return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { ASSERT(!index.hasLayer()); // ensure the underlying texture is created - if (!ensureRenderTarget()) + gl::Error error = ensureRenderTarget(); + if (error.isError()) { - return NULL; + return error; } - updateStorageLevel(index.mipIndex); - return mTexStorage->getRenderTarget(index); + error = updateStorageLevel(index.mipIndex); + if (error.isError()) + { + return error; + } + + return mTexStorage->getRenderTarget(index, outRT); } bool TextureD3D_2D::isValidLevel(int level) const @@ -586,31 +953,55 @@ bool TextureD3D_2D::isLevelComplete(int level) const return true; } +bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const +{ + return isLevelComplete(index.mipIndex); +} + // Constructs a native texture resource from the texture images -void TextureD3D_2D::initializeStorage(bool renderTarget) +gl::Error TextureD3D_2D::initializeStorage(bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return; + return gl::Error(GL_NO_ERROR); } // do not attempt to create storage for nonexistant data if (!isLevelComplete(0)) { - return; + return gl::Error(GL_NO_ERROR); } bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); - setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + TextureStorage *storage = NULL; + gl::Error error = createCompleteStorage(createRenderTarget, &storage); + if (error.isError()) + { + return error; + } + + error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + ASSERT(mTexStorage); // flush image data to the storage - updateStorage(); + error = updateStorage(); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); } -TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const +gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const { GLsizei width = getBaseLevelWidth(); GLsizei height = getBaseLevelHeight(); @@ -621,26 +1012,35 @@ TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const // use existing storage level count, when previously specified by TexStorage*D GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); - return mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels); + // TODO(geofflang): Determine if the texture creation succeeded + *outTexStorage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels); + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { - SafeDelete(mTexStorage); - mTexStorage = newCompleteTexStorage; - - if (mTexStorage && mTexStorage->isManaged()) + if (newCompleteTexStorage && newCompleteTexStorage->isManaged()) { - for (int level = 0; level < mTexStorage->getLevelCount(); level++) + for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++) { - mImageArray[level]->setManagedSurface2D(mTexStorage, level); + gl::Error error = mImageArray[level]->setManagedSurface2D(newCompleteTexStorage, level); + if (error.isError()) + { + return error; + } } } + SafeDelete(mTexStorage); + mTexStorage = newCompleteTexStorage; + mDirtyImages = true; + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2D::updateStorage() +gl::Error TextureD3D_2D::updateStorage() { ASSERT(mTexStorage != NULL); GLint storageLevels = mTexStorage->getLevelCount(); @@ -648,54 +1048,34 @@ void TextureD3D_2D::updateStorage() { if (mImageArray[level]->isDirty() && isLevelComplete(level)) { - updateStorageLevel(level); - } - } -} - -bool TextureD3D_2D::ensureRenderTarget() -{ - initializeStorage(true); - - if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0) - { - ASSERT(mTexStorage); - if (!mTexStorage->isRenderTarget()) - { - TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - - if (!mRenderer->copyToRenderTarget2D(newRenderTargetStorage, mTexStorage)) + gl::Error error = updateStorageLevel(level); + if (error.isError()) { - delete newRenderTargetStorage; - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } - - setCompleteTexStorage(newRenderTargetStorage); } } - return (mTexStorage && mTexStorage->isRenderTarget()); + return gl::Error(GL_NO_ERROR); } -TextureStorage *TextureD3D_2D::getBaseLevelStorage() -{ - return mTexStorage; -} - -const ImageD3D *TextureD3D_2D::getBaseLevelImage() const -{ - return mImageArray[0]; -} - -void TextureD3D_2D::updateStorageLevel(int level) +gl::Error TextureD3D_2D::updateStorageLevel(int level) { ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL); ASSERT(isLevelComplete(level)); if (mImageArray[level]->isDirty()) { - commitRect(level, 0, 0, getWidth(level), getHeight(level)); + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); + gl::Error error = commitRegion(index, region); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height) @@ -727,22 +1107,25 @@ void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei wi } } -void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +gl::ImageIndexIterator TextureD3D_2D::imageIterator() const { - if (isValidLevel(level)) - { - ImageD3D *image = mImageArray[level]; - if (image->copyToStorage2D(mTexStorage, level, xoffset, yoffset, width, height)) - { - image->markClean(); - } - } + return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount()); } +gl::ImageIndex TextureD3D_2D::getImageIndex(GLint mip, GLint /*layer*/) const +{ + // "layer" does not apply to 2D Textures. + return gl::ImageIndex::Make2D(mip); +} -TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer) - : TextureD3D(renderer), - mTexStorage(NULL) +bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.type == GL_TEXTURE_2D && + index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount()); +} + +TextureD3D_Cube::TextureD3D_Cube(RendererD3D *renderer) + : TextureD3D(renderer) { for (int i = 0; i < 6; i++) { @@ -802,19 +1185,23 @@ bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0; } -void TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, + GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + const void *pixels) { ASSERT(depth == 1); - int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - redefineImage(faceIndex, level, sizedInternalFormat, width, height); + redefineImage(index.layerIndex, level, sizedInternalFormat, width, height); - TextureD3D::setImage(unpack, type, pixels, mImageArray[faceIndex][level]); + return TextureD3D::setImage(unpack, type, pixels, index); } -void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format, + GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(depth == 1); @@ -823,101 +1210,129 @@ void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum form redefineImage(faceIndex, level, format, width, height); - TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]); + return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[faceIndex][level]); } -void TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(depth == 1 && zoffset == 0); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index); +} - int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); +gl::Error TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) +{ + ASSERT(depth == 1 && zoffset == 0); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index)) + + gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[index.layerIndex][level]); + if (error.isError()) { - commitRect(faceIndex, level, xoffset, yoffset, width, height); + return error; } + + gl::Box region(xoffset, yoffset, 0, width, height, 1); + return commitRegion(index, region); } -void TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) -{ - ASSERT(depth == 1 && zoffset == 0); - - int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); - - if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level])) - { - commitRect(faceIndex, level, xoffset, yoffset, width, height); - } -} - -void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, + GLsizei width, GLsizei height, gl::Framebuffer *source) { int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE); redefineImage(faceIndex, level, sizedInternalFormat, width, height); - if (!mImageArray[faceIndex][level]->isRenderableFormat()) + gl::Rectangle sourceRect(x, y, width, height); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + + if (!canCreateRenderTargetForImage(index)) { - mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source); + gl::Error error = mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } else { - ensureRenderTarget(); + gl::Error error = ensureRenderTarget(); + if (error.isError()) + { + return error; + } + mImageArray[faceIndex][level]->markClean(); ASSERT(width == height); if (width > 0 && isValidFaceLevel(faceIndex, level)) { - gl::Rectangle sourceRect; - sourceRect.x = x; - sourceRect.width = width; - sourceRect.y = y; - sourceRect.height = height; - - mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level); + error = mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target); - // We can only make our texture storage to a render target if the level we're copying *to* is complete - // and the base level is cube-complete. The base level must be cube complete (common case) because we cannot - // rely on the "getBaseLevel*" methods reliably otherwise. - bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete(); + gl::Rectangle sourceRect(x, y, width, height); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) + if (!canCreateRenderTargetForImage(index)) { - mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source); + gl::Error error =mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } else { - ensureRenderTarget(); + gl::Error error = ensureRenderTarget(); + if (error.isError()) + { + return error; + } if (isValidFaceLevel(faceIndex, level)) { - updateStorageFaceLevel(faceIndex, level); + error = updateStorageFaceLevel(faceIndex, level); + if (error.isError()) + { + return error; + } - gl::Rectangle sourceRect; - sourceRect.x = x; - sourceRect.width = width; - sourceRect.y = y; - sourceRect.height = height; - - mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, - xoffset, yoffset, mTexStorage, target, level); + error = mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, + xoffset, yoffset, mTexStorage, target, level); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +gl::Error TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { ASSERT(width == height); ASSERT(depth == 1); @@ -939,11 +1354,20 @@ void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalform } } - mImmutable = true; - + // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); TextureStorage *storage = mRenderer->createTextureStorageCube(internalformat, renderTarget, width, levels); - setCompleteTexStorage(storage); + + gl::Error error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + + mImmutable = true; + + return gl::Error(GL_NO_ERROR); } // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. @@ -984,7 +1408,7 @@ void TextureD3D_Cube::releaseTexImage() } -void TextureD3D_Cube::generateMipmaps() +void TextureD3D_Cube::initMipmapsImages() { // Purge array levels 1 through q and reset them to represent the generated mipmap levels. int levelCount = mipLevels(); @@ -996,74 +1420,76 @@ void TextureD3D_Cube::generateMipmaps() redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize); } } - - if (mTexStorage && mTexStorage->isRenderTarget()) - { - mTexStorage->generateMipmaps(); - - for (int faceIndex = 0; faceIndex < 6; faceIndex++) - { - for (int level = 1; level < levelCount; level++) - { - mImageArray[faceIndex][level]->markClean(); - } - } - } - else - { - for (int faceIndex = 0; faceIndex < 6; faceIndex++) - { - for (int level = 1; level < levelCount; level++) - { - mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]); - } - } - } } unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index) { - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); + return (ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { ASSERT(gl::IsCubemapTextureTarget(index.type)); // ensure the underlying texture is created - if (!ensureRenderTarget()) + gl::Error error = ensureRenderTarget(); + if (error.isError()) { - return NULL; + return error; } - updateStorageFaceLevel(index.layerIndex, index.mipIndex); - return mTexStorage->getRenderTarget(index); + error = updateStorageFaceLevel(index.layerIndex, index.mipIndex); + if (error.isError()) + { + return error; + } + + return mTexStorage->getRenderTarget(index, outRT); } -void TextureD3D_Cube::initializeStorage(bool renderTarget) +gl::Error TextureD3D_Cube::initializeStorage(bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return; + return gl::Error(GL_NO_ERROR); } // do not attempt to create storage for nonexistant data if (!isFaceLevelComplete(0, 0)) { - return; + return gl::Error(GL_NO_ERROR); } bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); - setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + TextureStorage *storage = NULL; + gl::Error error = createCompleteStorage(createRenderTarget, &storage); + if (error.isError()) + { + return error; + } + + error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + ASSERT(mTexStorage); // flush image data to the storage - updateStorage(); + error = updateStorage(); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); } -TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const +gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const { GLsizei size = getBaseLevelWidth(); @@ -1072,29 +1498,37 @@ TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const // use existing storage level count, when previously specified by TexStorage*D GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1)); - return mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels); + // TODO (geofflang): detect if storage creation succeeded + *outTexStorage = mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels); + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { - SafeDelete(mTexStorage); - mTexStorage = newCompleteTexStorage; - - if (mTexStorage && mTexStorage->isManaged()) + if (newCompleteTexStorage && newCompleteTexStorage->isManaged()) { for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - for (int level = 0; level < mTexStorage->getLevelCount(); level++) + for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++) { - mImageArray[faceIndex][level]->setManagedSurfaceCube(mTexStorage, faceIndex, level); + gl::Error error = mImageArray[faceIndex][level]->setManagedSurfaceCube(newCompleteTexStorage, faceIndex, level); + if (error.isError()) + { + return error; + } } } } + SafeDelete(mTexStorage); + mTexStorage = newCompleteTexStorage; + mDirtyImages = true; + return gl::Error(GL_NO_ERROR); } -void TextureD3D_Cube::updateStorage() +gl::Error TextureD3D_Cube::updateStorage() { ASSERT(mTexStorage != NULL); GLint storageLevels = mTexStorage->getLevelCount(); @@ -1104,46 +1538,16 @@ void TextureD3D_Cube::updateStorage() { if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level)) { - updateStorageFaceLevel(face, level); + gl::Error error = updateStorageFaceLevel(face, level); + if (error.isError()) + { + return error; + } } } } -} -bool TextureD3D_Cube::ensureRenderTarget() -{ - initializeStorage(true); - - if (getBaseLevelWidth() > 0) - { - ASSERT(mTexStorage); - if (!mTexStorage->isRenderTarget()) - { - TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - - if (!mRenderer->copyToRenderTargetCube(newRenderTargetStorage, mTexStorage)) - { - delete newRenderTargetStorage; - return gl::error(GL_OUT_OF_MEMORY, false); - } - - setCompleteTexStorage(newRenderTargetStorage); - } - } - - return (mTexStorage && mTexStorage->isRenderTarget()); -} - -TextureStorage *TextureD3D_Cube::getBaseLevelStorage() -{ - return mTexStorage; -} - -const ImageD3D *TextureD3D_Cube::getBaseLevelImage() const -{ - // Note: if we are not cube-complete, there is no single base level image that can describe all - // cube faces, so this method is only well-defined for a cube-complete base level. - return mImageArray[0][0]; + return gl::Error(GL_NO_ERROR); } bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const @@ -1191,15 +1595,29 @@ bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const return true; } -void TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level) +bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const +{ + return isFaceLevelComplete(index.layerIndex, index.mipIndex); +} + +gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level) { ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); ImageD3D *image = mImageArray[faceIndex][level]; if (image->isDirty()) { - commitRect(faceIndex, level, 0, 0, image->getWidth(), image->getHeight()); + GLenum faceTarget = gl::TextureCubeMap::layerIndexToTarget(faceIndex); + gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level); + gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1); + gl::Error error = commitRegion(index, region); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height) @@ -1235,20 +1653,25 @@ void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalf } } -void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const { - if (isValidFaceLevel(faceIndex, level)) - { - ImageD3D *image = mImageArray[faceIndex][level]; - if (image->copyToStorageCube(mTexStorage, faceIndex, level, xoffset, yoffset, width, height)) - image->markClean(); - } + return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount()); } +gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const +{ + // The "layer" of the image index corresponds to the cube face + return gl::ImageIndex::MakeCube(gl::TextureCubeMap::layerIndexToTarget(layer), mip); +} -TextureD3D_3D::TextureD3D_3D(Renderer *renderer) - : TextureD3D(renderer), - mTexStorage(NULL) +bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && gl::IsCubemapTextureTarget(index.type) && + index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount()); +} + +TextureD3D_3D::TextureD3D_3D(RendererD3D *renderer) + : TextureD3D(renderer) { for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) { @@ -1327,7 +1750,9 @@ bool TextureD3D_3D::isDepth(GLint level) const return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, + GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + const void *pixels) { ASSERT(target == GL_TEXTURE_3D); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); @@ -1336,40 +1761,60 @@ void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei bool fastUnpacked = false; + gl::ImageIndex index = gl::ImageIndex::Make3D(level); + // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer if (isFastUnpackable(unpack, sizedInternalFormat)) { // Will try to create RT storage if it does not exist - gl::ImageIndex index = gl::ImageIndex::Make3D(level); - RenderTarget *destRenderTarget = getRenderTarget(index); + RenderTarget *destRenderTarget = NULL; + gl::Error error = getRenderTarget(index, &destRenderTarget); + if (error.isError()) + { + return error; + } + gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); - if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget)) + error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget); + if (error.isError()) { - // Ensure we don't overwrite our newly initialized data - mImageArray[level]->markClean(); - - fastUnpacked = true; + return error; } + + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; } if (!fastUnpacked) { - TextureD3D::setImage(unpack, type, pixels, mImageArray[level]); + gl::Error error = TextureD3D::setImage(unpack, type, pixels, index); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +gl::Error TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format, + GLsizei width, GLsizei height,GLsizei depth, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_3D); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly redefineImage(level, format, width, height, depth); - TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]); + return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]); } -void TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_3D); @@ -1380,74 +1825,108 @@ void TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yo // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer if (isFastUnpackable(unpack, getInternalFormat(level))) { - RenderTarget *destRenderTarget = getRenderTarget(index); - gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth); - - if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget)) + RenderTarget *destRenderTarget = NULL; + gl::Error error = getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - // Ensure we don't overwrite our newly initialized data - mImageArray[level]->markClean(); - - fastUnpacked = true; + return error; } + + gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth); + error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget); + if (error.isError()) + { + return error; + } + + // Ensure we don't overwrite our newly initialized data + mImageArray[level]->markClean(); + + fastUnpacked = true; } - if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, index)) + if (!fastUnpacked) { - commitRect(level, xoffset, yoffset, zoffset, width, height, depth); + return TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, + unpack, pixels, index); } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +gl::Error TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_3D); - if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level])) + gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, unpack, pixels, mImageArray[level]); + if (error.isError()) { - commitRect(level, xoffset, yoffset, zoffset, width, height, depth); + return error; } + + gl::ImageIndex index = gl::ImageIndex::Make3D(level); + gl::Box region(xoffset, yoffset, zoffset, width, height, depth); + return commitRegion(index, region); } -void TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, + GLsizei width, GLsizei height, gl::Framebuffer *source) { UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, "Copying 3D textures is unimplemented."); } -void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_3D); - // can only make our texture storage to a render target if level 0 is defined (with a width & height) and - // the current level we're copying to is defined (with appropriate format, width & height) - bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0); + gl::Rectangle sourceRect(x, y, width, height); + gl::ImageIndex index = gl::ImageIndex::Make3D(level); - if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) + if (canCreateRenderTargetForImage(index)) { - mImageArray[level]->copy(xoffset, yoffset, zoffset, x, y, width, height, source); + gl::Error error = mImageArray[level]->copy(xoffset, yoffset, zoffset, sourceRect, source); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } else { - ensureRenderTarget(); + gl::Error error = ensureRenderTarget(); + if (error.isError()) + { + return error; + } if (isValidLevel(level)) { - updateStorageLevel(level); + error = updateStorageLevel(level); + if (error.isError()) + { + return error; + } - gl::Rectangle sourceRect; - sourceRect.x = x; - sourceRect.width = width; - sourceRect.y = y; - sourceRect.height = height; - - mRenderer->copyImage3D(source, sourceRect, - gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, - xoffset, yoffset, zoffset, mTexStorage, level); + error = mRenderer->copyImage3D(source, sourceRect, + gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, + xoffset, yoffset, zoffset, mTexStorage, level); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +gl::Error TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { ASSERT(target == GL_TEXTURE_3D); @@ -1464,11 +1943,20 @@ void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true); } - mImmutable = true; - + // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); TextureStorage *storage = mRenderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels); - setCompleteTexStorage(storage); + + gl::Error error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + + mImmutable = true; + + return gl::Error(GL_NO_ERROR); } void TextureD3D_3D::bindTexImage(egl::Surface *surface) @@ -1482,7 +1970,7 @@ void TextureD3D_3D::releaseTexImage() } -void TextureD3D_3D::generateMipmaps() +void TextureD3D_3D::initMipmapsImages() { // Purge array levels 1 through q and reset them to represent the generated mipmap levels. int levelCount = mipLevels(); @@ -1493,74 +1981,85 @@ void TextureD3D_3D::generateMipmaps() std::max(getBaseLevelHeight() >> level, 1), std::max(getBaseLevelDepth() >> level, 1)); } - - if (mTexStorage && mTexStorage->isRenderTarget()) - { - mTexStorage->generateMipmaps(); - - for (int level = 1; level < levelCount; level++) - { - mImageArray[level]->markClean(); - } - } - else - { - for (int level = 1; level < levelCount; level++) - { - mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]); - } - } } unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index) { - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); + return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { // ensure the underlying texture is created - if (!ensureRenderTarget()) + gl::Error error = ensureRenderTarget(); + if (error.isError()) { - return NULL; + return error; } if (index.hasLayer()) { - updateStorage(); + error = updateStorage(); + if (error.isError()) + { + return error; + } } else { - updateStorageLevel(index.mipIndex); + error = updateStorageLevel(index.mipIndex); + if (error.isError()) + { + return error; + } } - return mTexStorage->getRenderTarget(index); + return mTexStorage->getRenderTarget(index, outRT); } -void TextureD3D_3D::initializeStorage(bool renderTarget) +gl::Error TextureD3D_3D::initializeStorage(bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return; + return gl::Error(GL_NO_ERROR); } // do not attempt to create storage for nonexistant data if (!isLevelComplete(0)) { - return; + return gl::Error(GL_NO_ERROR); } bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); - setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + TextureStorage *storage = NULL; + gl::Error error = createCompleteStorage(createRenderTarget, &storage); + if (error.isError()) + { + return error; + } + + error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + ASSERT(mTexStorage); // flush image data to the storage - updateStorage(); + error = updateStorage(); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); } -TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const +gl::Error TextureD3D_3D::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const { GLsizei width = getBaseLevelWidth(); GLsizei height = getBaseLevelHeight(); @@ -1572,10 +2071,13 @@ TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const // use existing storage level count, when previously specified by TexStorage*D GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth)); - return mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels); + // TODO: Verify creation of the storage succeeded + *outStorage = mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels); + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { SafeDelete(mTexStorage); mTexStorage = newCompleteTexStorage; @@ -1583,9 +2085,11 @@ void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) // We do not support managed 3D storage, as that is D3D9/ES2-only ASSERT(!mTexStorage->isManaged()); + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_3D::updateStorage() +gl::Error TextureD3D_3D::updateStorage() { ASSERT(mTexStorage != NULL); GLint storageLevels = mTexStorage->getLevelCount(); @@ -1593,43 +2097,15 @@ void TextureD3D_3D::updateStorage() { if (mImageArray[level]->isDirty() && isLevelComplete(level)) { - updateStorageLevel(level); - } - } -} - -bool TextureD3D_3D::ensureRenderTarget() -{ - initializeStorage(true); - - if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0) - { - ASSERT(mTexStorage); - if (!mTexStorage->isRenderTarget()) - { - TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - - if (!mRenderer->copyToRenderTarget3D(newRenderTargetStorage, mTexStorage)) + gl::Error error = updateStorageLevel(level); + if (error.isError()) { - delete newRenderTargetStorage; - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } - - setCompleteTexStorage(newRenderTargetStorage); } } - return (mTexStorage && mTexStorage->isRenderTarget()); -} - -TextureStorage *TextureD3D_3D::getBaseLevelStorage() -{ - return mTexStorage; -} - -const ImageD3D *TextureD3D_3D::getBaseLevelImage() const -{ - return mImageArray[0]; + return gl::Error(GL_NO_ERROR); } bool TextureD3D_3D::isValidLevel(int level) const @@ -1685,15 +2161,28 @@ bool TextureD3D_3D::isLevelComplete(int level) const return true; } -void TextureD3D_3D::updateStorageLevel(int level) +bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const +{ + return isLevelComplete(index.mipIndex); +} + +gl::Error TextureD3D_3D::updateStorageLevel(int level) { ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL); ASSERT(isLevelComplete(level)); if (mImageArray[level]->isDirty()) { - commitRect(level, 0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); + gl::ImageIndex index = gl::ImageIndex::Make3D(level); + gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); + gl::Error error = commitRegion(index, region); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) @@ -1727,22 +2216,26 @@ void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei wi } } -void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +gl::ImageIndexIterator TextureD3D_3D::imageIterator() const { - if (isValidLevel(level)) - { - ImageD3D *image = mImageArray[level]; - if (image->copyToStorage3D(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth)) - { - image->markClean(); - } - } + return gl::ImageIndexIterator::Make3D(0, mTexStorage->getLevelCount(), + gl::ImageIndex::ENTIRE_LEVEL, gl::ImageIndex::ENTIRE_LEVEL); } +gl::ImageIndex TextureD3D_3D::getImageIndex(GLint mip, GLint /*layer*/) const +{ + // The "layer" here does not apply to 3D images. We use one Image per mip. + return gl::ImageIndex::Make3D(mip); +} -TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer) - : TextureD3D(renderer), - mTexStorage(NULL) +bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.type == GL_TEXTURE_3D && + index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount()); +} + +TextureD3D_2DArray::TextureD3D_2DArray(RendererD3D *renderer) + : TextureD3D(renderer) { for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) { @@ -1791,11 +2284,6 @@ GLsizei TextureD3D_2DArray::getHeight(GLint level) const return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getHeight() : 0; } -GLsizei TextureD3D_2DArray::getLayers(GLint level) const -{ - return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mLayerCounts[level] : 0; -} - GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const { return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getInternalFormat() : GL_NONE; @@ -1806,7 +2294,9 @@ bool TextureD3D_2DArray::isDepth(GLint level) const return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, + GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, + const void *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); @@ -1820,11 +2310,20 @@ void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLs for (int i = 0; i < depth; i++) { const void *layerPixels = pixels ? (reinterpret_cast(pixels) + (inputDepthPitch * i)) : NULL; - TextureD3D::setImage(unpack, type, layerPixels, mImageArray[level][i]); + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i); + gl::Error error = TextureD3D::setImage(unpack, type, layerPixels, index); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) +gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format, + GLsizei width, GLsizei height, GLsizei depth, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); @@ -1837,11 +2336,19 @@ void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum f for (int i = 0; i < depth; i++) { const void *layerPixels = pixels ? (reinterpret_cast(pixels) + (inputDepthPitch * i)) : NULL; - TextureD3D::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]); + gl::Error error = TextureD3D::setCompressedImage(unpack, imageSize, layerPixels, mImageArray[level][i]); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) +gl::Error TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); @@ -1854,14 +2361,20 @@ void TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLi const void *layerPixels = pixels ? (reinterpret_cast(pixels) + (inputDepthPitch * i)) : NULL; gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); - if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, index)) + gl::Error error = TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, + unpack, layerPixels, index); + if (error.isError()) { - commitRect(level, xoffset, yoffset, layer, width, height); + return error; } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); @@ -1873,52 +2386,75 @@ void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xo int layer = zoffset + i; const void *layerPixels = pixels ? (reinterpret_cast(pixels) + (inputDepthPitch * i)) : NULL; - if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer])) + gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, unpack, layerPixels, mImageArray[level][layer]); + if (error.isError()) { - commitRect(level, xoffset, yoffset, layer, width, height); + return error; + } + + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); + gl::Box region(xoffset, yoffset, 0, width, height, 1); + error = commitRegion(index, region); + if (error.isError()) + { + return error; } } + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, "Copying 2D array textures is unimplemented."); } -void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_2D_ARRAY); - // can only make our texture storage to a render target if level 0 is defined (with a width & height) and - // the current level we're copying to is defined (with appropriate format, width & height) - bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0); + gl::Rectangle sourceRect(x, y, width, height); + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zoffset); - if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget)) + if (canCreateRenderTargetForImage(index)) { - mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, x, y, width, height, source); + gl::Error error = mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, sourceRect, source); + if (error.isError()) + { + return error; + } + mDirtyImages = true; } else { - ensureRenderTarget(); + gl::Error error = ensureRenderTarget(); + if (error.isError()) + { + return error; + } if (isValidLevel(level)) { - updateStorageLevel(level); + error = updateStorageLevel(level); + if (error.isError()) + { + return error; + } - gl::Rectangle sourceRect; - sourceRect.x = x; - sourceRect.width = width; - sourceRect.y = y; - sourceRect.height = height; - - mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format, - xoffset, yoffset, zoffset, mTexStorage, level); + error = mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format, + xoffset, yoffset, zoffset, mTexStorage, level); + if (error.isError()) + { + return error; + } } } + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +gl::Error TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { ASSERT(target == GL_TEXTURE_2D_ARRAY); @@ -1945,11 +2481,20 @@ void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalf } } - mImmutable = true; - + // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels); - setCompleteTexStorage(storage); + + gl::Error error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + + mImmutable = true; + + return gl::Error(GL_NO_ERROR); } void TextureD3D_2DArray::bindTexImage(egl::Surface *surface) @@ -1963,7 +2508,7 @@ void TextureD3D_2DArray::releaseTexImage() } -void TextureD3D_2DArray::generateMipmaps() +void TextureD3D_2DArray::initMipmapsImages() { int baseWidth = getBaseLevelWidth(); int baseHeight = getBaseLevelHeight(); @@ -1976,76 +2521,78 @@ void TextureD3D_2DArray::generateMipmaps() { redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth); } - - if (mTexStorage && mTexStorage->isRenderTarget()) - { - mTexStorage->generateMipmaps(); - - for (int level = 1; level < levelCount; level++) - { - for (int layer = 0; layer < mLayerCounts[level]; layer++) - { - mImageArray[level][layer]->markClean(); - } - } - } - else - { - for (int level = 1; level < levelCount; level++) - { - for (int layer = 0; layer < mLayerCounts[level]; layer++) - { - mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]); - } - } - } } unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index) { - return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0); + return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); } -RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { // ensure the underlying texture is created - if (!ensureRenderTarget()) + gl::Error error = ensureRenderTarget(); + if (error.isError()) { - return NULL; + return error; } - updateStorageLevel(index.mipIndex); - return mTexStorage->getRenderTarget(index); + error = updateStorageLevel(index.mipIndex); + if (error.isError()) + { + return error; + } + + return mTexStorage->getRenderTarget(index, outRT); } -void TextureD3D_2DArray::initializeStorage(bool renderTarget) +gl::Error TextureD3D_2DArray::initializeStorage(bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return; + return gl::Error(GL_NO_ERROR); } // do not attempt to create storage for nonexistant data if (!isLevelComplete(0)) { - return; + return gl::Error(GL_NO_ERROR); } bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); - setCompleteTexStorage(createCompleteStorage(createRenderTarget)); + TextureStorage *storage = NULL; + gl::Error error = createCompleteStorage(createRenderTarget, &storage); + if (error.isError()) + { + return error; + } + + error = setCompleteTexStorage(storage); + if (error.isError()) + { + SafeDelete(storage); + return error; + } + ASSERT(mTexStorage); // flush image data to the storage - updateStorage(); + error = updateStorage(); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); } -TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const +gl::Error TextureD3D_2DArray::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const { GLsizei width = getBaseLevelWidth(); GLsizei height = getBaseLevelHeight(); - GLsizei depth = getLayers(0); + GLsizei depth = getLayerCount(0); GLenum internalFormat = getBaseLevelInternalFormat(); ASSERT(width > 0 && height > 0 && depth > 0); @@ -2053,10 +2600,13 @@ TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) con // use existing storage level count, when previously specified by TexStorage*D GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); - return mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels); + // TODO(geofflang): Verify storage creation succeeds + *outStorage = mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels); + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) { SafeDelete(mTexStorage); mTexStorage = newCompleteTexStorage; @@ -2064,9 +2614,11 @@ void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexSto // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only ASSERT(!mTexStorage->isManaged()); + + return gl::Error(GL_NO_ERROR); } -void TextureD3D_2DArray::updateStorage() +gl::Error TextureD3D_2DArray::updateStorage() { ASSERT(mTexStorage != NULL); GLint storageLevels = mTexStorage->getLevelCount(); @@ -2074,43 +2626,15 @@ void TextureD3D_2DArray::updateStorage() { if (isLevelComplete(level)) { - updateStorageLevel(level); - } - } -} - -bool TextureD3D_2DArray::ensureRenderTarget() -{ - initializeStorage(true); - - if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getLayers(0) > 0) - { - ASSERT(mTexStorage); - if (!mTexStorage->isRenderTarget()) - { - TextureStorage *newRenderTargetStorage = createCompleteStorage(true); - - if (!mRenderer->copyToRenderTarget2DArray(newRenderTargetStorage, mTexStorage)) + gl::Error error = updateStorageLevel(level); + if (error.isError()) { - delete newRenderTargetStorage; - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } - - setCompleteTexStorage(newRenderTargetStorage); } } - return (mTexStorage && mTexStorage->isRenderTarget()); -} - -const ImageD3D *TextureD3D_2DArray::getBaseLevelImage() const -{ - return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL); -} - -TextureStorage *TextureD3D_2DArray::getBaseLevelStorage() -{ - return mTexStorage; + return gl::Error(GL_NO_ERROR); } bool TextureD3D_2DArray::isValidLevel(int level) const @@ -2129,7 +2653,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const GLsizei width = getBaseLevelWidth(); GLsizei height = getBaseLevelHeight(); - GLsizei layers = getLayers(0); + GLsizei layers = getLayerCount(0); if (width <= 0 || height <= 0 || layers <= 0) { @@ -2156,7 +2680,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const return false; } - if (getLayers(level) != layers) + if (getLayerCount(level) != layers) { return false; } @@ -2164,7 +2688,12 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const return true; } -void TextureD3D_2DArray::updateStorageLevel(int level) +bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const +{ + return isLevelComplete(index.mipIndex); +} + +gl::Error TextureD3D_2DArray::updateStorageLevel(int level) { ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts)); ASSERT(isLevelComplete(level)); @@ -2174,9 +2703,17 @@ void TextureD3D_2DArray::updateStorageLevel(int level) ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL); if (mImageArray[level][layer]->isDirty()) { - commitRect(level, 0, 0, layer, getWidth(level), getHeight(level)); + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); + gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); + gl::Error error = commitRegion(index, region); + if (error.isError()) + { + return error; + } } } + + return gl::Error(GL_NO_ERROR); } void TextureD3D_2DArray::deleteImages() @@ -2198,7 +2735,7 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz // If there currently is a corresponding storage texture image, it has these parameters const int storageWidth = std::max(1, getBaseLevelWidth() >> level); const int storageHeight = std::max(1, getBaseLevelHeight() >> level); - const int storageDepth = getLayers(0); + const int storageDepth = getLayerCount(0); const GLenum storageFormat = getBaseLevelInternalFormat(); for (int layer = 0; layer < mLayerCounts[level]; layer++) @@ -2245,16 +2782,32 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz } } -void TextureD3D_2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height) +gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const { - if (isValidLevel(level) && layerTarget < getLayers(level)) + return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts); +} + +gl::ImageIndex TextureD3D_2DArray::getImageIndex(GLint mip, GLint layer) const +{ + return gl::ImageIndex::Make2DArray(mip, layer); +} + +bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const +{ + // Check for having a storage and the right type of index + if (!mTexStorage || index.type != GL_TEXTURE_2D_ARRAY) { - ImageD3D *image = mImageArray[level][layerTarget]; - if (image->copyToStorage2DArray(mTexStorage, level, xoffset, yoffset, layerTarget, width, height)) - { - image->markClean(); - } + return false; } + + // Check the mip index + if (index.mipIndex < 0 || index.mipIndex >= mTexStorage->getLevelCount()) + { + return false; + } + + // Check the layer index + return (!index.hasLayer() || (index.layerIndex >= 0 && index.layerIndex < mLayerCounts[index.mipIndex])); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h index 41c73180de..083a6335b9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h @@ -11,7 +11,7 @@ #include "libGLESv2/renderer/TextureImpl.h" #include "libGLESv2/angletypes.h" -#include "libGLESv2/constants.h" +#include "libGLESv2/Constants.h" namespace gl { @@ -23,19 +23,19 @@ namespace rx class Image; class ImageD3D; -class Renderer; +class RendererD3D; class RenderTarget; class TextureStorage; class TextureD3D : public TextureImpl { public: - TextureD3D(Renderer *renderer); + TextureD3D(RendererD3D *renderer); virtual ~TextureD3D(); static TextureD3D *makeTextureD3D(TextureImpl *texture); - virtual TextureStorage *getNativeTexture(); + TextureStorage *getNativeTexture(); virtual void setUsage(GLenum usage) { mUsage = usage; } bool hasDirtyImages() const { return mDirtyImages; } @@ -48,45 +48,68 @@ class TextureD3D : public TextureImpl bool isImmutable() const { return mImmutable; } - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0; virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0; + // Returns an iterator over all "Images" for this particular Texture. + virtual gl::ImageIndexIterator imageIterator() const = 0; + + // Returns an ImageIndex for a particular "Image". 3D Textures do not have images for + // slices of their depth texures, so 3D textures ignore the layer parameter. + virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0; + virtual bool isValidIndex(const gl::ImageIndex &index) const = 0; + + virtual gl::Error generateMipmaps(); + TextureStorage *getStorage(); + Image *getBaseLevelImage() const; + protected: - void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image); - bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index); - void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image); - bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, const void *pixels, Image *image); + gl::Error setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index); + gl::Error subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index); + gl::Error setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image); + gl::Error subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image); bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat); - bool fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea, - GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget); + gl::Error fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea, + GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget); GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const; int mipLevels() const; + virtual void initMipmapsImages() = 0; + bool isBaseImageZeroSize() const; + virtual bool isImageComplete(const gl::ImageIndex &index) const = 0; - Renderer *mRenderer; + bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const; + virtual gl::Error ensureRenderTarget(); + + virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const = 0; + virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage) = 0; + gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box ®ion); + + RendererD3D *mRenderer; GLenum mUsage; bool mDirtyImages; bool mImmutable; + TextureStorage *mTexStorage; private: DISALLOW_COPY_AND_ASSIGN(TextureD3D); - virtual void initializeStorage(bool renderTarget) = 0; + virtual gl::Error initializeStorage(bool renderTarget) = 0; - virtual void updateStorage() = 0; - virtual TextureStorage *getBaseLevelStorage() = 0; - virtual const ImageD3D *getBaseLevelImage() const = 0; + virtual gl::Error updateStorage() = 0; + + bool shouldUseSetData(const Image *image) const; }; class TextureD3D_2D : public TextureD3D { public: - TextureD3D_2D(Renderer *renderer); + TextureD3D_2D(RendererD3D *renderer); virtual ~TextureD3D_2D(); virtual Image *getImage(int level, int layer) const; @@ -99,50 +122,49 @@ class TextureD3D_2D : public TextureD3D GLenum getActualFormat(GLint level) const; bool isDepth(GLint level) const; - virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); - virtual void generateMipmaps(); - - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); + virtual gl::ImageIndexIterator imageIterator() const; + virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; + virtual bool isValidIndex(const gl::ImageIndex &index) const; + private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D); - virtual void initializeStorage(bool renderTarget); - TextureStorage *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + virtual gl::Error initializeStorage(bool renderTarget); + virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const; + virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - virtual void updateStorage(); - bool ensureRenderTarget(); - virtual TextureStorage *getBaseLevelStorage(); - virtual const ImageD3D *getBaseLevelImage() const; + virtual gl::Error updateStorage(); + virtual void initMipmapsImages(); bool isValidLevel(int level) const; bool isLevelComplete(int level) const; + virtual bool isImageComplete(const gl::ImageIndex &index) const; - void updateStorageLevel(int level); + gl::Error updateStorageLevel(int level); void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height); - void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - TextureStorage *mTexStorage; ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureD3D_Cube : public TextureD3D { public: - TextureD3D_Cube(Renderer *renderer); + TextureD3D_Cube(RendererD3D *renderer); virtual ~TextureD3D_Cube(); virtual Image *getImage(int level, int layer) const; @@ -156,51 +178,49 @@ class TextureD3D_Cube : public TextureD3D GLenum getInternalFormat(GLint level, GLint layer) const; bool isDepth(GLint level, GLint layer) const; - virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); - virtual void generateMipmaps(); - - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); + virtual gl::ImageIndexIterator imageIterator() const; + virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; + virtual bool isValidIndex(const gl::ImageIndex &index) const; + private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube); - virtual void initializeStorage(bool renderTarget); - TextureStorage *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + virtual gl::Error initializeStorage(bool renderTarget); + virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const; + virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - virtual void updateStorage(); - bool ensureRenderTarget(); - virtual TextureStorage *getBaseLevelStorage(); - virtual const ImageD3D *getBaseLevelImage() const; + virtual gl::Error updateStorage(); + virtual void initMipmapsImages(); bool isValidFaceLevel(int faceIndex, int level) const; bool isFaceLevelComplete(int faceIndex, int level) const; bool isCubeComplete() const; - void updateStorageFaceLevel(int faceIndex, int level); + virtual bool isImageComplete(const gl::ImageIndex &index) const; + gl::Error updateStorageFaceLevel(int faceIndex, int level); void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height); - void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - - TextureStorage *mTexStorage; }; class TextureD3D_3D : public TextureD3D { public: - TextureD3D_3D(Renderer *renderer); + TextureD3D_3D(RendererD3D *renderer); virtual ~TextureD3D_3D(); virtual Image *getImage(int level, int layer) const; @@ -213,50 +233,48 @@ class TextureD3D_3D : public TextureD3D GLenum getInternalFormat(GLint level) const; bool isDepth(GLint level) const; - virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); - virtual void generateMipmaps(); - - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); + virtual gl::ImageIndexIterator imageIterator() const; + virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; + virtual bool isValidIndex(const gl::ImageIndex &index) const; + private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D); - virtual void initializeStorage(bool renderTarget); - TextureStorage *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + virtual gl::Error initializeStorage(bool renderTarget); + virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const; + virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - virtual void updateStorage(); - bool ensureRenderTarget(); - virtual TextureStorage *getBaseLevelStorage(); - virtual const ImageD3D *getBaseLevelImage() const; + virtual gl::Error updateStorage(); + virtual void initMipmapsImages(); bool isValidLevel(int level) const; bool isLevelComplete(int level) const; - void updateStorageLevel(int level); + virtual bool isImageComplete(const gl::ImageIndex &index) const; + gl::Error updateStorageLevel(int level); void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - - TextureStorage *mTexStorage; }; class TextureD3D_2DArray : public TextureD3D { public: - TextureD3D_2DArray(Renderer *renderer); + TextureD3D_2DArray(RendererD3D *renderer); virtual ~TextureD3D_2DArray(); virtual Image *getImage(int level, int layer) const; @@ -265,45 +283,44 @@ class TextureD3D_2DArray : public TextureD3D GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; - GLsizei getLayers(GLint level) const; GLenum getInternalFormat(GLint level) const; bool isDepth(GLint level) const; - virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); - virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); - virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); - virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels); + virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); - virtual void generateMipmaps(); - - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); + virtual gl::ImageIndexIterator imageIterator() const; + virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; + virtual bool isValidIndex(const gl::ImageIndex &index) const; + private: DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray); - virtual void initializeStorage(bool renderTarget); - TextureStorage *createCompleteStorage(bool renderTarget) const; - void setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + virtual gl::Error initializeStorage(bool renderTarget); + virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const; + virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); - virtual void updateStorage(); - bool ensureRenderTarget(); - virtual TextureStorage *getBaseLevelStorage(); - virtual const ImageD3D *getBaseLevelImage() const; + virtual gl::Error updateStorage(); + virtual void initMipmapsImages(); bool isValidLevel(int level) const; bool isLevelComplete(int level) const; - void updateStorageLevel(int level); + virtual bool isImageComplete(const gl::ImageIndex &index) const; + gl::Error updateStorageLevel(int level); void deleteImages(); void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height); // Storing images as an array of single depth textures since D3D11 treats each array level of a // Texture2D object as a separate subresource. Each layer would have to be looped over @@ -311,8 +328,6 @@ class TextureD3D_2DArray : public TextureD3D // sense for the Image class to not have to worry about layer subresource as well as mip subresources. GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - - TextureStorage *mTexStorage; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp index dedd266c09..320b74b8ed 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp @@ -8,6 +8,7 @@ #include "libGLESv2/renderer/d3d/TextureStorage.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" +#include "libGLESv2/renderer/RenderTarget.h" #include "libGLESv2/renderer/Renderer.h" #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Texture.h" @@ -18,17 +19,14 @@ namespace rx { -unsigned int TextureStorage::mCurrentTextureSerial = 1; - TextureStorage::TextureStorage() - : mTextureSerial(issueTextureSerial()), - mFirstRenderTargetSerial(0), + : mFirstRenderTargetSerial(0), mRenderTargetSerialsLayerStride(0) {} void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride) { - mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(rtSerialsToReserve); + mFirstRenderTargetSerial = RenderTarget::issueSerials(rtSerialsToReserve); mRenderTargetSerialsLayerStride = rtSerialsLayerStride; } @@ -38,14 +36,4 @@ unsigned int TextureStorage::getRenderTargetSerial(const gl::ImageIndex &index) return mFirstRenderTargetSerial + static_cast(index.mipIndex) + layerOffset; } -unsigned int TextureStorage::getTextureSerial() const -{ - return mTextureSerial; -} - -unsigned int TextureStorage::issueTextureSerial() -{ - return mCurrentTextureSerial++; -} - } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h index 9cc2c2977b..da92be3c74 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h @@ -9,20 +9,26 @@ #ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_ #define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_ +#include "libGLESv2/Error.h" + #include "common/debug.h" +#include "libGLESv2/Error.h" #include +#include namespace gl { struct ImageIndex; +struct Box; +struct PixelUnpackState; } namespace rx { -class Renderer; class SwapChain; class RenderTarget; +class Image; class TextureStorage { @@ -35,8 +41,12 @@ class TextureStorage virtual bool isManaged() const = 0; virtual int getLevelCount() const = 0; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; - virtual void generateMipmaps() = 0; + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0; + virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0; + + virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0; + virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type, + const gl::PixelUnpackState &unpack, const uint8_t *pixelData) = 0; unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const; unsigned int getTextureSerial() const; @@ -47,11 +57,6 @@ class TextureStorage private: DISALLOW_COPY_AND_ASSIGN(TextureStorage); - const unsigned int mTextureSerial; - static unsigned int issueTextureSerial(); - - static unsigned int mCurrentTextureSerial; - unsigned int mFirstRenderTargetSerial; unsigned int mRenderTargetSerialsLayerStride; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp index 4f85eb94fa..73f0c79e19 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp @@ -9,7 +9,7 @@ #include "libGLESv2/renderer/d3d/VertexBuffer.h" #include "libGLESv2/renderer/d3d/BufferD3D.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/VertexAttribute.h" #include "common/mathutil.h" @@ -38,7 +38,7 @@ unsigned int VertexBuffer::getSerial() const return mSerial; } -VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer) +VertexBufferInterface::VertexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer) { mDynamic = dynamic; mWritePosition = 0; @@ -127,7 +127,7 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute mWritePosition += spaceRequired; // Align to 16-byte boundary - mWritePosition = rx::roundUp(mWritePosition, 16u); + mWritePosition = roundUp(mWritePosition, 16u); return gl::Error(GL_NO_ERROR); } @@ -153,7 +153,7 @@ gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &a mReservedSpace += requiredSpace; // Align to 16-byte boundary - mReservedSpace = rx::roundUp(mReservedSpace, 16u); + mReservedSpace = roundUp(mReservedSpace, 16u); return gl::Error(GL_NO_ERROR); } @@ -197,7 +197,7 @@ bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &att return !requiresConversion && isAligned; } -StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true) +StreamingVertexBufferInterface::StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true) { setBufferSize(initialSize); } @@ -231,7 +231,7 @@ gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size) return gl::Error(GL_NO_ERROR); } -StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false) +StaticVertexBufferInterface::StaticVertexBufferInterface(RendererD3D *renderer) : VertexBufferInterface(renderer, false) { } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h index fa747d9cb4..4b40818f8e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h @@ -26,7 +26,7 @@ struct VertexAttribCurrentValueData; namespace rx { -class Renderer; +class RendererD3D; class VertexBuffer { @@ -60,7 +60,7 @@ class VertexBuffer class VertexBufferInterface { public: - VertexBufferInterface(rx::Renderer *renderer, bool dynamic); + VertexBufferInterface(RendererD3D *renderer, bool dynamic); virtual ~VertexBufferInterface(); gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); @@ -90,7 +90,7 @@ class VertexBufferInterface private: DISALLOW_COPY_AND_ASSIGN(VertexBufferInterface); - rx::Renderer *const mRenderer; + RendererD3D *const mRenderer; VertexBuffer* mVertexBuffer; @@ -102,7 +102,7 @@ class VertexBufferInterface class StreamingVertexBufferInterface : public VertexBufferInterface { public: - StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize); + StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize); ~StreamingVertexBufferInterface(); protected: @@ -112,7 +112,7 @@ class StreamingVertexBufferInterface : public VertexBufferInterface class StaticVertexBufferInterface : public VertexBufferInterface { public: - explicit StaticVertexBufferInterface(rx::Renderer *renderer); + explicit StaticVertexBufferInterface(RendererD3D *renderer); ~StaticVertexBufferInterface(); gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp index 7034b78eab..8d3df31c8b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp @@ -14,6 +14,7 @@ #include "libGLESv2/Buffer.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" +#include "libGLESv2/State.h" namespace { @@ -51,7 +52,7 @@ static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int ve return vertexDrawCount; } -VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer) +VertexDataManager::VertexDataManager(RendererD3D *renderer) : mRenderer(renderer) { for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { @@ -82,8 +83,8 @@ VertexDataManager::~VertexDataManager() } } -gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[], - gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) +gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count, + TranslatedAttribute *translated, GLsizei instances) { if (!mStreamingBuffer) { @@ -93,20 +94,22 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs // Invalidate static buffers that don't contain matching attributes for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) { - translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1); + translated[attributeIndex].active = (state.getCurrentProgramBinary()->getSemanticIndex(attributeIndex) != -1); + const gl::VertexAttribute &curAttrib = state.getVertexAttribState(attributeIndex); - if (translated[attributeIndex].active && attribs[attributeIndex].enabled) + if (translated[attributeIndex].active && curAttrib.enabled) { - invalidateMatchingStaticData(attribs[attributeIndex], currentValues[attributeIndex]); + invalidateMatchingStaticData(curAttrib, state.getVertexAttribCurrentValue(attributeIndex)); } } // Reserve the required space in the buffers for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { - if (translated[i].active && attribs[i].enabled) + const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i); + if (translated[i].active && curAttrib.enabled) { - gl::Error error = reserveSpaceForAttrib(attribs[i], currentValues[i], count, instances); + gl::Error error = reserveSpaceForAttrib(curAttrib, state.getVertexAttribCurrentValue(i), count, instances); if (error.isError()) { return error; @@ -117,12 +120,14 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs // Perform the vertex data translations for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { + const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i); if (translated[i].active) { - if (attribs[i].enabled) + if (curAttrib.enabled) { - gl::Error error = storeAttribute(attribs[i], currentValues[i], &translated[i], - start, count, instances); + gl::Error error = storeAttribute(curAttrib, state.getVertexAttribCurrentValue(i), + &translated[i], start, count, instances); + if (error.isError()) { return error; @@ -135,7 +140,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE); } - gl::Error error = storeCurrentValue(attribs[i], currentValues[i], &translated[i], + gl::Error error = storeCurrentValue(curAttrib, state.getVertexAttribCurrentValue(i), &translated[i], &mCurrentValue[i], &mCurrentValueOffsets[i], mCurrentValueBuffer[i]); if (error.isError()) @@ -148,14 +153,15 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { - if (translated[i].active && attribs[i].enabled) + const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i); + if (translated[i].active && curAttrib.enabled) { - gl::Buffer *buffer = attribs[i].buffer.get(); + gl::Buffer *buffer = curAttrib.buffer.get(); if (buffer) { BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation()); - bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(attribs[i])); + bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(curAttrib)); } } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h index 7728722246..64ef653221 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h @@ -16,8 +16,9 @@ namespace gl { -struct VertexAttribute; class ProgramBinary; +class State; +struct VertexAttribute; struct VertexAttribCurrentValueData; } @@ -26,7 +27,7 @@ namespace rx class BufferD3D; class StreamingVertexBufferInterface; class VertexBuffer; -class Renderer; +class RendererD3D; struct TranslatedAttribute { @@ -49,11 +50,11 @@ struct TranslatedAttribute class VertexDataManager { public: - VertexDataManager(rx::Renderer *renderer); + VertexDataManager(RendererD3D *renderer); virtual ~VertexDataManager(); - gl::Error prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[], - gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances); + gl::Error prepareVertexData(const gl::State &state, GLint start, GLsizei count, + TranslatedAttribute *outAttribs, GLsizei instances); private: DISALLOW_COPY_AND_ASSIGN(VertexDataManager); @@ -80,7 +81,7 @@ class VertexDataManager size_t *cachedOffset, StreamingVertexBufferInterface *buffer); - rx::Renderer *const mRenderer; + RendererD3D *const mRenderer; StreamingVertexBufferInterface *mStreamingBuffer; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp index d43e65ea78..06aea9befe 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp @@ -172,7 +172,7 @@ static void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &source *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; } -Blit11::Blit11(rx::Renderer11 *renderer) +Blit11::Blit11(Renderer11 *renderer) : mRenderer(renderer), mBlitShaderMap(compareBlitParameters), mSwizzleShaderMap(compareSwizzleParameters), mVertexBuffer(NULL), mPointSampler(NULL), mLinearSampler(NULL), mScissorEnabledRasterizerState(NULL), mScissorDisabledRasterizerState(NULL), mDepthStencilState(NULL), @@ -209,7 +209,7 @@ Blit11::Blit11(rx::Renderer11 *renderer) pointSamplerDesc.BorderColor[2] = 0.0f; pointSamplerDesc.BorderColor[3] = 0.0f; pointSamplerDesc.MinLOD = 0.0f; - pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f; + pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f; result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler); ASSERT(SUCCEEDED(result)); @@ -228,7 +228,7 @@ Blit11::Blit11(rx::Renderer11 *renderer) linearSamplerDesc.BorderColor[2] = 0.0f; linearSamplerDesc.BorderColor[3] = 0.0f; linearSamplerDesc.MinLOD = 0.0f; - linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f; + linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f; result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler); ASSERT(SUCCEEDED(result)); @@ -468,8 +468,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); // Unset the currently bound shader resource to avoid conflicts - ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); // Apply render target mRenderer->setOneTimeRenderTarget(dest); @@ -485,7 +484,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &source); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers deviceContext->PSSetSamplers(0, 1, &mPointSampler); @@ -494,7 +493,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); @@ -507,9 +506,9 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT return gl::Error(GL_NO_ERROR); } -bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, GLenum destFormat, GLenum filter) +gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, GLenum destFormat, GLenum filter) { HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -531,7 +530,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source if (i == mBlitShaderMap.end()) { UNREACHABLE(); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Could not find appropriate shader for internal texture blit."); } const Shader& shader = i->second; @@ -541,8 +540,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); } UINT stride = 0; @@ -587,8 +585,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0); // Unset the currently bound shader resource to avoid conflicts - ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); // Apply render target mRenderer->setOneTimeRenderTarget(dest); @@ -604,7 +601,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &source); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers ID3D11SamplerState *sampler = NULL; @@ -612,7 +609,10 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source { case GL_NEAREST: sampler = mPointSampler; break; case GL_LINEAR: sampler = mLinearSampler; break; - default: UNREACHABLE(); return false; + + default: + UNREACHABLE(); + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, unknown blit filter mode."); } deviceContext->PSSetSamplers(0, 1, &sampler); @@ -620,7 +620,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); @@ -630,21 +630,21 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } -bool Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor) +gl::Error Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) { return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource, destArea, destSize, scissor, true); } -bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor) +gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) { HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -654,8 +654,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); } UINT stride = 0; @@ -700,8 +699,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr deviceContext->GSSetShader(NULL, NULL, 0); // Unset the currently bound shader resource to avoid conflicts - ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); // Apply render target deviceContext->OMSetRenderTargets(0, NULL, dest); @@ -717,7 +715,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &source); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers deviceContext->PSSetSamplers(0, 1, &mPointSampler); @@ -726,7 +724,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); @@ -736,21 +734,21 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } -bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor) +gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor) { return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource, destArea, destSize, scissor, false); } -bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, bool stencilOnly) +gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, bool stencilOnly) { ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -764,7 +762,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso { SafeRelease(sourceStaging); SafeRelease(destStaging); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging textures for depth stencil blit."); } DXGI_FORMAT format = GetTextureFormat(source); @@ -785,23 +783,23 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso dxgiFormatInfo.depthBits % 8 == 0); } - D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping; - deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping); - deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping); - - if (!sourceMapping.pData || !destMapping.pData) + D3D11_MAPPED_SUBRESOURCE sourceMapping; + HRESULT result = deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping); + if (FAILED(result)) { - if (!sourceMapping.pData) - { - deviceContext->Unmap(sourceStaging, 0); - } - if (!destMapping.pData) - { - deviceContext->Unmap(destStaging, 0); - } SafeRelease(sourceStaging); SafeRelease(destStaging); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal source staging texture for depth stencil blit, HRESULT: 0x%X.", result); + } + + D3D11_MAPPED_SUBRESOURCE destMapping; + result = deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping); + if (FAILED(result)) + { + deviceContext->Unmap(sourceStaging, 0); + SafeRelease(sourceStaging); + SafeRelease(destStaging); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal destination staging texture for depth stencil blit, HRESULT: 0x%X.", result); } gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height); @@ -880,7 +878,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso SafeRelease(sourceStaging); SafeRelease(destStaging); - return true; + return gl::Error(GL_NO_ERROR); } bool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b) @@ -1001,12 +999,12 @@ void Blit11::buildShaderMap() add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" )); add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" )); add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" )); - add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" )); add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" )); add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" )); - add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" )); + add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" )); add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" )); add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" )); + add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" )); add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" )); add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" )); add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" )); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h index d6a0b795f4..821fa9d0cc 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h @@ -19,12 +19,6 @@ namespace rx { class Renderer11; -enum Filter -{ - Point, - Linear, -}; - class Blit11 { public: @@ -34,24 +28,24 @@ class Blit11 gl::Error swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); - bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, GLenum destFormat, GLenum filter); + gl::Error copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, GLenum destFormat, GLenum filter); - bool copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor); - - bool copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor); - - bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, const gl::Rectangle *scissor); + gl::Error copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor); + + gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor); + private: - rx::Renderer11 *mRenderer; + Renderer11 *mRenderer; struct BlitParameters { @@ -60,9 +54,9 @@ class Blit11 bool m3DBlit; }; - bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, bool stencilOnly); + gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, bool stencilOnly); static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp index ecd4d4672b..5aab37938f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp @@ -86,7 +86,7 @@ class Buffer11::BufferStorage11 virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset, size_t size, size_t destOffset) = 0; - virtual bool resize(size_t size, bool preserveData) = 0; + virtual gl::Error resize(size_t size, bool preserveData) = 0; virtual void *map(size_t offset, size_t length, GLbitfield access) = 0; virtual void unmap() = 0; @@ -112,17 +112,17 @@ class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11 virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset, size_t size, size_t destOffset); - virtual bool resize(size_t size, bool preserveData); + virtual gl::Error resize(size_t size, bool preserveData); virtual void *map(size_t offset, size_t length, GLbitfield access); virtual void unmap(); - bool setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset); + gl::Error setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset); private: ID3D11Buffer *mNativeBuffer; - static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize); + static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize); }; // Pack storage represents internal storage for pack buffers. We implement pack buffers @@ -135,7 +135,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset, size_t size, size_t destOffset); - virtual bool resize(size_t size, bool preserveData); + virtual gl::Error resize(size_t size, bool preserveData); virtual void *map(size_t offset, size_t length, GLbitfield access); virtual void unmap(); @@ -144,7 +144,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11 private: - void flushQueuedPackCommand(); + gl::Error flushQueuedPackCommand(); ID3D11Texture2D *mStagingTexture; DXGI_FORMAT mTextureFormat; @@ -195,14 +195,14 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) return error; } -void *Buffer11::getData() +gl::Error Buffer11::getData(const uint8_t **outData) { NativeBuffer11 *stagingBuffer = getStagingBuffer(); if (!stagingBuffer) { // Out-of-memory - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get internal staging buffer."); } if (stagingBuffer->getDataRevision() > mResolvedDataRevision) @@ -211,7 +211,7 @@ void *Buffer11::getData() { if (!mResolvedData.resize(stagingBuffer->getSize())) { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer."); } } @@ -221,7 +221,7 @@ void *Buffer11::getData() HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource); if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result); } memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize()); @@ -238,13 +238,14 @@ void *Buffer11::getData() { if (!mResolvedData.resize(mSize)) { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer."); } } ASSERT(mResolvedData.size() >= mSize); - return mResolvedData.data(); + *outData = mResolvedData.data(); + return gl::Error(GL_NO_ERROR); } gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) @@ -265,15 +266,17 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) if (stagingBuffer->getSize() < requiredSize) { bool preserveData = (offset > 0); - if (!stagingBuffer->resize(requiredSize, preserveData)) + gl::Error error = stagingBuffer->resize(requiredSize, preserveData); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer."); + return error; } } - if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast(data), size, offset)) + gl::Error error = stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast(data), size, offset); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer."); + return error; } stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1); @@ -411,7 +414,7 @@ void Buffer11::markBufferUsage() } } -Renderer* Buffer11::getRenderer() +RendererD3D* Buffer11::getRenderer() { return mRenderer; } @@ -527,7 +530,7 @@ Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage) // resize buffer if (directBuffer->getSize() < mSize) { - if (!directBuffer->resize(mSize, true)) + if (directBuffer->resize(mSize, true).isError()) { // Out of memory error return NULL; @@ -667,6 +670,9 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s // Offset bounds are validated at the API layer ASSERT(sourceOffset + size <= destOffset + mBufferSize); memcpy(destPointer, sourcePointer, size); + + context->Unmap(mNativeBuffer, 0); + source->unmap(); } else { @@ -689,7 +695,7 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s return createBuffer; } -bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) +gl::Error Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) { ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -702,7 +708,7 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", result); } if (mNativeBuffer && preserveData) @@ -727,10 +733,10 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData) mBufferSize = bufferDesc.ByteWidth; - return true; + return gl::Error(GL_NO_ERROR); } -void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, +void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize) { bufferDesc->ByteWidth = bufferSize; @@ -748,7 +754,7 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: bufferDesc->Usage = D3D11_USAGE_DEFAULT; bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER; - if (!static_cast(renderer)->isLevel9()) + if (!renderer->isLevel9()) bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT; bufferDesc->CPUAccessFlags = 0; break; @@ -797,7 +803,7 @@ void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield acc return static_cast(mappedResource.pData) + offset; } -bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset) +gl::Error Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); @@ -805,7 +811,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource); if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result); } uint8_t *offsetBufferPointer = reinterpret_cast(mappedResource.pData) + offset; @@ -813,7 +819,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s context->Unmap(mNativeBuffer, 0); - return true; + return gl::Error(GL_NO_ERROR); } void Buffer11::NativeBuffer11::unmap() @@ -847,18 +853,18 @@ bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t so return false; } -bool Buffer11::PackStorage11::resize(size_t size, bool preserveData) +gl::Error Buffer11::PackStorage11::resize(size_t size, bool preserveData) { if (size != mBufferSize) { if (!mMemoryBuffer.resize(size)) { - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer storage."); } mBufferSize = size; } - return true; + return gl::Error(GL_NO_ERROR); } void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield access) @@ -869,7 +875,12 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce // and if D3D packs the staging texture memory identically to how we would fill // the pack buffer according to the current pack state. - flushQueuedPackCommand(); + gl::Error error = flushQueuedPackCommand(); + if (error.isError()) + { + return NULL; + } + mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); return mMemoryBuffer.data() + offset; @@ -882,7 +893,12 @@ void Buffer11::PackStorage11::unmap() gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) { - flushQueuedPackCommand(); + gl::Error error = flushQueuedPackCommand(); + if (error.isError()) + { + return error; + } + mQueuedPackCommand = new PackPixelsParams(params); D3D11_TEXTURE2D_DESC textureDesc; @@ -947,15 +963,21 @@ gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT s return gl::Error(GL_NO_ERROR); } -void Buffer11::PackStorage11::flushQueuedPackCommand() +gl::Error Buffer11::PackStorage11::flushQueuedPackCommand() { ASSERT(mMemoryBuffer.size() > 0); if (mQueuedPackCommand) { - mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data()); + gl::Error error = mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data()); SafeDelete(mQueuedPackCommand); + if (error.isError()) + { + return error; + } } + + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h index 5f24fb4e2d..1c06bbf88a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h @@ -47,7 +47,7 @@ typedef size_t DataRevision; class Buffer11 : public BufferD3D { public: - Buffer11(rx::Renderer11 *renderer); + Buffer11(Renderer11 *renderer); virtual ~Buffer11(); static Buffer11 *makeBuffer11(BufferImpl *buffer); @@ -60,11 +60,11 @@ class Buffer11 : public BufferD3D // BufferD3D implementation virtual size_t getSize() const { return mSize; } virtual bool supportsDirectBinding() const; - virtual Renderer* getRenderer(); + RendererD3D *getRenderer() override; // BufferImpl implementation virtual gl::Error setData(const void* data, size_t size, GLenum usage); - virtual void *getData(); + gl::Error getData(const uint8_t **outData) override; virtual gl::Error setSubData(const void* data, size_t size, size_t offset); virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); @@ -78,7 +78,7 @@ class Buffer11 : public BufferD3D class NativeBuffer11; class PackStorage11; - rx::Renderer11 *mRenderer; + Renderer11 *mRenderer; size_t mSize; BufferStorage11 *mMappedStorage; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp index 765d34fd3f..7185a05506 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp @@ -104,7 +104,7 @@ Clear11::Clear11(Renderer11 *renderer) rsDesc.DepthBias = 0; rsDesc.DepthBiasClamp = 0.0f; rsDesc.SlopeScaledDepthBias = 0.0f; - rsDesc.DepthClipEnable = mRenderer->isLevel9(); + rsDesc.DepthClipEnable = renderer->isLevel9(); rsDesc.ScissorEnable = FALSE; rsDesc.MultisampleEnable = FALSE; rsDesc.AntialiasedLineEnable = FALSE; @@ -119,7 +119,6 @@ Clear11::Clear11(Renderer11 *renderer) memset(&mIntClearShader, 0, sizeof(ClearShader)); return; } - mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint ); mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint ); } @@ -154,7 +153,7 @@ Clear11::~Clear11() SafeRelease(mRasterizerState); } -gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) { // First determine if a scissored clear is needed, this will always require drawing a quad. // @@ -217,10 +216,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl:: gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment); if (attachment) { - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); - if (!renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); + return error; } const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); @@ -290,10 +290,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl:: gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer(); if (attachment) { - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment); - if (!renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); + return error; } const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat()); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h index be8e187c40..a7e8fea56a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h @@ -32,7 +32,7 @@ class Clear11 ~Clear11(); // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied. - gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer); private: Renderer11 *mRenderer; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp index a841b52862..f44d934056 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp @@ -4,67 +4,229 @@ // found in the LICENSE file. // -// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. +// Fence11.cpp: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl. #include "libGLESv2/renderer/d3d/d3d11/Fence11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/main.h" +#include "common/utilities.h" + namespace rx { -Fence11::Fence11(rx::Renderer11 *renderer) -{ - mRenderer = renderer; - mQuery = NULL; -} +// +// Template helpers for set and test operations. +// -Fence11::~Fence11() +template +gl::Error FenceSetHelper(FenceClass *fence) { - SafeRelease(mQuery); -} - -bool Fence11::isSet() const -{ - return mQuery != NULL; -} - -void Fence11::set() -{ - if (!mQuery) + if (!fence->mQuery) { D3D11_QUERY_DESC queryDesc; queryDesc.Query = D3D11_QUERY_EVENT; queryDesc.MiscFlags = 0; - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result); } } - mRenderer->getDeviceContext()->End(mQuery); + fence->mRenderer->getDeviceContext()->End(fence->mQuery); + return gl::Error(GL_NO_ERROR); } -bool Fence11::test(bool flushCommandBuffer) +template +gl::Error FenceTestHelper(FenceClass *fence, bool flushCommandBuffer, GLboolean *outFinished) { - ASSERT(mQuery); + ASSERT(fence->mQuery); UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, getDataFlags); + HRESULT result = fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, NULL, 0, getDataFlags); - if (mRenderer->isDeviceLost()) + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, true); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result); + } + else if (fence->mRenderer->isDeviceLost()) + { + return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query."); } ASSERT(result == S_OK || result == S_FALSE); - return (result == S_OK); + *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); + return gl::Error(GL_NO_ERROR); } -bool Fence11::hasError() const +// +// FenceNV11 +// + +FenceNV11::FenceNV11(Renderer11 *renderer) + : FenceNVImpl(), + mRenderer(renderer), + mQuery(NULL) { - return mRenderer->isDeviceLost(); } +FenceNV11::~FenceNV11() +{ + SafeRelease(mQuery); } + +gl::Error FenceNV11::set() +{ + return FenceSetHelper(this); +} + +gl::Error FenceNV11::test(bool flushCommandBuffer, GLboolean *outFinished) +{ + return FenceTestHelper(this, flushCommandBuffer, outFinished); +} + +gl::Error FenceNV11::finishFence(GLboolean *outFinished) +{ + ASSERT(outFinished); + + while (*outFinished != GL_TRUE) + { + gl::Error error = test(true, outFinished); + if (error.isError()) + { + return error; + } + + Sleep(0); + } + + return gl::Error(GL_NO_ERROR); +} + +// +// FenceSync11 +// + +// Important note on accurate timers in Windows: +// +// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call +// as timeGetTime on laptops and "jumping" during certain hardware events. +// +// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc" +// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc +// +// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer +// from buggy implementations. + +FenceSync11::FenceSync11(Renderer11 *renderer) + : FenceSyncImpl(), + mRenderer(renderer), + mQuery(NULL) +{ + LARGE_INTEGER counterFreqency = { 0 }; + BOOL success = QueryPerformanceFrequency(&counterFreqency); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + + mCounterFrequency = counterFreqency.QuadPart; +} + +FenceSync11::~FenceSync11() +{ + SafeRelease(mQuery); +} + +gl::Error FenceSync11::set() +{ + return FenceSetHelper(this); +} + +gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) +{ + ASSERT(outResult); + + bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); + + GLboolean result = GL_FALSE; + gl::Error error = FenceTestHelper(this, flushCommandBuffer, &result); + if (error.isError()) + { + *outResult = GL_WAIT_FAILED; + return error; + } + + if (result == GL_TRUE) + { + *outResult = GL_ALREADY_SIGNALED; + return gl::Error(GL_NO_ERROR); + } + + if (timeout == 0) + { + *outResult = GL_TIMEOUT_EXPIRED; + return gl::Error(GL_NO_ERROR); + } + + LARGE_INTEGER currentCounter = { 0 }; + BOOL success = QueryPerformanceCounter(¤tCounter); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + + LONGLONG timeoutInSeconds = static_cast(timeout) * static_cast(1000000ll); + LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; + + while (currentCounter.QuadPart < endCounter && !result) + { + Sleep(0); + BOOL success = QueryPerformanceCounter(¤tCounter); + UNUSED_ASSERTION_VARIABLE(success); + ASSERT(success); + + error = FenceTestHelper(this, flushCommandBuffer, &result); + if (error.isError()) + { + *outResult = GL_WAIT_FAILED; + return error; + } + } + + if (currentCounter.QuadPart >= endCounter) + { + *outResult = GL_TIMEOUT_EXPIRED; + } + else + { + *outResult = GL_CONDITION_SATISFIED; + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error FenceSync11::serverWait(GLbitfield flags, GLuint64 timeout) +{ + // Because our API is currently designed to be called from a single thread, we don't need to do + // extra work for a server-side fence. GPU commands issued after the fence is created will always + // be processed after the fence is signaled. + return gl::Error(GL_NO_ERROR); +} + +gl::Error FenceSync11::getStatus(GLint *outResult) +{ + GLboolean result = GL_FALSE; + gl::Error error = FenceTestHelper(this, false, &result); + if (error.isError()) + { + // The spec does not specify any way to report errors during the status test (e.g. device lost) + // so we report the fence is unblocked in case of error or signaled. + *outResult = GL_SIGNALED; + + return error; + } + + *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED); + return gl::Error(GL_NO_ERROR); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h index 50c7621776..1223a53b90 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h @@ -4,10 +4,10 @@ // found in the LICENSE file. // -// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl. +// Fence11.h: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl. -#ifndef LIBGLESV2_RENDERER_Fence11_H_ -#define LIBGLESV2_RENDERER_Fence11_H_ +#ifndef LIBGLESV2_RENDERER_FENCE11_H_ +#define LIBGLESV2_RENDERER_FENCE11_H_ #include "libGLESv2/renderer/FenceImpl.h" @@ -15,24 +15,48 @@ namespace rx { class Renderer11; -class Fence11 : public FenceImpl +class FenceNV11 : public FenceNVImpl { public: - explicit Fence11(rx::Renderer11 *renderer); - virtual ~Fence11(); + explicit FenceNV11(Renderer11 *renderer); + virtual ~FenceNV11(); - bool isSet() const; - void set(); - bool test(bool flushCommandBuffer); - bool hasError() const; + gl::Error set(); + gl::Error test(bool flushCommandBuffer, GLboolean *outFinished); + gl::Error finishFence(GLboolean *outFinished); private: - DISALLOW_COPY_AND_ASSIGN(Fence11); + DISALLOW_COPY_AND_ASSIGN(FenceNV11); - rx::Renderer11 *mRenderer; + template friend gl::Error FenceSetHelper(T *fence); + template friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished); + + Renderer11 *mRenderer; ID3D11Query *mQuery; }; +class FenceSync11 : public FenceSyncImpl +{ + public: + explicit FenceSync11(Renderer11 *renderer); + virtual ~FenceSync11(); + + gl::Error set(); + gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult); + gl::Error serverWait(GLbitfield flags, GLuint64 timeout); + gl::Error getStatus(GLint *outResult); + + private: + DISALLOW_COPY_AND_ASSIGN(FenceSync11); + + template friend gl::Error FenceSetHelper(T *fence); + template friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished); + + Renderer11 *mRenderer; + ID3D11Query *mQuery; + LONGLONG mCounterFrequency; +}; + } #endif // LIBGLESV2_RENDERER_FENCE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp index 7536713af4..e6f3e90683 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp @@ -9,6 +9,7 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" @@ -22,15 +23,16 @@ namespace rx { Image11::Image11() + : mRenderer(NULL), + mDXGIFormat(DXGI_FORMAT_UNKNOWN), + mStagingTexture(NULL), + mStagingSubresource(0), + mRecoverFromStorage(false), + mAssociatedStorage(NULL), + mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()), + mRecoveredFromStorageCount(0) + { - mStagingTexture = NULL; - mRenderer = NULL; - mDXGIFormat = DXGI_FORMAT_UNKNOWN; - mRecoverFromStorage = false; - mAssociatedStorage = NULL; - mAssociatedStorageLevel = 0; - mAssociatedStorageLayerTarget = 0; - mRecoveredFromStorageCount = 0; } Image11::~Image11() @@ -41,11 +43,11 @@ Image11::~Image11() Image11 *Image11::makeImage11(Image *img) { - ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img)); - return static_cast(img); + ASSERT(HAS_DYNAMIC_TYPE(Image11*, img)); + return static_cast(img); } -void Image11::generateMipmap(Image11 *dest, Image11 *src) +gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src) { ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); @@ -55,21 +57,18 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL); D3D11_MAPPED_SUBRESOURCE destMapped; - HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped); - if (FAILED(destMapResult)) + gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped); + if (error.isError()) { - ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult); - return; + return error; } D3D11_MAPPED_SUBRESOURCE srcMapped; - HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped); - if (FAILED(srcMapResult)) + error = src->map(D3D11_MAP_READ, &srcMapped); + if (error.isError()) { - ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult); - dest->unmap(); - return; + return error; } const uint8_t *sourceData = reinterpret_cast(srcMapped.pData); @@ -83,6 +82,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src) src->unmap(); dest->markDirty(); + + return gl::Error(GL_NO_ERROR); } bool Image11::isDirty() const @@ -99,32 +100,10 @@ bool Image11::isDirty() const return mDirty; } -bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) { - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); - return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); -} + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(storage); -bool Image11::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); - return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height); -} - -bool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) -{ - TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); - return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height); -} - -bool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height) -{ - TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); - return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height); -} - -bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times, // then we should just keep the staging texture around to prevent the copying from impacting perf. // We allow the Image11 to copy its data to/from TextureStorage once. @@ -134,23 +113,38 @@ bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int laye if (attemptToReleaseStagingTexture) { // If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it. - storage11->releaseAssociatedImage(level, layerTarget, this); + gl::Error error = storage11->releaseAssociatedImage(index, this); + if (error.isError()) + { + return error; + } } - bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1); + ID3D11Resource *stagingTexture = NULL; + unsigned int stagingSubresourceIndex = 0; + gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); + if (error.isError()) + { + return error; + } + + error = storage11->updateSubresourceLevel(stagingTexture, stagingSubresourceIndex, index, region); + if (error.isError()) + { + return error; + } // Once the image data has been copied into the Storage, we can release it locally. - if (attemptToReleaseStagingTexture && updateSubresourceSuccess) + if (attemptToReleaseStagingTexture) { - storage11->associateImage(this, level, layerTarget); + storage11->associateImage(this, index); releaseStagingTexture(); mRecoverFromStorage = true; mAssociatedStorage = storage11; - mAssociatedStorageLevel = level; - mAssociatedStorageLayerTarget = layerTarget; + mAssociatedImageIndex = index; } - return updateSubresourceSuccess; + return gl::Error(GL_NO_ERROR); } bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const @@ -158,13 +152,17 @@ bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const return (mAssociatedStorage == textureStorage); } -bool Image11::recoverFromAssociatedStorage() +gl::Error Image11::recoverFromAssociatedStorage() { if (mRecoverFromStorage) { - createStagingTexture(); + gl::Error error = createStagingTexture(); + if (error.isError()) + { + return error; + } - bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, this); // This means that the cached TextureStorage has been modified after this Image11 released its copy of its data. // This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten. @@ -173,17 +171,21 @@ bool Image11::recoverFromAssociatedStorage() if (textureStorageCorrect) { // CopySubResource from the Storage to the Staging texture - mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth); + gl::Box region(0, 0, 0, mWidth, mHeight, mDepth); + error = mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region); + if (error.isError()) + { + return error; + } + mRecoveredFromStorageCount += 1; } // Reset all the recovery parameters, even if the texture storage association is broken. disassociateStorage(); - - return textureStorageCorrect; } - return false; + return gl::Error(GL_NO_ERROR); } void Image11::disassociateStorage() @@ -191,16 +193,15 @@ void Image11::disassociateStorage() if (mRecoverFromStorage) { // Make the texturestorage release the Image11 too - mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this); + mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this); mRecoverFromStorage = false; mAssociatedStorage = NULL; - mAssociatedStorageLevel = 0; - mAssociatedStorageLayerTarget = 0; + mAssociatedImageIndex = gl::ImageIndex::MakeInvalid(); } } -bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) +bool Image11::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) { if (mWidth != width || mHeight != height || @@ -227,7 +228,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, mActualFormat = dxgiFormatInfo.internalFormat; mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); - SafeRelease(mStagingTexture); + releaseStagingTexture(); mDirty = (formatInfo.dataInitializerFunction != NULL); return true; @@ -247,8 +248,8 @@ DXGI_FORMAT Image11::getDXGIFormat() const // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // into the target pixel rectangle. -void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input) +gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) { const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment); @@ -261,11 +262,10 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type); D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) + gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); + if (error.isError()) { - ERR("Could not map image for loading."); - return; + return error; } uint8_t* offsetMappedData = (reinterpret_cast(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch)); @@ -274,10 +274,12 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); unmap(); + + return gl::Error(GL_NO_ERROR); } -void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input) +gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input) { const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1); @@ -295,11 +297,10 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE); D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) + gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); + if (error.isError()) { - ERR("Could not map image for loading."); - return; + return error; } uint8_t* offsetMappedData = reinterpret_cast(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch + @@ -311,81 +312,130 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); unmap(); + + return gl::Error(GL_NO_ERROR); } -void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) { - gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer(); + RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source); + ASSERT(sourceRenderTarget->getTexture()); - if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat) + UINT subresourceIndex = sourceRenderTarget->getSubresourceIndex(); + ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject(sourceRenderTarget->getTexture()); + + if (!sourceTexture2D) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source RenderTarget."); + } + + gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); + + SafeRelease(sourceTexture2D); + + return error; +} + +gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source) +{ + TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source); + + UINT subresourceIndex = sourceStorage11->getSubresourceIndex(sourceIndex); + ID3D11Resource *resource = NULL; + gl::Error error = sourceStorage11->getResource(&resource); + if (error.isError()) + { + return error; + } + + ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject(resource); + + if (!sourceTexture2D) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source TextureStorage."); + } + + error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex); + + SafeRelease(sourceTexture2D); + + return error; +} + +gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource) +{ + D3D11_TEXTURE2D_DESC textureDesc; + source->GetDesc(&textureDesc); + + if (textureDesc.Format == mDXGIFormat) { // No conversion needed-- use copyback fastpath - ID3D11Texture2D *colorBufferTexture = NULL; - unsigned int subresourceIndex = 0; - - if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) + ID3D11Resource *stagingTexture = NULL; + unsigned int stagingSubresourceIndex = 0; + gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); + if (error.isError()) { - D3D11_TEXTURE2D_DESC textureDesc; - colorBufferTexture->GetDesc(&textureDesc); + return error; + } - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - ID3D11Texture2D* srcTex = NULL; - if (textureDesc.SampleDesc.Count > 1) + UINT subresourceAfterResolve = sourceSubResource; + + ID3D11Texture2D* srcTex = NULL; + if (textureDesc.SampleDesc.Count > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = textureDesc.Width; + resolveDesc.Height = textureDesc.Height; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureDesc.Format; + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); + if (FAILED(result)) { - D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; - resolveDesc.SampleDesc.Count = 1; - resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = D3D11_USAGE_DEFAULT; - resolveDesc.BindFlags = 0; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); - if (FAILED(result)) - { - ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); - return; - } - - deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); - subresourceIndex = 0; - } - else - { - srcTex = colorBufferTexture; - srcTex->AddRef(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); } - D3D11_BOX srcBox; - srcBox.left = x; - srcBox.right = x + width; - srcBox.top = y; - srcBox.bottom = y + height; - srcBox.front = 0; - srcBox.back = 1; + deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format); + subresourceAfterResolve = 0; + } + else + { + srcTex = source; + } - deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox); + D3D11_BOX srcBox; + srcBox.left = sourceArea.x; + srcBox.right = sourceArea.x + sourceArea.width; + srcBox.top = sourceArea.y; + srcBox.bottom = sourceArea.y + sourceArea.height; + srcBox.front = 0; + srcBox.back = 1; + deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox); + + if (textureDesc.SampleDesc.Count > 1) + { SafeRelease(srcTex); - SafeRelease(colorBufferTexture); } } else { // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) + gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); + if (error.isError()) { - ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result); - return; + return error; } // determine the offset coordinate into the destination buffer @@ -394,17 +444,32 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); unmap(); + + if (error.isError()) + { + return error; + } } + + mDirty = true; + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *Image11::getStagingTexture() +gl::Error Image11::getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex) { - createStagingTexture(); + gl::Error error = createStagingTexture(); + if (error.isError()) + { + return error; + } - return mStagingTexture; + *outStagingTexture = mStagingTexture; + *outSubresourceIndex = mStagingSubresource; + return gl::Error(GL_NO_ERROR); } void Image11::releaseStagingTexture() @@ -412,149 +477,149 @@ void Image11::releaseStagingTexture() SafeRelease(mStagingTexture); } -unsigned int Image11::getStagingSubresource() -{ - createStagingTexture(); - - return mStagingSubresource; -} - -void Image11::createStagingTexture() +gl::Error Image11::createStagingTexture() { if (mStagingTexture) { - return; + return gl::Error(GL_NO_ERROR); } + ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0); + const DXGI_FORMAT dxgiFormat = getDXGIFormat(); - if (mWidth > 0 && mHeight > 0 && mDepth > 0) + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + int lodOffset = 1; + GLsizei width = mWidth; + GLsizei height = mHeight; + + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); + + if (mTarget == GL_TEXTURE_3D) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + ID3D11Texture3D *newTexture = NULL; - int lodOffset = 1; - GLsizei width = mWidth; - GLsizei height = mHeight; + D3D11_TEXTURE3D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.Depth = mDepth; + desc.MipLevels = lodOffset + 1; + desc.Format = dxgiFormat; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); - - if (mTarget == GL_TEXTURE_3D) + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { - ID3D11Texture3D *newTexture = NULL; + std::vector initialData; + std::vector< std::vector > textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth, + lodOffset + 1, &initialData, &textureData); - D3D11_TEXTURE3D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.Depth = mDepth; - desc.MipLevels = lodOffset + 1; - desc.Format = dxgiFormat; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - - if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) - { - std::vector initialData; - std::vector< std::vector > textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth, - lodOffset + 1, &initialData, &textureData); - - result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); - } - else - { - result = device->CreateTexture3D(&desc, NULL, &newTexture); - } - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - return gl::error(GL_OUT_OF_MEMORY); - } - - mStagingTexture = newTexture; - mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); - } - else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) - { - ID3D11Texture2D *newTexture = NULL; - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = lodOffset + 1; - desc.ArraySize = 1; - desc.Format = dxgiFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - - if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) - { - std::vector initialData; - std::vector< std::vector > textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1, - lodOffset + 1, &initialData, &textureData); - - result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); - } - else - { - result = device->CreateTexture2D(&desc, NULL, &newTexture); - } - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - return gl::error(GL_OUT_OF_MEMORY); - } - - mStagingTexture = newTexture; - mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); } else { - UNREACHABLE(); + result = device->CreateTexture3D(&desc, NULL, &newTexture); } + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); + } + + mStagingTexture = newTexture; + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + } + else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) + { + ID3D11Texture2D *newTexture = NULL; + + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = lodOffset + 1; + desc.ArraySize = 1; + desc.Format = dxgiFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) + { + std::vector initialData; + std::vector< std::vector > textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1, + lodOffset + 1, &initialData, &textureData); + + result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); + } + else + { + result = device->CreateTexture2D(&desc, NULL, &newTexture); + } + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); + } + + mStagingTexture = newTexture; + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + } + else + { + UNREACHABLE(); } mDirty = false; + return gl::Error(GL_NO_ERROR); } -HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) +gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) { - createStagingTexture(); - // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE. - recoverFromAssociatedStorage(); - - HRESULT result = E_FAIL; - - if (mStagingTexture) + gl::Error error = recoverFromAssociatedStorage(); + if (error.isError()) { - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map); - - // this can fail if the device is removed (from TDR) - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - } - else if (SUCCEEDED(result)) - { - mDirty = true; - } + return error; } - return result; + ID3D11Resource *stagingTexture = NULL; + unsigned int subresourceIndex = 0; + error = getStagingTexture(&stagingTexture, &subresourceIndex); + if (error.isError()) + { + return error; + } + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + ASSERT(mStagingTexture); + HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map); + + // this can fail if the device is removed (from TDR) + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + } + else if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result); + } + + mDirty = true; + + return gl::Error(GL_NO_ERROR); } void Image11::unmap() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h index a76a61f036..a936e6d7b2 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h @@ -11,6 +11,7 @@ #define LIBGLESV2_RENDERER_IMAGE11_H_ #include "libGLESv2/renderer/d3d/ImageD3D.h" +#include "libGLESv2/ImageIndex.h" #include "common/debug.h" @@ -21,7 +22,6 @@ class Framebuffer; namespace rx { -class Renderer; class Renderer11; class TextureStorage11; @@ -33,42 +33,41 @@ class Image11 : public ImageD3D static Image11 *makeImage11(Image *img); - static void generateMipmap(Image11 *dest, Image11 *src); + static gl::Error generateMipmap(Image11 *dest, Image11 *src); virtual bool isDirty() const; - virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); - virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height); + virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion); - virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease); + bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override; DXGI_FORMAT getDXGIFormat() const; - - virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input); - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input); - virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input); + virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input); - bool recoverFromAssociatedStorage(); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, + const gl::ImageIndex &sourceIndex, TextureStorage *source); + + gl::Error recoverFromAssociatedStorage(); bool isAssociatedStorageValid(TextureStorage11* textureStorage) const; void disassociateStorage(); protected: - HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); + gl::Error map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); void unmap(); private: DISALLOW_COPY_AND_ASSIGN(Image11); - bool copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box ®ion); + gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource); - ID3D11Resource *getStagingTexture(); - unsigned int getStagingSubresource(); - void createStagingTexture(); + gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex); + gl::Error createStagingTexture(); void releaseStagingTexture(); Renderer11 *mRenderer; @@ -79,8 +78,7 @@ class Image11 : public ImageD3D bool mRecoverFromStorage; TextureStorage11 *mAssociatedStorage; - int mAssociatedStorageLevel; - int mAssociatedStorageLayerTarget; + gl::ImageIndex mAssociatedImageIndex; unsigned int mRecoveredFromStorageCount; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h index f7c2b38e7e..3351df5ec1 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h @@ -40,7 +40,7 @@ class IndexBuffer11 : public IndexBuffer private: DISALLOW_COPY_AND_ASSIGN(IndexBuffer11); - rx::Renderer11 *const mRenderer; + Renderer11 *const mRenderer; ID3D11Buffer *mBuffer; unsigned int mBufferSize; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp index d835e4fa68..ff90a6a69a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp @@ -12,6 +12,7 @@ #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" +#include "libGLESv2/renderer/d3d/ProgramD3D.h" #include "libGLESv2/renderer/d3d/VertexDataManager.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/VertexAttribute.h" @@ -137,7 +138,16 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl { gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS]; GetInputLayout(attributes, shaderInputLayout); - ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout)); + ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation()); + + ShaderExecutable *shader = NULL; + gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader); + if (error.isError()) + { + return error; + } + + ShaderExecutable *shader11 = ShaderExecutable11::makeShaderExecutable11(shader); D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS]; for (unsigned int j = 0; j < ilKey.elementCount; ++j) @@ -145,7 +155,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl descs[j] = ilKey.elements[j].desc; } - HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); + HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp index a4e84f91c2..6a3d3475ee 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -33,12 +33,38 @@ namespace rx PixelTransfer11::PixelTransfer11(Renderer11 *renderer) : mRenderer(renderer), + mResourcesLoaded(false), mBufferToTextureVS(NULL), mBufferToTextureGS(NULL), mParamsConstantBuffer(NULL), mCopyRasterizerState(NULL), mCopyDepthStencilState(NULL) { +} + +PixelTransfer11::~PixelTransfer11() +{ + for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) + { + SafeRelease(shaderMapIt->second); + } + + mBufferToTexturePSMap.clear(); + + SafeRelease(mBufferToTextureVS); + SafeRelease(mBufferToTextureGS); + SafeRelease(mParamsConstantBuffer); + SafeRelease(mCopyRasterizerState); + SafeRelease(mCopyDepthStencilState); +} + +gl::Error PixelTransfer11::loadResources() +{ + if (mResourcesLoaded) + { + return gl::Error(GL_NO_ERROR); + } + HRESULT result = S_OK; ID3D11Device *device = mRenderer->getDevice(); @@ -56,6 +82,10 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer) result = device->CreateRasterizerState(&rasterDesc, &mCopyRasterizerState); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer rasterizer state, result: 0x%X.", result); + } D3D11_DEPTH_STENCIL_DESC depthStencilDesc; depthStencilDesc.DepthEnable = true; @@ -75,9 +105,13 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer) result = device->CreateDepthStencilState(&depthStencilDesc, &mCopyDepthStencilState); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer depth stencil state, result: 0x%X.", result); + } D3D11_BUFFER_DESC constantBufferDesc = { 0 }; - constantBufferDesc.ByteWidth = rx::roundUp(sizeof(CopyShaderParams), 32u); + constantBufferDesc.ByteWidth = roundUp(sizeof(CopyShaderParams), 32u); constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; @@ -86,34 +120,39 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer) result = device->CreateBuffer(&constantBufferDesc, NULL, &mParamsConstantBuffer); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer constant buffer, result: 0x%X.", result); + } d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer"); + // init shaders + mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS"); + if (!mBufferToTextureVS) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader."); + } + + if (!mRenderer->isLevel9()) + { + mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); + if (!mBufferToTextureGS) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader."); + } + } + + gl::Error error = buildShaderMap(); + if (error.isError()) + { + return error; + } + StructZero(&mParamsData); - // init shaders - if (mRenderer->isLevel9()) - return; + mResourcesLoaded = true; - mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS"); - mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); - - buildShaderMap(); -} - -PixelTransfer11::~PixelTransfer11() -{ - for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) - { - SafeRelease(shaderMapIt->second); - } - - mBufferToTexturePSMap.clear(); - - SafeRelease(mBufferToTextureVS); - SafeRelease(mBufferToTextureGS); - SafeRelease(mParamsConstantBuffer); - SafeRelease(mCopyRasterizerState); - SafeRelease(mCopyDepthStencilState); + return gl::Error(GL_NO_ERROR); } void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, @@ -138,17 +177,20 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons parametersOut->PositionScale[1] = -2.0f / static_cast(destSize.height); } -bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { + gl::Error error = loadResources(); + if (error.isError()) + { + return error; + } + gl::Extents destSize = destRenderTarget->getExtents(); - if (destArea.x < 0 || destArea.x + destArea.width > destSize.width || - destArea.y < 0 || destArea.y + destArea.height > destSize.height || - destArea.z < 0 || destArea.z + destArea.depth > destSize.depth ) - { - return false; - } + ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && + destArea.y >= 0 && destArea.y + destArea.height <= destSize.height && + destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth ); const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get(); @@ -177,7 +219,6 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - ID3D11ShaderResourceView *nullSRV = NULL; ID3D11Buffer *nullBuffer = NULL; UINT zero = 0; @@ -187,7 +228,7 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0); deviceContext->GSSetShader(geometryShader, NULL, 0); deviceContext->PSSetShader(pixelShader, NULL, 0); - deviceContext->PSSetShaderResources(0, 1, &bufferSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV); deviceContext->IASetInputLayout(NULL); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); @@ -220,21 +261,32 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un deviceContext->Draw(numPixels, 0); // Unbind textures and render targets and vertex buffer - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); mRenderer->markAllStateDirty(); - return true; + return gl::Error(GL_NO_ERROR); } -void PixelTransfer11::buildShaderMap() +gl::Error PixelTransfer11::buildShaderMap() { ID3D11Device *device = mRenderer->getDevice(); mBufferToTexturePSMap[GL_FLOAT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4F, "BufferToTexture RGBA ps"); mBufferToTexturePSMap[GL_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4I, "BufferToTexture RGBA-I ps"); mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps"); + + // Check that all the shaders were created successfully + for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) + { + if (shaderMapIt->second == NULL) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture pixel shader."); + } + } + + return gl::Error(GL_NO_ERROR); } ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h index ed1a3ae1d0..29552140bb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h @@ -11,6 +11,8 @@ #ifndef LIBGLESV2_PIXELTRANSFER11_H_ #define LIBGLESV2_PIXELTRANSFER11_H_ +#include "libGLESv2/Error.h" + #include "common/platform.h" #include @@ -38,15 +40,13 @@ class PixelTransfer11 explicit PixelTransfer11(Renderer11 *renderer); ~PixelTransfer11(); - static bool supportsBufferToTextureCopy(GLenum internalFormat); - // unpack: the source buffer is stored in the unpack state, and buffer strides // offset: the start of the data within the unpack buffer // destRenderTarget: individual slice/layer of a target texture // destinationFormat/sourcePixelsType: determines shaders + shader parameters // destArea: the sub-section of destRenderTarget to copy to - bool copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + gl::Error copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); private: @@ -65,11 +65,13 @@ class PixelTransfer11 static void setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, const gl::PixelUnpackState &unpack, unsigned int offset, CopyShaderParams *parametersOut); - void buildShaderMap(); + gl::Error loadResources(); + gl::Error buildShaderMap(); ID3D11PixelShader *findBufferToTexturePS(GLenum internalFormat) const; Renderer11 *mRenderer; + bool mResourcesLoaded; std::map mBufferToTexturePSMap; ID3D11VertexShader *mBufferToTextureVS; ID3D11GeometryShader *mBufferToTextureGS; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp index 7109be3e28..17ab1f8ab3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp @@ -10,13 +10,14 @@ #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/main.h" +#include "common/utilities.h" #include namespace rx { -Query11::Query11(rx::Renderer11 *renderer, GLenum type) +Query11::Query11(Renderer11 *renderer, GLenum type) : QueryImpl(type), mResult(0), mQueryFinished(false), diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h index 822f2542ee..f9ff467873 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h @@ -18,7 +18,7 @@ class Renderer11; class Query11 : public QueryImpl { public: - Query11(rx::Renderer11 *renderer, GLenum type); + Query11(Renderer11 *renderer, GLenum type); virtual ~Query11(); virtual gl::Error begin(); @@ -35,7 +35,7 @@ class Query11 : public QueryImpl bool mQueryFinished; - rx::Renderer11 *mRenderer; + Renderer11 *mRenderer; ID3D11Query *mQuery; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp index 71b931f27e..ab4f60bd98 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp @@ -38,11 +38,14 @@ const unsigned int RenderStateCache::kMaxRasterizerStates = 4096; const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096; const unsigned int RenderStateCache::kMaxSamplerStates = 4096; -RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0), - mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), - mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), - mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), - mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates) +RenderStateCache::RenderStateCache(Renderer11 *renderer) + : mRenderer(renderer), + mDevice(NULL), + mCounter(0), + mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), + mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), + mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), + mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates) { } @@ -89,7 +92,7 @@ gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, co bool mrt = false; - const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(mRenderer->getWorkarounds()); BlendStateKey key = { 0 }; key.blendState = blendState; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h index d5471a3061..dfd1d84265 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h @@ -28,7 +28,7 @@ class Renderer11; class RenderStateCache { public: - RenderStateCache(); + RenderStateCache(Renderer11 *renderer); virtual ~RenderStateCache(); void initialize(ID3D11Device *device); @@ -42,6 +42,7 @@ class RenderStateCache private: DISALLOW_COPY_AND_ASSIGN(RenderStateCache); + Renderer11 *mRenderer; unsigned long long mCounter; // Blend state cache diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp index 3041f21faa..aff3453492 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp @@ -10,6 +10,7 @@ #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/main.h" @@ -176,246 +177,10 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, - ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) -{ - mRenderer = Renderer11::makeRenderer11(renderer); - - mTexture = resource; - if (mTexture) - { - mTexture->AddRef(); - } - - mRenderTarget = rtv; - if (mRenderTarget) - { - mRenderTarget->AddRef(); - } - - mDepthStencil = NULL; - - mShaderResource = srv; - if (mShaderResource) - { - mShaderResource->AddRef(); - } - - mSubresourceIndex = 0; - - if (mRenderTarget && mTexture) - { - D3D11_RENDER_TARGET_VIEW_DESC desc; - mRenderTarget->GetDesc(&desc); - - unsigned int mipLevels, samples; - getTextureProperties(mTexture, &mipLevels, &samples); - - mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); - mWidth = width; - mHeight = height; - mDepth = depth; - mSamples = samples; - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); - mInternalFormat = dxgiFormatInfo.internalFormat; - mActualFormat = dxgiFormatInfo.internalFormat; - } -} - -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, - ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) -{ - mRenderer = Renderer11::makeRenderer11(renderer); - - mTexture = resource; - if (mTexture) - { - mTexture->AddRef(); - } - - mRenderTarget = NULL; - - mDepthStencil = dsv; - if (mDepthStencil) - { - mDepthStencil->AddRef(); - } - - mShaderResource = srv; - if (mShaderResource) - { - mShaderResource->AddRef(); - } - - mSubresourceIndex = 0; - - if (mDepthStencil && mTexture) - { - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - mDepthStencil->GetDesc(&desc); - - unsigned int mipLevels, samples; - getTextureProperties(mTexture, &mipLevels, &samples); - - mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); - mWidth = width; - mHeight = height; - mDepth = depth; - mSamples = samples; - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); - mInternalFormat = dxgiFormatInfo.internalFormat; - mActualFormat = dxgiFormatInfo.internalFormat; - } -} - -RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples) -{ - mRenderer = Renderer11::makeRenderer11(renderer); - mTexture = NULL; - mRenderTarget = NULL; - mDepthStencil = NULL; - mShaderResource = NULL; - - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); - - const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); - GLuint supportedSamples = textureCaps.getNearestSamples(samples); - - if (width > 0 && height > 0) - { - // Create texture resource - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = formatInfo.texFormat; - desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - // If a rendertarget or depthstencil format exists for this texture format, - // we'll flag it to allow binding that way. Shader resource views are a little - // more complicated. - bool bindRTV = false, bindDSV = false, bindSRV = false; - bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); - bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); - if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) - { - // Multisample targets flagged for binding as depth stencil cannot also be - // flagged for binding as SRV, so make certain not to add the SRV flag for - // these targets. - bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); - } - - desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | - (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | - (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11Texture2D *texture = NULL; - HRESULT result = device->CreateTexture2D(&desc, NULL, &texture); - mTexture = texture; - - if (result == E_OUTOFMEMORY) - { - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - - if (bindSRV) - { - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = formatInfo.srvFormat; - srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; - srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Texture2D.MipLevels = 1; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(mTexture); - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - } - - if (bindDSV) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = formatInfo.dsvFormat; - dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; - dsvDesc.Texture2D.MipSlice = 0; - dsvDesc.Flags = 0; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(mTexture); - SafeRelease(mShaderResource); - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - } - - if (bindRTV) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = formatInfo.rtvFormat; - rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; - rtvDesc.Texture2D.MipSlice = 0; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(mTexture); - SafeRelease(mShaderResource); - SafeRelease(mDepthStencil); - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - - if (formatInfo.dataInitializerFunction != NULL) - { - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - context->ClearRenderTargetView(mRenderTarget, clearValues); - } - } - } - - - mWidth = width; - mHeight = height; - mDepth = 1; - mInternalFormat = internalFormat; - mSamples = supportedSamples; - mActualFormat = dxgiFormatInfo.internalFormat; - mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); -} - -RenderTarget11::~RenderTarget11() -{ - SafeRelease(mTexture); - SafeRelease(mRenderTarget); - SafeRelease(mDepthStencil); - SafeRelease(mShaderResource); -} - RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) { - ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target)); - return static_cast(target); + ASSERT(HAS_DYNAMIC_TYPE(RenderTarget11*, target)); + return static_cast(target); } void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) @@ -423,29 +188,217 @@ void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) // Currently a no-op } -ID3D11Resource *RenderTarget11::getTexture() const +TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) + : mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mActualFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(rtv), + mDepthStencil(NULL), + mShaderResource(srv) +{ + if (mTexture) + { + mTexture->AddRef(); + } + + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + + if (mShaderResource) + { + mShaderResource->AddRef(); + } + + if (mRenderTarget && mTexture) + { + mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); + + D3D11_RENDER_TARGET_VIEW_DESC desc; + mRenderTarget->GetDesc(&desc); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); + mActualFormat = dxgiFormatInfo.internalFormat; + } +} + +TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) + : mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mActualFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(NULL), + mDepthStencil(dsv), + mShaderResource(srv) +{ + if (mTexture) + { + mTexture->AddRef(); + } + + if (mDepthStencil) + { + mDepthStencil->AddRef(); + } + + if (mShaderResource) + { + mShaderResource->AddRef(); + } + + if (mDepthStencil && mTexture) + { + mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); + + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + mDepthStencil->GetDesc(&desc); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format); + mActualFormat = dxgiFormatInfo.internalFormat; + } +} + +TextureRenderTarget11::~TextureRenderTarget11() +{ + SafeRelease(mTexture); + SafeRelease(mRenderTarget); + SafeRelease(mDepthStencil); + SafeRelease(mShaderResource); +} + +ID3D11Resource *TextureRenderTarget11::getTexture() const { return mTexture; } -ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const +ID3D11RenderTargetView *TextureRenderTarget11::getRenderTargetView() const { return mRenderTarget; } -ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const +ID3D11DepthStencilView *TextureRenderTarget11::getDepthStencilView() const { return mDepthStencil; } -ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const +ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const { return mShaderResource; } -unsigned int RenderTarget11::getSubresourceIndex() const +GLsizei TextureRenderTarget11::getWidth() const +{ + return mWidth; +} + +GLsizei TextureRenderTarget11::getHeight() const +{ + return mHeight; +} + +GLsizei TextureRenderTarget11::getDepth() const +{ + return mDepth; +} + +GLenum TextureRenderTarget11::getInternalFormat() const +{ + return mInternalFormat; +} + +GLenum TextureRenderTarget11::getActualFormat() const +{ + return mActualFormat; +} + +GLsizei TextureRenderTarget11::getSamples() const +{ + return mSamples; +} + +unsigned int TextureRenderTarget11::getSubresourceIndex() const { return mSubresourceIndex; } + +SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth) + : mSwapChain(swapChain), + mDepth(depth) +{ + ASSERT(mSwapChain); +} + +SurfaceRenderTarget11::~SurfaceRenderTarget11() +{ +} + +GLsizei SurfaceRenderTarget11::getWidth() const +{ + return mSwapChain->getWidth(); +} + +GLsizei SurfaceRenderTarget11::getHeight() const +{ + return mSwapChain->getHeight(); +} + +GLsizei SurfaceRenderTarget11::getDepth() const +{ + return 1; +} + +GLenum SurfaceRenderTarget11::getInternalFormat() const +{ + return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); +} + +GLenum SurfaceRenderTarget11::getActualFormat() const +{ + return d3d11::GetDXGIFormatInfo(d3d11::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat; +} + +GLsizei SurfaceRenderTarget11::getSamples() const +{ + // Our EGL surfaces do not support multisampling. + return 0; +} + +ID3D11Resource *SurfaceRenderTarget11::getTexture() const +{ + return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture()); +} + +ID3D11RenderTargetView *SurfaceRenderTarget11::getRenderTargetView() const +{ + return (mDepth ? NULL : mSwapChain->getRenderTarget()); +} + +ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const +{ + return (mDepth ? mSwapChain->getDepthStencil() : NULL); +} + +ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const +{ + return (mDepth ? mSwapChain->getDepthStencilShaderResource() : mSwapChain->getRenderTargetShaderResource()); +} + +unsigned int SurfaceRenderTarget11::getSubresourceIndex() const +{ + return 0; +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h index 82182957af..c7babdda3f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h @@ -14,39 +14,95 @@ namespace rx { -class Renderer; -class Renderer11; +class SwapChain11; class RenderTarget11 : public RenderTarget { public: - // RenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them - RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth); - RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth); - RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples); - virtual ~RenderTarget11(); + RenderTarget11() { } + virtual ~RenderTarget11() { } static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget); - virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height); + void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override; - ID3D11Resource *getTexture() const; - ID3D11RenderTargetView *getRenderTargetView() const; - ID3D11DepthStencilView *getDepthStencilView() const; - ID3D11ShaderResourceView *getShaderResourceView() const; + virtual ID3D11Resource *getTexture() const = 0; + virtual ID3D11RenderTargetView *getRenderTargetView() const = 0; + virtual ID3D11DepthStencilView *getDepthStencilView() const = 0; + virtual ID3D11ShaderResourceView *getShaderResourceView() const = 0; - unsigned int getSubresourceIndex() const; + virtual unsigned int getSubresourceIndex() const = 0; private: DISALLOW_COPY_AND_ASSIGN(RenderTarget11); +}; + +class TextureRenderTarget11 : public RenderTarget11 +{ + public: + // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them + TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); + TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); + virtual ~TextureRenderTarget11(); + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLenum getActualFormat() const override; + GLsizei getSamples() const override; + + ID3D11Resource *getTexture() const override; + ID3D11RenderTargetView *getRenderTargetView() const override; + ID3D11DepthStencilView *getDepthStencilView() const override; + ID3D11ShaderResourceView *getShaderResourceView() const override; + + unsigned int getSubresourceIndex() const override; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget11); + + GLsizei mWidth; + GLsizei mHeight; + GLsizei mDepth; + GLenum mInternalFormat; + GLenum mActualFormat; + GLsizei mSamples; unsigned int mSubresourceIndex; ID3D11Resource *mTexture; ID3D11RenderTargetView *mRenderTarget; ID3D11DepthStencilView *mDepthStencil; ID3D11ShaderResourceView *mShaderResource; +}; - Renderer11 *mRenderer; +class SurfaceRenderTarget11 : public RenderTarget11 +{ + public: + SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth); + virtual ~SurfaceRenderTarget11(); + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLenum getActualFormat() const override; + GLsizei getSamples() const override; + + ID3D11Resource *getTexture() const override; + ID3D11RenderTargetView *getRenderTargetView() const override; + ID3D11DepthStencilView *getDepthStencilView() const override; + ID3D11ShaderResourceView *getShaderResourceView() const override; + + unsigned int getSubresourceIndex() const override; + + private: + DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget11); + + SwapChain11 *mSwapChain; + bool mDepth; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp index b29b2ef910..e6d7f3025b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp @@ -6,12 +6,12 @@ // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. -#include "common/platform.h" #include "libGLESv2/main.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Framebuffer.h" +#include "libGLESv2/State.h" #include "libGLESv2/renderer/d3d/ProgramD3D.h" #include "libGLESv2/renderer/d3d/ShaderD3D.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" @@ -36,10 +36,12 @@ #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h" #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h" #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" +#include "libGLESv2/renderer/d3d/RenderbufferD3D.h" #include "libEGL/Display.h" #include "common/utilities.h" +#include "common/tls.h" #include @@ -59,6 +61,9 @@ namespace rx { + +namespace +{ static const DXGI_FORMAT RenderTargetFormats[] = { DXGI_FORMAT_B8G8R8A8_UNORM, @@ -77,10 +82,22 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 }; -Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay) - : Renderer(display), +// Does *not* increment the resource ref count!! +ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv) +{ + ID3D11Resource *resource = NULL; + ASSERT(srv); + srv->GetResource(&resource); + resource->Release(); + return resource; +} + +} + +Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes) + : RendererD3D(display), mDc(hDc), - mRequestedDisplay(requestedDisplay) + mStateCache(this) { mVertexDataManager = NULL; mIndexDataManager = NULL; @@ -112,6 +129,50 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint r mAppliedGeometryShader = NULL; mCurPointGeometryShader = NULL; mAppliedPixelShader = NULL; + + EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE); + EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE); + + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0); + } + } + + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0); + } + } + +#if !defined(ANGLE_ENABLE_D3D9) + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9) + { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2); + } + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) + { + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1); + } + } +#endif + + mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP + : D3D_DRIVER_TYPE_HARDWARE; } Renderer11::~Renderer11() @@ -121,8 +182,8 @@ Renderer11::~Renderer11() Renderer11 *Renderer11::makeRenderer11(Renderer *renderer) { - ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer)); - return static_cast(renderer); + ASSERT(HAS_DYNAMIC_TYPE(Renderer11*, renderer)); + return static_cast(renderer); } #ifndef __d3d11_1_h__ @@ -136,7 +197,7 @@ EGLint Renderer11::initialize() return EGL_NOT_INITIALIZED; } -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); @@ -157,33 +218,14 @@ EGLint Renderer11::initialize() } #endif - D3D_FEATURE_LEVEL featureLevels[] = - { - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, -#if !defined(ANGLE_ENABLE_D3D9) - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, -#endif - }; - - D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE; - if (mRequestedDisplay == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE) - { - driverType = D3D_DRIVER_TYPE_WARP; - } - HRESULT result = S_OK; - #ifdef _DEBUG result = D3D11CreateDevice(NULL, - driverType, + mDriverType, NULL, D3D11_CREATE_DEVICE_DEBUG, - featureLevels, - ArraySize(featureLevels), + mAvailableFeatureLevels.data(), + mAvailableFeatureLevels.size(), D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, @@ -198,11 +240,11 @@ EGLint Renderer11::initialize() #endif { result = D3D11CreateDevice(NULL, - driverType, + mDriverType, NULL, 0, - featureLevels, - ArraySize(featureLevels), + mAvailableFeatureLevels.data(), + mAvailableFeatureLevels.size(), D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, @@ -215,7 +257,18 @@ EGLint Renderer11::initialize() } } -#if !ANGLE_SKIP_DXGI_1_2_CHECK && !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED"); + if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1")) + { + ID3D10Multithread *multithread; + result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread)); + ASSERT(SUCCEEDED(result)); + result = multithread->SetMultithreadProtected(true); + ASSERT(SUCCEEDED(result)); + multithread->Release(); + } +#if !ANGLE_SKIP_DXGI_1_2_CHECK // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. // The easiest way to check is to query for a IDXGIDevice2. bool requireDXGI1_2 = false; @@ -244,13 +297,10 @@ EGLint Renderer11::initialize() SafeRelease(dxgiDevice2); } #endif - -#if !defined(ANGLE_PLATFORM_WINRT) - IDXGIDevice *dxgiDevice = NULL; -#else - IDXGIDevice1 *dxgiDevice = NULL; #endif - result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); + + IDXGIDevice *dxgiDevice = NULL; + result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (FAILED(result)) { @@ -281,9 +331,9 @@ EGLint Renderer11::initialize() } // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log -#if !defined(__MINGW32__) && defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) +#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) ID3D11InfoQueue *infoQueue; - result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); + result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue); if (SUCCEEDED(result)) { @@ -301,19 +351,6 @@ EGLint Renderer11::initialize() } #endif -#if !defined(ANGLE_PLATFORM_WINRT) - static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED"); - if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1")) - { - ID3D10Multithread *multithread; - result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread)); - ASSERT(SUCCEEDED(result)); - result = multithread->SetMultithreadProtected(true); - ASSERT(SUCCEEDED(result)); - multithread->Release(); - } -#endif - initializeDevice(); return EGL_SUCCESS; @@ -394,7 +431,7 @@ void Renderer11::deleteConfigs(ConfigDesc *configDescList) delete [] (configDescList); } -void Renderer11::sync(bool block) +gl::Error Renderer11::sync(bool block) { if (block) { @@ -408,6 +445,10 @@ void Renderer11::sync(bool block) result = mDevice->CreateQuery(&queryDesc, &mSyncQuery); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result); + } } mDeviceContext->End(mSyncQuery); @@ -416,13 +457,17 @@ void Renderer11::sync(bool block) do { result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + } // Keep polling, but allow other threads to do something useful first Sleep(0); if (testDeviceLost(true)) { - return; + return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync."); } } while (result == S_FALSE); @@ -431,22 +476,26 @@ void Renderer11::sync(bool block) { mDeviceContext->Flush(); } + + return gl::Error(GL_NO_ERROR); } -SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +SwapChain *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) { - return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); + return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); } gl::Error Renderer11::generateSwizzle(gl::Texture *texture) { if (texture) { - TextureStorage *texStorage = texture->getNativeTexture(); + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + ASSERT(textureD3D); + + TextureStorage *texStorage = textureD3D->getNativeTexture(); if (texStorage) { TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); - gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed, texture->getSamplerState().swizzleGreen, texture->getSamplerState().swizzleBlue, @@ -461,16 +510,21 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam) { + // Make sure to add the level offset for our tiny compressed texture workaround + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + gl::SamplerState samplerStateInternal = samplerStateParam; + samplerStateInternal.baseLevel += textureD3D->getNativeTexture()->getTopLevel(); + if (type == gl::SAMPLER_PIXEL) { ASSERT(static_cast(index) < getRendererCaps().maxTextureImageUnits); - if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) + if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) { ID3D11SamplerState *dxSamplerState = NULL; - gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState); if (error.isError()) { return error; @@ -479,7 +533,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: ASSERT(dxSamplerState != NULL); mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); - mCurPixelSamplerStates[index] = samplerState; + mCurPixelSamplerStates[index] = samplerStateInternal; } mForceSetPixelSamplerStates[index] = false; @@ -488,10 +542,10 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: { ASSERT(static_cast(index) < getRendererCaps().maxVertexTextureImageUnits); - if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) + if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) { ID3D11SamplerState *dxSamplerState = NULL; - gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); + gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState); if (error.isError()) { return error; @@ -500,7 +554,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: ASSERT(dxSamplerState != NULL); mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); - mCurVertexSamplerStates[index] = samplerState; + mCurVertexSamplerStates[index] = samplerStateInternal; } mForceSetVertexSamplerStates[index] = false; @@ -513,50 +567,36 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl: gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) { ID3D11ShaderResourceView *textureSRV = NULL; - bool forceSetTexture = false; if (texture) { - TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); + TextureD3D *textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); TextureStorage *texStorage = textureImpl->getNativeTexture(); ASSERT(texStorage != NULL); TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); - gl::SamplerState samplerState; - texture->getSamplerStateWithNativeOffset(&samplerState); - textureSRV = storage11->getSRV(samplerState); + + // Make sure to add the level offset for our tiny compressed texture workaround + gl::SamplerState samplerState = texture->getSamplerState(); + samplerState.baseLevel += storage11->getTopLevel(); + + gl::Error error = storage11->getSRV(samplerState, &textureSRV); + if (error.isError()) + { + return error; + } // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly // missing the shader resource view ASSERT(textureSRV != NULL); - forceSetTexture = textureImpl->hasDirtyImages(); textureImpl->resetDirty(); } - if (type == gl::SAMPLER_PIXEL) - { - ASSERT(static_cast(index) < getRendererCaps().maxTextureImageUnits); + ASSERT((type == gl::SAMPLER_PIXEL && static_cast(index) < getRendererCaps().maxTextureImageUnits) || + (type == gl::SAMPLER_VERTEX && static_cast(index) < getRendererCaps().maxVertexTextureImageUnits)); - if (forceSetTexture || mCurPixelSRVs[index] != textureSRV) - { - mDeviceContext->PSSetShaderResources(index, 1, &textureSRV); - } - - mCurPixelSRVs[index] = textureSRV; - } - else if (type == gl::SAMPLER_VERTEX) - { - ASSERT(static_cast(index) < getRendererCaps().maxVertexTextureImageUnits); - - if (forceSetTexture || mCurVertexSRVs[index] != textureSRV) - { - mDeviceContext->VSSetShaderResources(index, 1, &textureSRV); - } - - mCurVertexSRVs[index] = textureSRV; - } - else UNREACHABLE(); + setShaderResource(type, index, textureSRV); return gl::Error(GL_NO_ERROR); } @@ -631,7 +671,7 @@ gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, +gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask) { if (mForceSetBlendState || @@ -831,7 +871,22 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) return count >= minCount; } -gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) +void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource) +{ + std::vector ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex) + { + ID3D11ShaderResourceView *srv = currentSRVs[resourceIndex]; + + if (srv && GetSRVResource(srv) == resource) + { + setShaderResource(samplerType, static_cast(resourceIndex), NULL); + } + } +} + +gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) { // Get the color render buffer and serial // Also extract the render target dimensions and view @@ -842,7 +897,7 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; bool missingColorRenderTarget = true; - const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); + const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(getWorkarounds()); for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { @@ -863,17 +918,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer); // Extract the render target dimensions and view - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); + return error; } + ASSERT(renderTarget); framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); - if (!framebufferRTVs[colorAttachment]) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); - } + ASSERT(framebufferRTVs[colorAttachment]); if (missingColorRenderTarget) { @@ -883,8 +937,12 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) missingColorRenderTarget = false; } - // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent - // D3D11 warnings. +#if !defined(NDEBUG) + // Unbind render target SRVs from the shader here to prevent D3D11 warnings. + ID3D11Resource *renderTargetResource = renderTarget->getTexture(); + unsetSRVsWithResource(gl::SAMPLER_VERTEX, renderTargetResource); + unsetSRVsWithResource(gl::SAMPLER_PIXEL, renderTargetResource); +#endif } } @@ -905,19 +963,17 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) ID3D11DepthStencilView* framebufferDSV = NULL; if (depthStencil) { - RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil); - if (!depthStencilRenderTarget) + RenderTarget11 *depthStencilRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget); + if (error.isError()) { SafeRelease(framebufferRTVs); - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); + return error; } + ASSERT(depthStencilRenderTarget); framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); - if (!framebufferDSV) - { - SafeRelease(framebufferRTVs); - return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); - } + ASSERT(framebufferDSV); // If there is no render buffer, the width, height and format values come from // the depth stencil @@ -964,17 +1020,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); if (error.isError()) { return error; } - return mInputLayoutCache.applyVertexBuffers(attributes, programBinary); + return mInputLayoutCache.applyVertexBuffers(attributes, state.getCurrentProgramBinary()); } gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) @@ -1011,28 +1066,25 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen return gl::Error(GL_NO_ERROR); } -void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) +void Renderer11::applyTransformFeedbackBuffers(const gl::State& state) { - ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + size_t numXFBBindings = state.getTransformFeedbackBufferIndexRange(); + ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); + bool requiresUpdate = false; - for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (size_t i = 0; i < numXFBBindings; i++) { - if (transformFeedbackBuffers[i]) + gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i); + GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i); + ID3D11Buffer *d3dBuffer = NULL; + if (curXFBBuffer) { - Buffer11 *storage = Buffer11::makeBuffer11(transformFeedbackBuffers[i]->getImplementation()); - ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); - - d3dBuffers[i] = buffer; - d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast(offsets[i]) : -1; - } - else - { - d3dBuffers[i] = NULL; - d3dOffsets[i] = 0; + Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation()); + d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); } - if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i]) + // TODO: mAppliedTFBuffers and friends should also be kept in a vector. + if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i]) { requiresUpdate = true; } @@ -1040,12 +1092,29 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff if (requiresUpdate) { - mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets); - for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) + for (size_t i = 0; i < numXFBBindings; ++i) { - mAppliedTFBuffers[i] = d3dBuffers[i]; - mAppliedTFOffsets[i] = offsets[i]; + gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i); + GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i); + + if (curXFBBuffer) + { + Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation()); + ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + + mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer && mAppliedTFOffsets[i] != curXFBOffset) ? + static_cast(curXFBOffset) : -1; + mAppliedTFBuffers[i] = d3dBuffer; + } + else + { + mAppliedTFBuffers[i] = NULL; + mCurrentD3DOffsets[i] = 0; + } + mAppliedTFOffsets[i] = curXFBOffset; } + + mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets); } } @@ -1129,7 +1198,6 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons return gl::Error(GL_NO_ERROR); } } - template static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data) { @@ -1213,10 +1281,17 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferImpl *storage = indexBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; + + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } // TODO: some level 9 hardware supports 32-bit indices; test and store support instead @@ -1291,10 +1366,17 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferImpl *storage = indexBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; + + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; @@ -1376,9 +1458,23 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, bool rasterizerDiscard, bool transformFeedbackActive) { - ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); - ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); - ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); + ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation()); + + ShaderExecutable *vertexExe = NULL; + gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe); + if (error.isError()) + { + return error; + } + + ShaderExecutable *pixelExe = NULL; + error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + if (error.isError()) + { + return error; + } + + ShaderExecutable *geometryExe = programD3D->getGeometryExecutable(); ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL); @@ -1433,16 +1529,14 @@ gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::V if (dirtyUniforms) { - programBinary->dirtyAllUniforms(); + programD3D->dirtyAllUniforms(); } return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector &uniformArray) { - const std::vector &uniformArray = programBinary.getUniforms(); - unsigned int totalRegisterCountVS = 0; unsigned int totalRegisterCountPS = 0; @@ -1466,7 +1560,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) } } - const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation()); + const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(&program); const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage()); const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage()); ASSERT(vertexUniformStorage); @@ -1598,7 +1692,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) { gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer); if (error.isError()) @@ -1626,14 +1720,12 @@ void Renderer11::markAllStateDirty() for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) { mForceSetVertexSamplerStates[vsamplerId] = true; - mCurVertexSRVs[vsamplerId] = NULL; } ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size()); for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) { mForceSetPixelSamplerStates[fsamplerId] = true; - mCurPixelSRVs[fsamplerId] = NULL; } mForceSetBlendState = true; @@ -1746,32 +1838,20 @@ bool Renderer11::testDeviceResettable() return false; } - D3D_FEATURE_LEVEL featureLevels[] = - { - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, -#if !defined(ANGLE_ENABLE_D3D9) - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, -#endif - }; - ID3D11Device* dummyDevice; D3D_FEATURE_LEVEL dummyFeatureLevel; ID3D11DeviceContext* dummyContext; HRESULT result = D3D11CreateDevice(NULL, - D3D_DRIVER_TYPE_HARDWARE, + mDriverType, NULL, #if defined(_DEBUG) D3D11_CREATE_DEVICE_DEBUG, #else 0, #endif - featureLevels, - ArraySize(featureLevels), + mAvailableFeatureLevels.data(), + mAvailableFeatureLevels.size(), D3D11_SDK_VERSION, &dummyDevice, &dummyFeatureLevel, @@ -1939,119 +2019,37 @@ int Renderer11::getMaxSwapInterval() const return 4; } -bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source); - TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source); - TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source); - TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) -{ - if (source && dest) - { - TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source); - TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest); - - mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); - - dest11->invalidateSwizzleCache(); - - return true; - } - - return false; -} - -bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) +gl::Error Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - if (!colorbuffer) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(colorbuffer); - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(sourceRenderTarget); ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(source); TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); - if (!storage11) - { - ERR("Failed to retrieve the texture storage from the destination."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(storage11); gl::ImageIndex index = gl::ImageIndex::Make2D(level); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); @@ -2061,59 +2059,48 @@ bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle & // Use nearest filtering because source and destination are the same size for the direct // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); + mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } storage11->invalidateSwizzleCacheLevel(level); - return ret; + return gl::Error(GL_NO_ERROR); } -bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - if (!colorbuffer) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(colorbuffer); - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(sourceRenderTarget); ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(source); TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); - if (!storage11) - { - ERR("Failed to retrieve the texture storage from the destination."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(storage11); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); @@ -2123,123 +2110,48 @@ bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle // Use nearest filtering because source and destination are the same size for the direct // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } storage11->invalidateSwizzleCacheLevel(level); - return ret; + return gl::Error(GL_NO_ERROR); } -bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) -{ - gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - if (!colorbuffer) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) - { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); - if (!storage11) - { - ERR("Failed to retrieve the texture storage from the destination."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) - { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); - - gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - - // Use nearest filtering because source and destination are the same size for the direct - // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); - - storage11->invalidateSwizzleCacheLevel(level); - - return ret; -} - -bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, +gl::Error Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - if (!colorbuffer) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(colorbuffer); - RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (!sourceRenderTarget) + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(sourceRenderTarget); ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ASSERT(source); - TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); - if (!storage11) - { - SafeRelease(source); - ERR("Failed to retrieve the texture storage from the destination."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); + ASSERT(storage11); - gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset); - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); - if (!destRenderTarget) + gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset); + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) { - SafeRelease(source); - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); @@ -2249,12 +2161,66 @@ bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectan // Use nearest filtering because source and destination are the same size for the direct // copy - bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } storage11->invalidateSwizzleCacheLevel(level); - return ret; + return gl::Error(GL_NO_ERROR); +} + +gl::Error Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) +{ + gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); + ASSERT(colorbuffer); + + RenderTarget11 *sourceRenderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(sourceRenderTarget); + + ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + ASSERT(source); + + TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); + ASSERT(storage11); + + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset); + RenderTarget *destRenderTarget = NULL; + error = storage11->getRenderTarget(index, &destRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(destRenderTarget); + + ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView(); + ASSERT(dest); + + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + + gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); + + // Use nearest filtering because source and destination are the same size for the direct + // copy + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + if (error.isError()) + { + return error; + } + + storage11->invalidateSwizzleCacheLevel(level); + + return gl::Error(GL_NO_ERROR); } void Renderer11::unapplyRenderTargets() @@ -2277,39 +2243,150 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView } } -RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth) +gl::Error Renderer11::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) { SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); - RenderTarget11 *renderTarget = NULL; + *outRT = new SurfaceRenderTarget11(swapChain11, depth); + return gl::Error(GL_NO_ERROR); +} - if (depth) +gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) +{ + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format); + + const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); + + if (width > 0 && height > 0) { - // Note: depth stencil may be NULL for 0 sized surfaces - renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), - swapChain11->getDepthStencilTexture(), - swapChain11->getDepthStencilShaderResource(), - swapChain11->getWidth(), swapChain11->getHeight(), 1); + // Create texture resource + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = formatInfo.texFormat; + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + // If a rendertarget or depthstencil format exists for this texture format, + // we'll flag it to allow binding that way. Shader resource views are a little + // more complicated. + bool bindRTV = false, bindDSV = false, bindSRV = false; + bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + { + // Multisample targets flagged for binding as depth stencil cannot also be + // flagged for binding as SRV, so make certain not to add the SRV flag for + // these targets. + bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); + } + + desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | + (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | + (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); + + // The format must be either an RTV or a DSV + ASSERT(bindRTV != bindDSV); + + ID3D11Texture2D *texture = NULL; + HRESULT result = mDevice->CreateTexture2D(&desc, NULL, &texture); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result); + } + + ID3D11ShaderResourceView *srv = NULL; + if (bindSRV) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = formatInfo.srvFormat; + srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + + result = mDevice->CreateShaderResourceView(texture, &srvDesc, &srv); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + SafeRelease(texture); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result); + } + } + + if (bindDSV) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = formatInfo.dsvFormat; + dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.Flags = 0; + + ID3D11DepthStencilView *dsv = NULL; + result = mDevice->CreateDepthStencilView(texture, &dsvDesc, &dsv); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + SafeRelease(texture); + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result); + } + + *outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples); + + SafeRelease(dsv); + } + else if (bindRTV) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = formatInfo.rtvFormat; + rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; + rtvDesc.Texture2D.MipSlice = 0; + + ID3D11RenderTargetView *rtv = NULL; + result = mDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + SafeRelease(texture); + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result); + } + + if (formatInfo.dataInitializerFunction != NULL) + { + const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + mDeviceContext->ClearRenderTargetView(rtv, clearValues); + } + + *outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples); + + SafeRelease(rtv); + } + else + { + UNREACHABLE(); + } + + SafeRelease(texture); + SafeRelease(srv); } else { - // Note: render target may be NULL for 0 sized surfaces - renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), - swapChain11->getOffscreenTexture(), - swapChain11->getRenderTargetShaderResource(), - swapChain11->getWidth(), swapChain11->getHeight(), 1); + *outRT = new TextureRenderTarget11(reinterpret_cast(NULL), NULL, NULL, format, width, height, 1, supportedSamples); } - return renderTarget; + + return gl::Error(GL_NO_ERROR); } -RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples) +ShaderImpl *Renderer11::createShader(const gl::Data &data, GLenum type) { - RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples); - return renderTarget; -} - -ShaderImpl *Renderer11::createShader(GLenum type) -{ - return new ShaderD3D(type, this); + return new ShaderD3D(data, type, this); } ProgramImpl *Renderer11::createProgram() @@ -2322,22 +2399,23 @@ void Renderer11::releaseShaderCompiler() ShaderD3D::releaseCompiler(); } -ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers) +gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable) { - ShaderExecutable11 *executable = NULL; - HRESULT result; - switch (type) { - case rx::SHADER_VERTEX: + case SHADER_VERTEX: { ID3D11VertexShader *vertexShader = NULL; ID3D11GeometryShader *streamOutShader = NULL; - result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader); + HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result); + } if (transformFeedbackVaryings.size() > 0) { @@ -2363,99 +2441,116 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(), NULL, 0, 0, NULL, &streamOutShader); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create steam output shader, result: 0x%X.", result); + } } - if (vertexShader) - { - executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader); - } + *outExecutable = new ShaderExecutable11(function, length, vertexShader, streamOutShader); } break; - case rx::SHADER_PIXEL: + case SHADER_PIXEL: { ID3D11PixelShader *pixelShader = NULL; - result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader); + HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader); ASSERT(SUCCEEDED(result)); - - if (pixelShader) + if (FAILED(result)) { - executable = new ShaderExecutable11(function, length, pixelShader); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader, result: 0x%X.", result); } + + *outExecutable = new ShaderExecutable11(function, length, pixelShader); } break; - case rx::SHADER_GEOMETRY: + case SHADER_GEOMETRY: { ID3D11GeometryShader *geometryShader = NULL; - result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader); + HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader); ASSERT(SUCCEEDED(result)); - - if (geometryShader) + if (FAILED(result)) { - executable = new ShaderExecutable11(function, length, geometryShader); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create geometry shader, result: 0x%X.", result); } + + *outExecutable = new ShaderExecutable11(function, length, geometryShader); } break; default: UNREACHABLE(); - break; + return gl::Error(GL_INVALID_OPERATION); } - return executable; + return gl::Error(GL_NO_ERROR); } -ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround) +gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable) { const char *profileType = NULL; switch (type) { - case rx::SHADER_VERTEX: + case SHADER_VERTEX: profileType = "vs"; break; - case rx::SHADER_PIXEL: + case SHADER_PIXEL: profileType = "ps"; break; - case rx::SHADER_GEOMETRY: + case SHADER_GEOMETRY: profileType = "gs"; break; default: UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } - const char *profileVersion = NULL; + unsigned int profileMajorVersion = 0; + unsigned int profileMinorVersion = 0; + const char *profileSuffix = NULL; switch (mFeatureLevel) { case D3D_FEATURE_LEVEL_11_0: - profileVersion = "5_0"; + profileMajorVersion = 5; + profileMinorVersion = 0; break; case D3D_FEATURE_LEVEL_10_1: - profileVersion = "4_1"; + profileMajorVersion = 4; + profileMinorVersion = 1; break; case D3D_FEATURE_LEVEL_10_0: - profileVersion = "4_0"; + profileMajorVersion = 4; + profileMinorVersion = 0; break; case D3D_FEATURE_LEVEL_9_3: - profileVersion = "4_0_level_9_3"; + profileMajorVersion = 4; + profileMinorVersion = 0; + profileSuffix = "_level_9_3"; break; case D3D_FEATURE_LEVEL_9_2: - profileVersion = "4_0_level_9_2"; + profileMajorVersion = 4; + profileMinorVersion = 0; + profileSuffix = "_level_9_2"; break; case D3D_FEATURE_LEVEL_9_1: - profileVersion = "4_0_level_9_1"; + profileMajorVersion = 4; + profileMinorVersion = 0; + profileSuffix = "_level_9_1"; break; + break; default: UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } - char profile[32]; - snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion); + std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); + if (profileSuffix) + profile += profileSuffix; - UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0; + UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2; if (gl::perfActive()) { @@ -2464,44 +2559,51 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch #endif flags |= D3DCOMPILE_DEBUG; - - std::string sourcePath = getTempPath(); - std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL); - writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); } // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. // Try the default flags first and if compilation fails, try some alternatives. - const UINT extraFlags[] = - { - flags, - flags | D3DCOMPILE_SKIP_VALIDATION, - flags | D3DCOMPILE_SKIP_OPTIMIZATION - }; + std::vector configs; + configs.push_back(CompileConfig(flags, "default" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization")); - const static char *extraFlagNames[] = - { - "default", - "skip validation", - "skip optimization" - }; + D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} }; - int attempts = ArraySize(extraFlags); - - ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts); - if (!binary) + ID3DBlob *binary = NULL; + std::string debugInfo; + gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, &debugInfo); + if (error.isError()) { - return NULL; + return error; } - ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers); - SafeRelease(binary); + // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL + // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK. + if (!binary) + { + *outExectuable = NULL; + return gl::Error(GL_NO_ERROR); + } - return executable; + error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, + transformFeedbackVaryings, separatedOutputBuffers, outExectuable); + + SafeRelease(binary); + if (error.isError()) + { + return error; + } + + if (!debugInfo.empty()) + { + (*outExectuable)->appendDebugInfo(debugInfo); + } + + return gl::Error(GL_NO_ERROR); } -rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize) +UniformStorage *Renderer11::createUniformStorage(size_t storageSize) { return new UniformStorage11(this, storageSize); } @@ -2531,9 +2633,14 @@ QueryImpl *Renderer11::createQuery(GLenum type) return new Query11(this, type); } -FenceImpl *Renderer11::createFence() +FenceNVImpl *Renderer11::createFenceNV() { - return new Fence11(this); + return new FenceNV11(this); +} + +FenceSyncImpl *Renderer11::createFenceSync() +{ + return new FenceSync11(this); } TransformFeedbackImpl* Renderer11::createTransformFeedback() @@ -2576,82 +2683,77 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const return true; } -bool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { ASSERT(supportsFastCopyBufferToTexture(destinationFormat)); return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea); } -bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource) +gl::Error Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut) + { - ASSERT(colorbuffer != NULL); + ASSERT(colorbuffer); - RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); - if (renderTarget) + RenderTarget11 *renderTarget = NULL; + gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) { - *subresourceIndex = renderTarget->getSubresourceIndex(); - - ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView(); - if (colorBufferRTV) - { - ID3D11Resource *textureResource = NULL; - colorBufferRTV->GetResource(&textureResource); - - if (textureResource) - { - HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource); - SafeRelease(textureResource); - - if (SUCCEEDED(result)) - { - return true; - } - else - { - ERR("Failed to extract the ID3D11Texture2D from the render target resource, " - "HRESULT: 0x%X.", result); - } - } - } + return error; } - return false; + ID3D11Resource *renderTargetResource = renderTarget->getTexture(); + ASSERT(renderTargetResource); + + *subresourceIndexOut = renderTarget->getSubresourceIndex(); + *texture2DOut = d3d11::DynamicCastComObject(renderTargetResource); + + if (!(*texture2DOut)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget"); + } + + return gl::Error(GL_NO_ERROR); } -bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) +gl::Error Renderer11::blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, + const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, + bool blitDepth, bool blitStencil, GLenum filter) { if (blitRenderTarget) { gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer(); + ASSERT(readBuffer); - if (!readBuffer) + RenderTarget *readRenderTarget = NULL; + gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the read buffer from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } - - RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); + ASSERT(readRenderTarget); for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { if (drawTarget->isEnabledColorAttachment(colorAttachment)) { gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment); + ASSERT(drawBuffer); - if (!drawBuffer) + RenderTarget *drawRenderTarget = NULL; + error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the draw buffer from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(drawRenderTarget); - RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); - - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, - blitRenderTarget, false, false)) + error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget, + false, false); + if (error.isError()) { - return false; + return error; } } } @@ -2660,78 +2762,88 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read if (blitDepth || blitStencil) { gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer(); + ASSERT(readBuffer); + + RenderTarget *readRenderTarget = NULL; + gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(readRenderTarget); + gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer(); + ASSERT(drawBuffer); - if (!readBuffer) + RenderTarget *drawRenderTarget = NULL; + error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + if (error.isError()) { - ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return error; } + ASSERT(drawRenderTarget); - if (!drawBuffer) + error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false, + blitDepth, blitStencil); + if (error.isError()) { - ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); - RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); - ASSERT(readRenderTarget && drawRenderTarget); - - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, - false, blitDepth, blitStencil)) - { - return false; + return error; } } invalidateFramebufferSwizzles(drawTarget); - return true; + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, +gl::Error Renderer11::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ID3D11Texture2D *colorBufferTexture = NULL; unsigned int subresourceIndex = 0; gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); + ASSERT(colorbuffer); - if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) + gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture); + if (error.isError()) { - gl::Rectangle area; - area.x = x; - area.y = y; - area.width = width; - area.height = height; - - gl::Buffer *packBuffer = pack.pixelBuffer.get(); - if (packBuffer != NULL) - { - rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); - PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast(pixels)); - - gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); - if (error.isError()) - { - return error; - } - - packBuffer->getIndexRangeCache()->clear(); - } - else - { - gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); - if (error.isError()) - { - return error; - } - } - - SafeRelease(colorBufferTexture); + return error; } + gl::Rectangle area; + area.x = x; + area.y = y; + area.width = width; + area.height = height; + + gl::Buffer *packBuffer = pack.pixelBuffer.get(); + if (packBuffer != NULL) + { + Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); + PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast(pixels)); + + error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + if (error.isError()) + { + SafeRelease(colorBufferTexture); + return error; + } + + packBuffer->getIndexRangeCache()->clear(); + } + else + { + error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + if (error.isError()) + { + SafeRelease(colorBufferTexture); + return error; + } + } + + SafeRelease(colorBufferTexture); + return gl::Error(GL_NO_ERROR); } @@ -2740,11 +2852,11 @@ Image *Renderer11::createImage() return new Image11(); } -void Renderer11::generateMipmap(Image *dest, Image *src) +gl::Error Renderer11::generateMipmap(Image *dest, Image *src) { Image11 *dest11 = Image11::makeImage11(dest); Image11 *src11 = Image11::makeImage11(src); - Image11::generateMipmap(dest11, src11); + return Image11::generateMipmap(dest11, src11); } TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain) @@ -2788,6 +2900,19 @@ TextureImpl *Renderer11::createTexture(GLenum target) return NULL; } +RenderbufferImpl *Renderer11::createRenderbuffer() +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + return renderbuffer; +} + +RenderbufferImpl *Renderer11::createRenderbuffer(SwapChain *swapChain, bool depth) +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + renderbuffer->setStorage(swapChain, depth); + return renderbuffer; +} + gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { @@ -2882,22 +3007,25 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub SafeRelease(srcTex); PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0); - packPixels(stagingTex, packParams, pixels); + gl::Error error = packPixels(stagingTex, packParams, pixels); SafeRelease(stagingTex); - return gl::Error(GL_NO_ERROR); + return error; } -void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) +gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) { D3D11_TEXTURE2D_DESC textureDesc; readTexture->GetDesc(&textureDesc); D3D11_MAPPED_SUBRESOURCE mapping; HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping); - UNUSED_ASSERTION_VARIABLE(hr); - ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) + { + ASSERT(hr == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr); + } uint8_t *source; int inputPitch; @@ -2968,24 +3096,23 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams } mDeviceContext->Unmap(readTexture, 0); + + return gl::Error(GL_NO_ERROR); } -bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, - RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, - bool colorBlit, bool depthBlit, bool stencilBlit) +gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, + bool colorBlit, bool depthBlit, bool stencilBlit) { // Since blitRenderbufferRect is called for each render buffer that needs to be blitted, // it should never be the case that both color and depth/stencil need to be blitted at // at the same time. ASSERT(colorBlit != (depthBlit || stencilBlit)); - bool result = true; - RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); if (!drawRenderTarget) { - ERR("Failed to retrieve the draw render target from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer."); } ID3D11Resource *drawTexture = drawRenderTarget11->getTexture(); @@ -2996,8 +3123,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget); if (!readRenderTarget) { - ERR("Failed to retrieve the read render target from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer."); } ID3D11Resource *readTexture = NULL; @@ -3019,7 +3145,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R if (FAILED(hresult)) { SafeRelease(readTexture); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader resource view to resolve multisampled framebuffer."); } } } @@ -3036,8 +3162,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R { SafeRelease(readTexture); SafeRelease(readSRV); - ERR("Failed to retrieve the read render target view from the read render target."); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target."); } gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); @@ -3063,6 +3188,8 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat()); bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit); + gl::Error result(GL_NO_ERROR); + if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && (!(depthBlit || stencilBlit) || wholeBufferCopy)) @@ -3109,7 +3236,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0, readTexture, readSubresource, pSrcBox); - result = true; + result = gl::Error(GL_NO_ERROR); } else { @@ -3190,7 +3317,8 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta ASSERT(attachment->isTexture()); gl::Texture *texture = attachment->getTexture(); - TextureStorage *texStorage = texture->getNativeTexture(); + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + TextureStorage *texStorage = textureD3D->getNativeTexture(); if (texStorage) { TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage); @@ -3204,7 +3332,7 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta } } -void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer) +void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer) { for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) { @@ -3248,7 +3376,7 @@ bool Renderer11::getLUID(LUID *adapterLuid) const return true; } -rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { return d3d11::GetVertexFormatInfo(vertexFormat).conversionType; } @@ -3263,4 +3391,30 @@ void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureC d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions); } +Workarounds Renderer11::generateWorkarounds() const +{ + return d3d11::GenerateWorkarounds(); +} + +void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv) +{ + std::vector ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + ASSERT(static_cast(resourceSlot) < currentSRVs.size()); + + if (currentSRVs[resourceSlot] != srv) + { + if (shaderType == gl::SAMPLER_VERTEX) + { + mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv); + } + else + { + mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv); + } + + currentSRVs[resourceSlot] = srv; + } +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h index 2a53fa1672..d44bd2fd30 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h @@ -13,12 +13,14 @@ #include "libGLESv2/angletypes.h" #include "common/mathutil.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/d3d/HLSLCompiler.h" #include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h" #include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h" +#include "libGLESv2/renderer/d3d/HLSLCompiler.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/RenderTarget.h" +#include "libEGL/AttributeMap.h" + namespace gl { class FramebufferAttachment; @@ -33,6 +35,7 @@ class StreamingIndexBufferInterface; class Blit11; class Clear11; class PixelTransfer11; +class RenderTarget11; struct PackPixelsParams; enum @@ -41,10 +44,10 @@ enum MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024 }; -class Renderer11 : public Renderer +class Renderer11 : public RendererD3D { public: - Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay); + Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes); virtual ~Renderer11(); static Renderer11 *makeRenderer11(Renderer *renderer); @@ -55,19 +58,19 @@ class Renderer11 : public Renderer virtual int generateConfigs(ConfigDesc **configDescList); virtual void deleteConfigs(ConfigDesc *configDescList); - virtual void sync(bool block); + virtual gl::Error sync(bool block); - virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); virtual gl::Error generateSwizzle(gl::Texture *texture); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); - virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask); + gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask) override; virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, int stencilBackRef, bool frontFaceCCW); @@ -76,32 +79,32 @@ class Renderer11 : public Renderer bool ignoreViewport); virtual bool applyPrimitiveType(GLenum mode, GLsizei count); - virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer); + gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, bool rasterizerDiscard, bool transformFeedbackActive); - virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary); - virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances); + + virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector &uniformArray); + virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances); virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); + virtual void applyTransformFeedbackBuffers(const gl::State &state); virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override; virtual void markAllStateDirty(); // lost device - void notifyDeviceLost(); - virtual bool isDeviceLost(); - virtual bool testDeviceLost(bool notify); - virtual bool testDeviceResettable(); + void notifyDeviceLost() override; + bool isDeviceLost() override; + bool testDeviceLost(bool notify) override; + bool testDeviceResettable() override; - virtual DWORD getAdapterVendor() const; - virtual std::string getRendererDescription() const; - virtual GUID getAdapterIdentifier() const; + DWORD getAdapterVendor() const override; + std::string getRendererDescription() const override; + GUID getAdapterIdentifier() const override; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; @@ -115,47 +118,43 @@ class Renderer11 : public Renderer virtual int getMaxSwapInterval() const; // Pixel operations - virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source); - virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source); - virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source); - virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source); - - virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); - virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); - virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); - virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); + virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); - virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter); + gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) override; - virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); // RenderTarget creation - virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); + virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT); + virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT); // Shader creation - virtual ShaderImpl *createShader(GLenum type); + virtual ShaderImpl *createShader(const gl::Data &data, GLenum type); virtual ProgramImpl *createProgram(); // Shader operations - virtual void releaseShaderCompiler(); - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers); - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround); + void releaseShaderCompiler() override; + virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable); + virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable); virtual UniformStorage *createUniformStorage(size_t storageSize); // Image operations virtual Image *createImage(); - virtual void generateMipmap(Image *dest, Image *source); + gl::Error generateMipmap(Image *dest, Image *source) override; virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels); @@ -165,6 +164,10 @@ class Renderer11 : public Renderer // Texture creation virtual TextureImpl *createTexture(GLenum target); + // Renderbuffer creation + virtual RenderbufferImpl *createRenderbuffer(); + virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth); + // Buffer creation virtual BufferImpl *createBuffer(); virtual VertexBuffer *createVertexBuffer(); @@ -175,7 +178,8 @@ class Renderer11 : public Renderer // Query and Fence creation virtual QueryImpl *createQuery(GLenum type); - virtual FenceImpl *createFence(); + virtual FenceNVImpl *createFenceNV(); + virtual FenceSyncImpl *createFenceSync(); // Transform Feedback creation virtual TransformFeedbackImpl* createTransformFeedback(); @@ -183,48 +187,54 @@ class Renderer11 : public Renderer // D3D11-renderer specific methods ID3D11Device *getDevice() { return mDevice; } ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; - IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; + DXGIFactory *getDxgiFactory() { return mDxgiFactory; }; bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; } Blit11 *getBlitter() { return mBlit; } // Buffer-to-texture and Texture-to-buffer copies virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + + gl::Error getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut); - bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); void unapplyRenderTargets(); void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); - void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut); + gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut); virtual bool getLUID(LUID *adapterLuid) const; - virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; + virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; - private: - DISALLOW_COPY_AND_ASSIGN(Renderer11); - - virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const; - - gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); - gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); - bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, - RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, - bool colorBlit, bool depthBlit, bool stencilBlit); + void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv); + + private: + DISALLOW_COPY_AND_ASSIGN(Renderer11); + + void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override; + Workarounds generateWorkarounds() const override; + + gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); + + gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, + bool colorBlit, bool depthBlit, bool stencilBlit); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); + void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource); static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel); - static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer); + static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer); HMODULE mD3d11Module; HMODULE mDxgiModule; EGLNativeDisplayType mDc; - EGLint mRequestedDisplay; + std::vector mAvailableFeatureLevels; + D3D_DRIVER_TYPE mDriverType; HLSLCompiler mCompiler; @@ -243,7 +253,7 @@ class Renderer11 : public Renderer unsigned int mAppliedStencilbufferSerial; bool mDepthStencilInitialized; bool mRenderTargetDescInitialized; - rx::RenderTarget::Desc mRenderTargetDesc; + RenderTarget::Desc mRenderTargetDesc; // Currently applied sampler states std::vector mForceSetVertexSamplerStates; @@ -292,8 +302,14 @@ class Renderer11 : public Renderer unsigned int mAppliedIBOffset; // Currently applied transform feedback buffers - ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; - GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; + ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current D3D buffers + // in use for streamout + GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current GL-specified + // buffer offsets to transform feedback + // buffers + UINT mCurrentD3DOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the D3D buffer offsets, + // which may differ from GLs, due + // to different append behavior // Currently applied shaders ID3D11VertexShader *mAppliedVertexShader; @@ -339,7 +355,7 @@ class Renderer11 : public Renderer IDXGIAdapter *mDxgiAdapter; DXGI_ADAPTER_DESC mAdapterDescription; char mDescription[128]; - IDXGIFactory *mDxgiFactory; + DXGIFactory *mDxgiFactory; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp index 4b29be055d..52c8a81633 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp @@ -6,7 +6,6 @@ // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. -#include "common/platform.h" #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" @@ -16,12 +15,16 @@ #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h" +#include "common/features.h" +#include "common/NativeWindow.h" + namespace rx { -SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, +SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) + : mRenderer(renderer), + SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat) { mSwapChain = NULL; mBackBufferTexture = NULL; @@ -39,8 +42,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDL mPassThroughPS = NULL; mWidth = -1; mHeight = -1; - mViewportWidth = -1; - mViewportHeight = -1; + mRotateL = false; + mRotateR = false; mSwapInterval = 0; mAppCreatedShareHandle = mShareHandle != NULL; mPassThroughResourcesInit = false; @@ -91,11 +94,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(device != NULL); // D3D11 does not allow zero size textures - ASSERT(backbufferWidth >= 1); - ASSERT(backbufferHeight >= 1); + ASSERT(backbufferWidth != 0); + ASSERT(backbufferHeight != 0); // Preserve the render target content -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { @@ -137,8 +140,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; mOffscreenTexture->GetDesc(&offscreenTextureDesc); - if (offscreenTextureDesc.Width != (UINT)backbufferWidth || - offscreenTextureDesc.Height != (UINT)backbufferHeight || + if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) || + offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) || offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1) @@ -150,11 +153,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } else { - const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport(); + const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport(); D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; - offscreenTextureDesc.Width = backbufferWidth; - offscreenTextureDesc.Height = backbufferHeight; + offscreenTextureDesc.Width = abs(backbufferWidth); + offscreenTextureDesc.Height = abs(backbufferHeight); offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; @@ -234,8 +237,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei if (mDepthBufferFormat != GL_NONE) { D3D11_TEXTURE2D_DESC depthStencilTextureDesc; - depthStencilTextureDesc.Width = backbufferWidth; - depthStencilTextureDesc.Height = backbufferHeight; + depthStencilTextureDesc.Width = abs(backbufferWidth); + depthStencilTextureDesc.Height = abs(backbufferHeight); depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; @@ -286,12 +289,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei mWidth = backbufferWidth; mHeight = backbufferHeight; -#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP - mViewportWidth = backbufferWidth; - mViewportHeight = backbufferHeight; -#endif -#if !defined(ANGLE_PLATFORM_WINRT) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) if (previousOffscreenTexture != NULL) { D3D11_BOX sourceBox = {0}; @@ -310,7 +309,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei if (mSwapChain) { - swapRect(0, 0, mWidth, mHeight, SWAP_NORMAL); + swapRect(0, 0, mWidth, mHeight); } } #endif @@ -327,8 +326,16 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) return EGL_BAD_ACCESS; } + // Windows Phone works around the rotation limitation by using negative values for the swap chain size +#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape + mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape + backbufferWidth = abs(backbufferWidth); + backbufferHeight = abs(backbufferHeight); +#endif + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains - if (backbufferWidth < 1 || backbufferHeight < 1) + if (backbufferWidth == 0 || backbufferHeight == 0) { return EGL_SUCCESS; } @@ -336,19 +343,15 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) // Can only call resize if we have already created our swap buffer and resources ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView); +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); // Resize swap chain - HRESULT result; -#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP // Windows phone swap chain is never resized, only the texture is -#if !defined(ANGLE_PLATFORM_WINRT) - const int bufferCount = 1; -#else - const int bufferCount = 2; -#endif + DXGI_SWAP_CHAIN_DESC desc; + mSwapChain->GetDesc(&desc); const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); - result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); + HRESULT result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); if (FAILED(result)) { @@ -364,7 +367,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) return EGL_BAD_ALLOC; } } -#endif result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); @@ -379,6 +381,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) { d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); } +#endif return resetOffscreenTexture(backbufferWidth, backbufferHeight); } @@ -412,62 +415,14 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap return EGL_SUCCESS; } - if (mWindow) + if (mNativeWindow.getNativeWindow()) { const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); - IDXGIFactory *factory = mRenderer->getDxgiFactory(); + HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(), + backbufferFormatInfo.texFormat, + backbufferWidth, backbufferHeight, &mSwapChain); -#if !defined(ANGLE_PLATFORM_WINRT) - DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; - swapChainDesc.BufferDesc.Width = backbufferWidth; - swapChainDesc.BufferDesc.Height = backbufferHeight; - swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; - swapChainDesc.BufferDesc.Format = backbufferFormatInfo.texFormat; - swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 1; - swapChainDesc.OutputWindow = mWindow; - swapChainDesc.Windowed = TRUE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - swapChainDesc.Flags = 0; - - HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain); -#else - IDXGIFactory2 *factory2; - HRESULT result = factory->QueryInterface(IID_PPV_ARGS(&factory2)); - ASSERT(SUCCEEDED(result)); - - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; - swapChainDesc.Width = 0; - swapChainDesc.Height = 0; - swapChainDesc.Format = backbufferFormatInfo.texFormat; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.Stereo = FALSE; - swapChainDesc.Flags = 0; -#if WINAPI_FAMILY==WINAPI_FAMILY_PC_APP - swapChainDesc.Scaling = DXGI_SCALING_NONE; - swapChainDesc.BufferCount = 2; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; -#elif WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - swapChainDesc.BufferCount = 1; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; -#endif - - IDXGISwapChain1 *swapChain; - result = factory2->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain); - mSwapChain = swapChain; - HRESULT hr = swapChain->GetDesc1(&swapChainDesc); - ASSERT(SUCCEEDED(hr)); - mViewportWidth = swapChainDesc.Width; - mViewportHeight = swapChainDesc.Height; -#endif if (FAILED(result)) { ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); @@ -537,7 +492,7 @@ void SwapChain11::initPassThroughResources() samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; samplerDesc.MinLOD = 0; - samplerDesc.MaxLOD = FLT_MAX; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); ASSERT(SUCCEEDED(result)); @@ -563,7 +518,7 @@ void SwapChain11::initPassThroughResources() } // parameters should be validated/clamped by caller -EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) +EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { @@ -573,16 +528,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - // Set vertices - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - return EGL_BAD_ACCESS; - } - - d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); - // Create a quad in homogeneous coordinates float x1 = (x / float(mWidth)) * 2.0f - 1.0f; float y1 = (y / float(mHeight)) * 2.0f - 1.0f; @@ -594,8 +539,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG float u2 = (x + width) / float(mWidth); float v2 = (y + height) / float(mHeight); - const int rotateL = flags & SWAP_ROTATE_90; - const int rotateR = flags & SWAP_ROTATE_270; + const bool rotateL = mRotateL; + const bool rotateR = mRotateR; + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return EGL_BAD_ACCESS; + } + + d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1); d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2); @@ -628,22 +583,23 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG // Set the viewport D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = mViewportWidth; - viewport.Height = mViewportHeight; + viewport.TopLeftX = 0.0f; + viewport.TopLeftY = 0.0f; + const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR); + viewport.Width = FLOAT(invertViewport ? mHeight : mWidth); + viewport.Height = FLOAT(invertViewport ? mWidth : mHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); // Apply textures - deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); // Draw deviceContext->Draw(4, 0); -#ifdef ANGLE_FORCE_VSYNC_OFF +#if ANGLE_VSYNC == ANGLE_DISABLED result = mSwapChain->Present(0, 0); #else result = mSwapChain->Present(mSwapInterval, 0); @@ -667,8 +623,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG } // Unbind - static ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); + mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); mRenderer->unapplyRenderTargets(); mRenderer->markAllStateDirty(); @@ -708,8 +663,8 @@ ID3D11Texture2D *SwapChain11::getDepthStencilTexture() SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain) { - ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain)); - return static_cast(swapChain); + ASSERT(HAS_DYNAMIC_TYPE(SwapChain11*, swapChain)); + return static_cast(swapChain); } void SwapChain11::recreate() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h index b30b78568a..77509edcd3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h @@ -19,13 +19,13 @@ class Renderer11; class SwapChain11 : public SwapChain { public: - SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, + SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); virtual ~SwapChain11(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags); + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); virtual void recreate(); virtual ID3D11Texture2D *getOffscreenTexture(); @@ -52,13 +52,13 @@ class SwapChain11 : public SwapChain Renderer11 *mRenderer; EGLint mHeight; EGLint mWidth; - EGLint mViewportWidth; - EGLint mViewportHeight; + bool mRotateL; + bool mRotateR; bool mAppCreatedShareHandle; unsigned int mSwapInterval; bool mPassThroughResourcesInit; - IDXGISwapChain *mSwapChain; + DXGISwapChain *mSwapChain; ID3D11Texture2D *mBackBufferTexture; ID3D11RenderTargetView *mBackBufferRTView; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp index 91e7147da6..74af27e8b3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp @@ -8,6 +8,9 @@ // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" + +#include + #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" @@ -15,6 +18,7 @@ #include "libGLESv2/renderer/d3d/d3d11/Blit11.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d/MemoryBuffer.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/main.h" #include "libGLESv2/ImageIndex.h" @@ -52,46 +56,16 @@ TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle) { } -bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const +bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const { - return baseLevel == rhs.baseLevel && - mipLevels == rhs.mipLevels && - swizzle == rhs.swizzle; + return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle); } -TextureStorage11::SRVCache::~SRVCache() -{ - for (size_t i = 0; i < cache.size(); i++) - { - SafeRelease(cache[i].srv); - } -} - -ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const -{ - for (size_t i = 0; i < cache.size(); i++) - { - if (cache[i].key == key) - { - return cache[i].srv; - } - } - - return NULL; -} - -ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv) -{ - SRVPair pair = {key, srv}; - cache.push_back(pair); - - return srv; -} - -TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags) +TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags) : mBindFlags(bindFlags), mTopLevel(0), mMipLevels(0), + mInternalFormat(GL_NONE), mTextureFormat(DXGI_FORMAT_UNKNOWN), mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), @@ -114,6 +88,12 @@ TextureStorage11::~TextureStorage11() { SafeRelease(mLevelSRVs[level]); } + + for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++) + { + SafeRelease(i->second); + } + mSrvCache.clear(); } TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage) @@ -183,17 +163,16 @@ int TextureStorage11::getLevelDepth(int mipLevel) const return std::max(static_cast(mTextureDepth) >> mipLevel, 1); } -UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const +UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const { - UINT index = 0; - if (getResource()) - { - index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels); - } - return index; + UINT mipSlice = static_cast(index.mipIndex + mTopLevel); + UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); + UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); + ASSERT(subresource != std::numeric_limits::max()); + return subresource; } -ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState) +gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV) { bool swizzleRequired = samplerState.swizzleRequired(); bool mipmapping = gl::IsMipmapFiltered(samplerState); @@ -206,38 +185,71 @@ ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &sampl { verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha); } - + SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired); - ID3D11ShaderResourceView *srv = srvCache.find(key); - - if(srv) + SRVCache::const_iterator iter = mSrvCache.find(key); + if (iter != mSrvCache.end()) { - return srv; - } - - DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat); - ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource(); - - srv = createSRV(samplerState.baseLevel, mipLevels, format, texture); - - return srvCache.add(key, srv); -} - -ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel) -{ - if (mipLevel >= 0 && mipLevel < getLevelCount()) - { - if (!mLevelSRVs[mipLevel]) - { - mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource()); - } - - return mLevelSRVs[mipLevel]; + *outSRV = iter->second; } else { - return NULL; + ID3D11Resource *texture = NULL; + if (swizzleRequired) + { + gl::Error error = getSwizzleTexture(&texture); + if (error.isError()) + { + return error; + } + } + else + { + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } + } + + ID3D11ShaderResourceView *srv = NULL; + DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat); + gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv); + if (error.isError()) + { + return error; + } + + mSrvCache.insert(std::make_pair(key, srv)); + *outSRV = srv; } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + if (!mLevelSRVs[mipLevel]) + { + ID3D11Resource *resource = NULL; + gl::Error error = getResource(&resource); + if (error.isError()) + { + return error; + } + + error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]); + if (error.isError()) + { + return error; + } + } + + *outSRV = mLevelSRVs[mipLevel]; + + return gl::Error(GL_NO_ERROR); } gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) @@ -249,14 +261,25 @@ gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGr if (mSwizzleCache[level] != swizzleTarget) { // Need to re-render the swizzle for this level - ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level); - ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level); + ID3D11ShaderResourceView *sourceSRV = NULL; + gl::Error error = getSRVLevel(level, &sourceSRV); + if (error.isError()) + { + return error; + } + + ID3D11RenderTargetView *destRTV = NULL; + error = getSwizzleRenderTarget(level, &destRTV); + if (error.isError()) + { + return error; + } gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); Blit11 *blitter = mRenderer->getBlitter(); - gl::Error error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); + error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); if (error.isError()) { return error; @@ -287,104 +310,120 @@ void TextureStorage11::invalidateSwizzleCache() } } -bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource, - int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth) +gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource, + const gl::ImageIndex &index, const gl::Box ©Area) { - if (srcTexture) + ASSERT(srcTexture); + + GLint level = index.mipIndex; + + invalidateSwizzleCacheLevel(level); + + gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); + + bool fullCopy = copyArea.x == 0 && + copyArea.y == 0 && + copyArea.z == 0 && + copyArea.width == texSize.width && + copyArea.height == texSize.height && + copyArea.depth == texSize.depth; + + ID3D11Resource *dstTexture = NULL; + gl::Error error = getResource(&dstTexture); + if (error.isError()) { - invalidateSwizzleCacheLevel(level); - - gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); - gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth); - - bool fullCopy = copyArea.x == 0 && - copyArea.y == 0 && - copyArea.z == 0 && - copyArea.width == texSize.width && - copyArea.height == texSize.height && - copyArea.depth == texSize.depth; - - ID3D11Resource *dstTexture = getResource(); - unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget); - - ASSERT(dstTexture); - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0)) - { - // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead - Blit11 *blitter = mRenderer->getBlitter(); - - return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, - dstTexture, dstSubresource, copyArea, texSize, - NULL); - } - else - { - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - - D3D11_BOX srcBox; - srcBox.left = copyArea.x; - srcBox.top = copyArea.y; - srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth); - srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight); - srcBox.front = copyArea.z; - srcBox.back = copyArea.z + copyArea.depth; - - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z, - srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox); - return true; - } + return error; } - return false; -} + unsigned int dstSubresource = getSubresourceIndex(index); -bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, - int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth) -{ - if (dstTexture) + ASSERT(dstTexture); + + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0)) { - ID3D11Resource *srcTexture = getResource(); - unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget); + // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead + Blit11 *blitter = mRenderer->getBlitter(); - ASSERT(srcTexture); + return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, + dstTexture, dstSubresource, copyArea, texSize, + NULL); + } + else + { + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); + + D3D11_BOX srcBox; + srcBox.left = copyArea.x; + srcBox.top = copyArea.y; + srcBox.right = copyArea.x + roundUp(static_cast(copyArea.width), dxgiFormatInfo.blockWidth); + srcBox.bottom = copyArea.y + roundUp(static_cast(copyArea.height), dxgiFormatInfo.blockHeight); + srcBox.front = copyArea.z; + srcBox.back = copyArea.z + copyArea.depth; ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset, - srcTexture, srcSubresource, NULL); - return true; + context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z, + srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox); + return gl::Error(GL_NO_ERROR); } - - return false; } -void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) +gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, + const gl::ImageIndex &index, const gl::Box ®ion) { - if (source && dest) + ASSERT(dstTexture); + + ID3D11Resource *srcTexture = NULL; + gl::Error error = getResource(&srcTexture); + if (error.isError()) { - ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView(); - ID3D11RenderTargetView *destRTV = dest->getRenderTargetView(); - - if (sourceSRV && destRTV) - { - gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); - gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); - - gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth()); - gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); - - Blit11 *blitter = mRenderer->getBlitter(); - - blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, - gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR); - } + return error; } + + ASSERT(srcTexture); + + unsigned int srcSubresource = getSubresourceIndex(index); + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z, + srcTexture, srcSubresource, NULL); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +{ + ASSERT(sourceIndex.layerIndex == destIndex.layerIndex); + + invalidateSwizzleCacheLevel(destIndex.mipIndex); + + RenderTarget *source = NULL; + gl::Error error = getRenderTarget(sourceIndex, &source); + if (error.isError()) + { + return error; + } + + RenderTarget *dest = NULL; + error = getRenderTarget(destIndex, &dest); + if (error.isError()) + { + return error; + } + + ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView(); + ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView(); + + gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); + gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); + + gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth()); + gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); + + Blit11 *blitter = mRenderer->getBlitter(); + return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, + gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR); } void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) @@ -396,7 +435,112 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree } } -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) +gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) +{ + ASSERT(destStorage); + + ID3D11Resource *sourceResouce = NULL; + gl::Error error = getResource(&sourceResouce); + if (error.isError()) + { + return error; + } + + TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage); + ID3D11Resource *destResource = NULL; + error = dest11->getResource(&destResource); + if (error.isError()) + { + return error; + } + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + immediateContext->CopyResource(destResource, sourceResouce); + + dest11->invalidateSwizzleCache(); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type, + const gl::PixelUnpackState &unpack, const uint8_t *pixelData) +{ + ID3D11Resource *resource = NULL; + gl::Error error = getResource(&resource); + if (error.isError()) + { + return error; + } + ASSERT(resource); + + UINT destSubresource = getSubresourceIndex(index); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat()); + + bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth)); + ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate); + + // TODO(jmadill): Handle compressed formats + // Compressed formats have different load syntax, so we'll have to handle them with slightly + // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData + // with compressed formats in the calling logic. + ASSERT(!internalFormatInfo.compressed); + + int width = destBox ? destBox->width : static_cast(image->getWidth()); + int height = destBox ? destBox->height : static_cast(image->getHeight()); + int depth = destBox ? destBox->depth : static_cast(image->getDepth()); + UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment); + UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment); + + const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat()); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat); + + size_t outputPixelSize = dxgiFormatInfo.pixelBytes; + + UINT bufferRowPitch = outputPixelSize * width; + UINT bufferDepthPitch = bufferRowPitch * height; + + MemoryBuffer conversionBuffer; + if (!conversionBuffer.resize(bufferDepthPitch * depth)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer."); + } + + // TODO: fast path + LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type); + loadFunction(width, height, depth, + pixelData, srcRowPitch, srcDepthPitch, + conversionBuffer.data(), bufferRowPitch, bufferDepthPitch); + + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + + if (!fullUpdate) + { + ASSERT(destBox); + + D3D11_BOX destD3DBox; + destD3DBox.left = destBox->x; + destD3DBox.right = destBox->x + destBox->width; + destD3DBox.top = destBox->y; + destD3DBox.bottom = destBox->y + destBox->height; + destD3DBox.front = 0; + destD3DBox.back = 1; + + immediateContext->UpdateSubresource(resource, destSubresource, + &destD3DBox, conversionBuffer.data(), + bufferRowPitch, bufferDepthPitch); + } + else + { + immediateContext->UpdateSubresource(resource, destSubresource, + NULL, conversionBuffer.data(), + bufferRowPitch, bufferDepthPitch); + } + + return gl::Error(GL_NO_ERROR); +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain) : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE), mTexture(swapchain->getOffscreenTexture()), mSwizzleTexture(NULL) @@ -418,6 +562,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch mTextureHeight = texDesc.Height; mTextureDepth = 1; + mInternalFormat = swapchain->GetBackBufferInternalFormat(); + ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource(); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srv->GetDesc(&srvDesc); @@ -439,7 +585,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch initializeSerials(1, 1); } -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)), mTexture(NULL), mSwizzleTexture(NULL) @@ -451,6 +597,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform mSwizzleRenderTargets[i] = NULL; } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -460,51 +608,11 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - // if the width or height is not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (width > 0 && height > 0) - { - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; // Compressed texture size constraints? - desc.Height = height; - desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0); - desc.ArraySize = 1; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = 1; - } - } + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = 1; initializeSerials(getLevelCount(), 1); } @@ -521,7 +629,11 @@ TextureStorage11_2D::~TextureStorage11_2D() if (imageAssociationCorrect) { // We must let the Images recover their data before we delete it from the TextureStorage. - mAssociatedImages[i]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage(); + if (error.isError()) + { + // TODO: Find a way to report this back to the context + } } } } @@ -542,8 +654,10 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage return static_cast(storage); } -void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -552,8 +666,10 @@ void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTar } } -bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { // This validation check should never return false. It means the Image/TextureStorage association is broken. @@ -566,8 +682,10 @@ bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Ima } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -582,8 +700,10 @@ void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* } // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -599,137 +719,168 @@ void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Ima { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[level]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_2D::getResource() const +gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource) { - return mTexture; + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; + desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels; + desc.ArraySize = 1; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { ASSERT(!index.hasLayer()); int level = index.mipIndex; + ASSERT(level >= 0 && level < getLevelCount()); - if (level >= 0 && level < getLevelCount()) + if (!mRenderTarget[level]) { - if (!mRenderTarget[level]) + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) { - ID3D11ShaderResourceView *srv = getSRVLevel(level); - if (!srv) - { - return NULL; - } - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = mTopLevel + level; - - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = mTopLevel + level; - dsvDesc.Flags = 0; - - ID3D11DepthStencilView *dsv; - HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); - - // RenderTarget will take ownership of these resources - SafeRelease(dsv); - } - else - { - UNREACHABLE(); - } + return error; } - return mRenderTarget[level]; - } - else - { - return NULL; + ID3D11ShaderResourceView *srv = NULL; + error = getSRVLevel(level, &srv); + if (error.isError()) + { + return error; + } + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; + + ID3D11RenderTargetView *rtv; + HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + } + + mRenderTarget[level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mDepthStencilFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = mTopLevel + level; + dsvDesc.Flags = 0; + + ID3D11DepthStencilView *dsv; + HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); + } + + mRenderTarget[level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + } + else + { + UNREACHABLE(); + } } + + ASSERT(outRT); + *outRT = mRenderTarget[level]; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; - srvDesc.Texture2D.MipLevels = mipLevels; - - ID3D11ShaderResourceView *SRV = NULL; + srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels; ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -void TextureStorage11_2D::generateMipmaps() +gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture) { - // Base level must already be defined + ASSERT(outTexture); - for (int level = 1; level < getLevelCount(); level++) - { - invalidateSwizzleCacheLevel(level); - - gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1); - gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level); - - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - - generateMipmapLayer(source, dest); - } -} - -ID3D11Resource *TextureStorage11_2D::getSwizzleTexture() -{ if (!mSwizzleTexture) { ID3D11Device *device = mRenderer->getDevice(); @@ -749,52 +900,52 @@ ID3D11Resource *TextureStorage11_2D::getSwizzleTexture() HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; - - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); + return error; } - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + } } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } -TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) +TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) { mTexture = NULL; @@ -803,13 +954,15 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { mSwizzleRenderTargets[level] = NULL; - for (unsigned int face = 0; face < 6; face++) + for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { mAssociatedImages[face][level] = NULL; mRenderTarget[face][level] = NULL; } } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -819,56 +972,23 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - // if the size is not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (size > 0) - { - // adjust size if needed for compressed textures - int height = size; - d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); + // adjust size if needed for compressed textures + int height = size; + d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); - ID3D11Device *device = mRenderer->getDevice(); + mMipLevels = mTopLevel + levels; + mTextureWidth = size; + mTextureHeight = size; + mTextureDepth = 1; - D3D11_TEXTURE2D_DESC desc; - desc.Width = size; - desc.Height = size; - desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); - desc.ArraySize = 6; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = 1; - } - } - - initializeSerials(getLevelCount() * 6, 6); + initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT); } - TextureStorage11_Cube::~TextureStorage11_Cube() { for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - for (unsigned int face = 0; face < 6; face++) + for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { if (mAssociatedImages[face][level] != NULL) { @@ -890,7 +1010,7 @@ TextureStorage11_Cube::~TextureStorage11_Cube() for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { SafeRelease(mSwizzleRenderTargets[level]); - for (unsigned int face = 0; face < 6; face++) + for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { SafeDelete(mRenderTarget[face][level]); } @@ -903,25 +1023,31 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS return static_cast(storage); } -void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < 6); + ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { mAssociatedImages[layerTarget][level] = image; } } } -bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { // This validation check should never return false. It means the Image/TextureStorage association is broken. bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage); @@ -934,14 +1060,17 @@ bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, I } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < 6); + ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); @@ -954,14 +1083,17 @@ void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image1 } // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < 6); + ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) { - if (0 <= layerTarget && layerTarget < 6) + if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { // No need to let the old Image recover its data, if it is also the incoming Image. if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage) @@ -974,114 +1106,165 @@ void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, I { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_Cube::getResource() const +gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource) { - return mTexture; + // if the size is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = CUBE_FACE_COUNT; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { int faceIndex = index.layerIndex; int level = index.mipIndex; - if (level >= 0 && level < getLevelCount()) + ASSERT(level >= 0 && level < getLevelCount()); + ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT); + + if (!mRenderTarget[faceIndex][level]) { - if (!mRenderTarget[faceIndex][level]) + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = faceIndex; - srvDesc.Texture2DArray.ArraySize = 1; - - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; - rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; - rtvDesc.Texture2DArray.ArraySize = 1; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - SafeRelease(srv); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Flags = 0; - dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; - dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; - dsvDesc.Texture2DArray.ArraySize = 1; - - ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1); - - // RenderTarget will take ownership of these resources - SafeRelease(dsv); - SafeRelease(srv); - } - else - { - UNREACHABLE(); - } + return error; } - return mRenderTarget[faceIndex][level]; - } - else - { - return NULL; + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = faceIndex; + srvDesc.Texture2DArray.ArraySize = 1; + + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(texture, &srvDesc, &srv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); + } + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; + rtvDesc.Texture2DArray.ArraySize = 1; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + } + + mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + SafeRelease(srv); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mDepthStencilFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Flags = 0; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; + dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; + dsvDesc.Texture2DArray.ArraySize = 1; + + ID3D11DepthStencilView *dsv; + result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); + } + + mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + SafeRelease(srv); + } + else + { + UNREACHABLE(); + } } + + ASSERT(outRT); + *outRT = mRenderTarget[faceIndex][level]; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; @@ -1093,7 +1276,7 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; srvDesc.Texture2DArray.MipLevels = 1; srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = 6; + srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; } else { @@ -1102,43 +1285,22 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel; } - ID3D11ShaderResourceView *SRV = NULL; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -void TextureStorage11_Cube::generateMipmaps() +gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture) { - // Base level must already be defined + ASSERT(outTexture); - for (int faceIndex = 0; faceIndex < 6; faceIndex++) - { - for (int level = 1; level < getLevelCount(); level++) - { - invalidateSwizzleCacheLevel(level); - - gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1); - gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level); - - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - - generateMipmapLayer(source, dest); - } - } -} - -ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() -{ if (!mSwizzleTexture) { ID3D11Device *device = mRenderer->getDevice(); @@ -1147,7 +1309,7 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() desc.Width = mTextureWidth; desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; - desc.ArraySize = 6; + desc.ArraySize = CUBE_FACE_COUNT; desc.Format = mSwizzleTextureFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; @@ -1158,55 +1320,54 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture() HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = 6; - - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); + return error; } - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + } } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } -TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget, +TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) { @@ -1220,6 +1381,8 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform mSwizzleRenderTargets[i] = NULL; } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -1229,49 +1392,13 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - // If the width, height or depth are not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (width > 0 && height > 0 && depth > 0) - { - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE3D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.Depth = depth; - desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); - desc.Format = mTextureFormat; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = desc.Depth; - } - } + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; initializeSerials(getLevelCount() * depth, depth); } @@ -1315,8 +1442,10 @@ TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage return static_cast(storage); } -void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -1325,8 +1454,10 @@ void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTar } } -bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { // This validation check should never return false. It means the Image/TextureStorage association is broken. @@ -1339,8 +1470,10 @@ bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Ima } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -1355,8 +1488,10 @@ void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* } // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) @@ -1372,148 +1507,188 @@ void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Ima { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[level]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_3D::getResource() const +gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource) { - return mTexture; + // If the width, height or depth are not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE3D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = mTextureFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { + ASSERT(outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; srvDesc.Texture3D.MostDetailedMip = baseLevel; srvDesc.Texture3D.MipLevels = mipLevels; - ID3D11ShaderResourceView *SRV = NULL; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { int mipLevel = index.mipIndex; + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); + + if (!index.hasLayer()) { - ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); - - if (!index.hasLayer()) + if (!mLevelRenderTargets[mipLevel]) { - if (!mLevelRenderTargets[mipLevel]) + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) { - ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel); - if (!srv) - { - return NULL; - } - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = -1; - - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel)); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); + return error; } - return mLevelRenderTargets[mipLevel]; - } - else - { - int layer = index.layerIndex; - - LevelLayerKey key(mipLevel, layer); - if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + ID3D11ShaderResourceView *srv = NULL; + error = getSRVLevel(mipLevel, &srv); + if (error.isError()) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + return error; + } - // TODO, what kind of SRV is expected here? - ID3D11ShaderResourceView *srv = NULL; + ID3D11Device *device = mRenderer->getDevice(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture3D.FirstWSlice = layer; - rtvDesc.Texture3D.WSize = 1; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = -1; - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + ID3D11RenderTargetView *rtv; + HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - return mLevelLayerRenderTargets[key]; + mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); } + + ASSERT(outRT); + *outRT = mLevelRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } - - return NULL; -} - -void TextureStorage11_3D::generateMipmaps() -{ - // Base level must already be defined - - for (int level = 1; level < getLevelCount(); level++) + else { - invalidateSwizzleCacheLevel(level); + int layer = index.layerIndex; - gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1); - gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level); + LevelLayerKey key(mipLevel, layer); + if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } - generateMipmapLayer(source, dest); + // TODO, what kind of SRV is expected here? + ID3D11ShaderResourceView *srv = NULL; + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = layer; + rtvDesc.Texture3D.WSize = 1; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + } + ASSERT(SUCCEEDED(result)); + + mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + } + + ASSERT(outRT); + *outRT = mLevelLayerRenderTargets[key]; + return gl::Error(GL_NO_ERROR); } } -ID3D11Resource *TextureStorage11_3D::getSwizzleTexture() +gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture) { + ASSERT(outTexture); + if (!mSwizzleTexture) { ID3D11Device *device = mRenderer->getDevice(); @@ -1531,55 +1706,54 @@ ID3D11Resource *TextureStorage11_3D::getSwizzleTexture() HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = -1; - - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); + return error; } - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = -1; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + } } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } -TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, +TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)) { @@ -1591,6 +1765,8 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in mSwizzleRenderTargets[level] = NULL; } + mInternalFormat = internalformat; + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat); mTextureFormat = formatInfo.texFormat; mShaderResourceFormat = formatInfo.srvFormat; @@ -1600,51 +1776,13 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - // if the width, height or depth is not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (width > 0 && height > 0 && depth > 0) - { - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); - desc.ArraySize = depth; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - mTextureDepth = desc.ArraySize; - } - } + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; initializeSerials(getLevelCount() * depth, depth); } @@ -1685,8 +1823,11 @@ TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray return static_cast(storage); } -void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget) +void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + ASSERT(0 <= level && level < getLevelCount()); if (0 <= level && level < getLevelCount()) @@ -1696,8 +1837,11 @@ void TextureStorage11_2DArray::associateImage(Image11* image, int level, int lay } } -bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) +bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + LevelLayerKey key(level, layerTarget); // This validation check should never return false. It means the Image/TextureStorage association is broken. @@ -1707,8 +1851,11 @@ bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage) +void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + LevelLayerKey key(level, layerTarget); bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); @@ -1721,8 +1868,11 @@ void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Ima } // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) +gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) { + GLint level = index.mipIndex; + GLint layerTarget = index.layerIndex; + LevelLayerKey key(level, layerTarget); ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end()); @@ -1739,18 +1889,62 @@ void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget { // Force the image to recover from storage before its data is overwritten. // This will reset mAssociatedImages[level] to NULL too. - mAssociatedImages[key]->recoverFromAssociatedStorage(); + gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage(); + if (error.isError()) + { + return error; + } } } } + + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_2DArray::getResource() const +gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource) { - return mTexture; + // if the width, height or depth is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + { + ASSERT(mMipLevels > 0); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); + } + } + + *outResource = mTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) +gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; @@ -1760,112 +1954,94 @@ ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.ArraySize = mTextureDepth; - ID3D11ShaderResourceView *SRV = NULL; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); - return SRV; + return gl::Error(GL_NO_ERROR); } -RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index) +gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { ASSERT(index.hasLayer()); int mipLevel = index.mipIndex; int layer = index.layerIndex; - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + + LevelLayerKey key(mipLevel, layer); + if (mRenderTargets.find(key) == mRenderTargets.end()) { - LevelLayerKey key(mipLevel, layer); - if (mRenderTargets.find(key) == mRenderTargets.end()) + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + ID3D11Resource *texture = NULL; + gl::Error error = getResource(&texture); + if (error.isError()) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + return error; + } - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = layer; - srvDesc.Texture2DArray.ArraySize = 1; + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = layer; + srvDesc.Texture2DArray.ArraySize = 1; - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(texture, &srvDesc, &srv); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); + } + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = layer; + rtvDesc.Texture2DArray.ArraySize = 1; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture2DArray.FirstArraySlice = layer; - rtvDesc.Texture2DArray.ArraySize = 1; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - SafeRelease(srv); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); } - else - { - UNREACHABLE(); - } + + mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + SafeRelease(srv); } - - return mRenderTargets[key]; - } - else - { - return NULL; - } -} - -void TextureStorage11_2DArray::generateMipmaps() -{ - // Base level must already be defined - - for (int level = 0; level < getLevelCount(); level++) - { - invalidateSwizzleCacheLevel(level); - for (unsigned int layer = 0; layer < mTextureDepth; layer++) + else { - gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer); - gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer); - - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex)); - - generateMipmapLayer(source, dest); + UNREACHABLE(); } } + + ASSERT(outRT); + *outRT = mRenderTargets[key]; + return gl::Error(GL_NO_ERROR); } -ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture() +gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture) { if (!mSwizzleTexture) { @@ -1886,52 +2062,51 @@ ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture() HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - if (result == E_OUTOFMEMORY) + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); } - ASSERT(SUCCEEDED(result)); } - return mSwizzleTexture; + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); } -ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel) +gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) { - if (mipLevel >= 0 && mipLevel < getLevelCount()) + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) { - if (!mSwizzleRenderTargets[mipLevel]) + ID3D11Resource *swizzleTexture = NULL; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) { - ID3D11Resource *swizzleTexture = getSwizzleTexture(); - if (!swizzleTexture) - { - return NULL; - } - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = mTextureDepth; - - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); + return error; } - return mSwizzleRenderTargets[mipLevel]; - } - else - { - return NULL; + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = mTextureDepth; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + } } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h index 9d63b2699d..930300a63d 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h @@ -25,7 +25,6 @@ namespace rx { class RenderTarget; class RenderTarget11; -class Renderer; class Renderer11; class SwapChain11; class Image11; @@ -41,47 +40,49 @@ class TextureStorage11 : public TextureStorage UINT getBindFlags() const; - virtual ID3D11Resource *getResource() const = 0; - virtual ID3D11ShaderResourceView *getSRV(const gl::SamplerState &samplerState); - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; + virtual gl::Error getResource(ID3D11Resource **outResource) = 0; + virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0; - virtual void generateMipmaps() = 0; + virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); virtual int getTopLevel() const; virtual bool isRenderTarget() const; virtual bool isManaged() const; virtual int getLevelCount() const; - UINT getSubresourceIndex(int mipLevel, int layerTarget) const; + UINT getSubresourceIndex(const gl::ImageIndex &index) const; gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); void invalidateSwizzleCacheLevel(int mipLevel); void invalidateSwizzleCache(); - bool updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, int level, - int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth); + gl::Error updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, + const gl::ImageIndex &index, const gl::Box ©Area); - bool copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, int level, - int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth); + gl::Error copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, + const gl::ImageIndex &index, const gl::Box ®ion); - virtual void associateImage(Image11* image, int level, int layerTarget) = 0; - virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage) = 0; - virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) = 0; - virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0; + virtual void associateImage(Image11* image, const gl::ImageIndex &index) = 0; + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) = 0; + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) = 0; + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) = 0; + + virtual gl::Error copyToStorage(TextureStorage *destStorage); + virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type, + const gl::PixelUnpackState &unpack, const uint8_t *pixelData); protected: - TextureStorage11(Renderer *renderer, UINT bindFlags); - void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); + TextureStorage11(Renderer11 *renderer, UINT bindFlags); int getLevelWidth(int mipLevel) const; int getLevelHeight(int mipLevel) const; int getLevelDepth(int mipLevel) const; - virtual ID3D11Resource *getSwizzleTexture() = 0; - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel) = 0; - ID3D11ShaderResourceView *getSRVLevel(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0; + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0; + gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) = 0; + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const = 0; void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); @@ -89,6 +90,7 @@ class TextureStorage11 : public TextureStorage int mTopLevel; unsigned int mMipLevels; + GLenum mInternalFormat; DXGI_FORMAT mTextureFormat; DXGI_FORMAT mShaderResourceFormat; DXGI_FORMAT mRenderTargetFormat; @@ -115,69 +117,53 @@ class TextureStorage11 : public TextureStorage }; SwizzleCacheValue mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - struct SRVKey - { - SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false); - - bool operator==(const SRVKey &rhs) const; - - int baseLevel; - int mipLevels; - bool swizzle; - }; - - struct SRVPair - { - SRVKey key; - ID3D11ShaderResourceView *srv; - }; - - struct SRVCache - { - ~SRVCache(); - - ID3D11ShaderResourceView *find(const SRVKey &key) const; - ID3D11ShaderResourceView *add(const SRVKey &key, ID3D11ShaderResourceView *srv); - - std::vector cache; - }; - private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11); const UINT mBindFlags; - SRVCache srvCache; + struct SRVKey + { + SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false); + + bool operator<(const SRVKey &rhs) const; + + int baseLevel; + int mipLevels; + bool swizzle; + }; + typedef std::map SRVCache; + + SRVCache mSrvCache; ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_2D : public TextureStorage11 { public: - TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain); - TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); + TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain); + TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual ~TextureStorage11_2D(); static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getResource(ID3D11Resource **outResource); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - virtual void generateMipmaps(); - - virtual void associateImage(Image11* image, int level, int layerTarget); - virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); - virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); - virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; ID3D11Texture2D *mTexture; RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; @@ -191,68 +177,68 @@ class TextureStorage11_2D : public TextureStorage11 class TextureStorage11_Cube : public TextureStorage11 { public: - TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels); + TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels); virtual ~TextureStorage11_Cube(); static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getResource(ID3D11Resource **outResource); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - virtual void generateMipmaps(); - - virtual void associateImage(Image11* image, int level, int layerTarget); - virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); - virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); - virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; + + static const size_t CUBE_FACE_COUNT = 6; ID3D11Texture2D *mTexture; - RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + RenderTarget11 *mRenderTarget[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; ID3D11Texture2D *mSwizzleTexture; ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - Image11 *mAssociatedImages[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + Image11 *mAssociatedImages[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; class TextureStorage11_3D : public TextureStorage11 { public: - TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget, + TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); virtual ~TextureStorage11_3D(); static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; + virtual gl::Error getResource(ID3D11Resource **outResource); // Handles both layer and non-layer RTs - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - virtual void generateMipmaps(); - - virtual void associateImage(Image11* image, int level, int layerTarget); - virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); - virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); - virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; typedef std::pair LevelLayerKey; typedef std::map RenderTargetMap; @@ -270,30 +256,29 @@ class TextureStorage11_3D : public TextureStorage11 class TextureStorage11_2DArray : public TextureStorage11 { public: - TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget, + TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); virtual ~TextureStorage11_2DArray(); static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage); - virtual ID3D11Resource *getResource() const; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); + virtual gl::Error getResource(ID3D11Resource **outResource); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); - virtual void generateMipmaps(); - - virtual void associateImage(Image11* image, int level, int layerTarget); - virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage); - virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage); - virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage); + virtual void associateImage(Image11* image, const gl::ImageIndex &index); + virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); + virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); + virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); protected: - virtual ID3D11Resource *getSwizzleTexture(); - virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel); + virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); + virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray); - virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture); + virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const; typedef std::pair LevelLayerKey; typedef std::map RenderTargetMap; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h index 590cb9f05a..70bc3bb26f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h @@ -19,7 +19,7 @@ class Renderer11; class VertexArray11 : public VertexArrayImpl { public: - VertexArray11(rx::Renderer11 *renderer) + VertexArray11(Renderer11 *renderer) : VertexArrayImpl(), mRenderer(renderer) { @@ -34,7 +34,7 @@ class VertexArray11 : public VertexArrayImpl private: DISALLOW_COPY_AND_ASSIGN(VertexArray11); - rx::Renderer11 *mRenderer; + Renderer11 *mRenderer; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp index 9bc5b1d2d1..a9d6fa2ca4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -16,7 +16,7 @@ namespace rx { -VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) +VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) { mBuffer = NULL; mBufferSize = 0; @@ -91,8 +91,13 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri { if (buffer) { - Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation()); - input = static_cast(storage->getData()) + static_cast(attrib.offset); + BufferD3D *storage = BufferD3D::makeFromBuffer(buffer); + gl::Error error = storage->getData(&input); + if (error.isError()) + { + return error; + } + input += static_cast(attrib.offset); } else { @@ -132,7 +137,7 @@ gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GL else { // Round up to divisor, if possible - elementCount = rx::UnsignedCeilDivide(static_cast(instances), attrib.divisor); + elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); } gl::VertexFormat vertexFormat(attrib); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h index 0e10da1df8..a9bbac98fa 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h @@ -18,7 +18,7 @@ class Renderer11; class VertexBuffer11 : public VertexBuffer { public: - explicit VertexBuffer11(rx::Renderer11 *const renderer); + explicit VertexBuffer11(Renderer11 *const renderer); virtual ~VertexBuffer11(); virtual gl::Error initialize(unsigned int size, bool dynamicUsage); @@ -40,7 +40,7 @@ class VertexBuffer11 : public VertexBuffer private: DISALLOW_COPY_AND_ASSIGN(VertexBuffer11); - rx::Renderer11 *const mRenderer; + Renderer11 *const mRenderer; ID3D11Buffer *mBuffer; unsigned int mBufferSize; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp index c07828757d..90a879e170 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp @@ -795,7 +795,7 @@ static D3D11ES3FormatMap BuildD3D11FormatMap() // From GL_EXT_texture_storage // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); + InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp index 2af97e73f0..121aa3bbad 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp @@ -10,6 +10,7 @@ #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/Workarounds.h" #include "libGLESv2/ProgramBinary.h" #include "libGLESv2/Framebuffer.h" @@ -95,9 +96,6 @@ #ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT # define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 #endif -#ifndef D3D11_VS_OUTPUT_REGISTER_COUNT -# define D3D11_VS_OUTPUT_REGISTER_COUNT 32 -#endif namespace rx { @@ -357,7 +355,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -377,7 +375,7 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY; @@ -399,7 +397,7 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -421,7 +419,7 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -441,7 +439,7 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -466,7 +464,7 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -486,7 +484,7 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; @@ -506,7 +504,7 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; @@ -526,7 +524,7 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION; @@ -546,7 +544,7 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; @@ -566,7 +564,7 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; @@ -586,7 +584,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX; @@ -612,7 +610,7 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -636,7 +634,7 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -655,7 +653,7 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; @@ -677,7 +675,7 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; @@ -704,7 +702,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); @@ -733,7 +731,7 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); @@ -754,7 +752,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; @@ -778,7 +776,7 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; @@ -805,7 +803,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); @@ -826,7 +824,7 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); @@ -847,7 +845,7 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; @@ -868,7 +866,7 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; @@ -889,7 +887,7 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; @@ -914,7 +912,7 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; @@ -935,7 +933,7 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT; @@ -951,11 +949,11 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) } } -static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel) +static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif case D3D_FEATURE_LEVEL_11_0: @@ -971,14 +969,14 @@ static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL fea } } -static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel) +static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -#if _MSC_VER >= 1700 +#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: #endif - case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) / + case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) / GetMaximumStreamOutputBuffers(featureLevel); @@ -1087,9 +1085,9 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; // Transform feedback limits - caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel); + caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponents(featureLevel); caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); - caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel); + caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateComponents(featureLevel); // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); @@ -1198,17 +1196,31 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) { -#if !defined(__MINGW32__) && defined(_DEBUG) +#if defined(_DEBUG) && !defined(__MINGW32__) return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); #else return S_OK; #endif } -RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT) { - RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); - return RenderTarget11::makeRenderTarget11(renderTarget); + RenderTarget *renderTarget = NULL; + gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) + { + return error; + } + *outRT = RenderTarget11::makeRenderTarget11(renderTarget); + return gl::Error(GL_NO_ERROR); +} + +Workarounds GenerateWorkarounds() +{ + Workarounds workarounds; + workarounds.mrtPerfWorkaround = true; + workarounds.setDataFasterThanImageUpload = true; + return workarounds; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h index 4c05eb9256..9df9c95763 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h @@ -12,6 +12,7 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +#include "libGLESv2/Error.h" #include @@ -23,6 +24,7 @@ class FramebufferAttachment; namespace rx { class RenderTarget11; +struct Workarounds; namespace gl_d3d11 { @@ -176,7 +178,9 @@ inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBu context->Unmap(constantBuffer, 0); } -RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT); + +Workarounds GenerateWorkarounds(); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp index f061a32c52..2ca7a9cf8a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp @@ -46,10 +46,16 @@ const size_t g_shaderSize[] = namespace rx { -Blit9::Blit9(rx::Renderer9 *renderer) - : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL) + +Blit9::Blit9(Renderer9 *renderer) + : mRenderer(renderer), + mGeometryLoaded(false), + mQuadVertexBuffer(NULL), + mQuadVertexDeclaration(NULL), + mSavedStateBlock(NULL), + mSavedRenderTarget(NULL), + mSavedDepthStencil(NULL) { - initGeometry(); memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); } @@ -65,8 +71,13 @@ Blit9::~Blit9() } } -void Blit9::initGeometry() +gl::Error Blit9::initialize() { + if (mGeometryLoaded) + { + return gl::Error(GL_NO_ERROR); + } + static const float quad[] = { -1, -1, @@ -82,7 +93,7 @@ void Blit9::initGeometry() if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal blit vertex shader, result: 0x%X.", result); } void *lockPtr = NULL; @@ -91,7 +102,8 @@ void Blit9::initGeometry() if (FAILED(result) || lockPtr == NULL) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY); + SafeRelease(mQuadVertexBuffer); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex shader, result: 0x%X.", result); } memcpy(lockPtr, quad, sizeof(quad)); @@ -108,14 +120,18 @@ void Blit9::initGeometry() if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY); + SafeRelease(mQuadVertexBuffer); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex declaration, result: 0x%X.", result); } + + mGeometryLoaded = true; + return gl::Error(GL_NO_ERROR); } template -bool Blit9::setShader(ShaderId source, const char *profile, - D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length), - HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)) +gl::Error Blit9::setShader(ShaderId source, const char *profile, + gl::Error (Renderer9::*createShader)(const DWORD *, size_t length, D3DShaderType **outShader), + HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)) { IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -130,35 +146,32 @@ bool Blit9::setShader(ShaderId source, const char *profile, const BYTE* shaderCode = g_shaderCode[source]; size_t shaderSize = g_shaderSize[source]; - shader = (mRenderer->*createShader)(reinterpret_cast(shaderCode), shaderSize); - if (!shader) + gl::Error error = (mRenderer->*createShader)(reinterpret_cast(shaderCode), shaderSize, &shader); + if (error.isError()) { - ERR("Failed to create shader for blit operation"); - return false; + return error; } mCompiledShaders[source] = shader; } HRESULT hr = (device->*setShader)(shader); - if (FAILED(hr)) { - ERR("Failed to set shader for blit operation"); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to set shader for blit operation, result: 0x%X.", hr); } - return true; + return gl::Error(GL_NO_ERROR); } -bool Blit9::setVertexShader(ShaderId shader) +gl::Error Blit9::setVertexShader(ShaderId shader) { - return setShader(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader); + return setShader(shader, "vs_2_0", &Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader); } -bool Blit9::setPixelShader(ShaderId shader) +gl::Error Blit9::setPixelShader(ShaderId shader) { - return setShader(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader); + return setShader(shader, "ps_2_0", &Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader); } RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const @@ -175,12 +188,19 @@ RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const return rect; } -bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) +gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) { - IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source)); - if (!texture) + gl::Error error = initialize(); + if (error.isError()) { - return false; + return error; + } + + IDirect3DTexture9 *texture = NULL; + error = copySurfaceToTexture(source, getSurfaceRect(source), &texture); + if (error.isError()) + { + return error; } IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -205,87 +225,90 @@ bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) restoreState(); - return true; + return gl::Error(GL_NO_ERROR); } -bool Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) +gl::Error Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *source = NULL; + gl::Error error = initialize(); + if (error.isError()) + { + return error; + } + gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); + ASSERT(colorbuffer); - if (colorbuffer) + RenderTarget9 *renderTarget9 = NULL; + error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9); + if (error.isError()) { - renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); + return error; } + ASSERT(renderTarget9); - if (renderTarget) - { - source = renderTarget->getSurface(); - } - - if (!source) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + IDirect3DSurface9 *source = renderTarget9->getSurface(); + ASSERT(source); + IDirect3DSurface9 *destSurface = NULL; TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); - IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true); - bool result = false; - - if (destSurface) + error = storage9->getSurfaceLevel(level, true, &destSurface); + if (error.isError()) { - result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); - SafeRelease(destSurface); + return error; } + ASSERT(destSurface); + gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); + + SafeRelease(destSurface); SafeRelease(source); + return result; } -bool Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *source = NULL; + gl::Error error = initialize(); + if (error.isError()) + { + return error; + } + gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); + ASSERT(colorbuffer); - if (colorbuffer) + RenderTarget9 *renderTarget9 = NULL; + error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9); + if (error.isError()) { - renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); + return error; } + ASSERT(renderTarget9); - if (renderTarget) - { - source = renderTarget->getSurface(); - } - - if (!source) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + IDirect3DSurface9 *source = renderTarget9->getSurface(); + ASSERT(source); + IDirect3DSurface9 *destSurface = NULL; TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); - IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true); - bool result = false; - - if (destSurface) + error = storage9->getCubeMapSurface(target, level, true, &destSurface); + if (error.isError()) { - result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); - SafeRelease(destSurface); + return error; } + ASSERT(destSurface); + gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); + + SafeRelease(destSurface); SafeRelease(source); + return result; } -bool Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) +gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) { - if (!dest) - { - return false; - } + ASSERT(source != NULL && dest != NULL); IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -303,22 +326,30 @@ bool Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destF if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY, false); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit between textures, StretchRect result: 0x%X.", result); } + + return gl::Error(GL_NO_ERROR); } else { return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest); } - return true; } -bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) +gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) { - IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect); - if (!texture) + gl::Error error = initialize(); + if (error.isError()) { - return false; + return error; + } + + IDirect3DTexture9 *texture = NULL; + error = copySurfaceToTexture(source, sourceRect, &texture); + if (error.isError()) + { + return error; } IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -331,7 +362,9 @@ bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLe setViewport(sourceRect, xoffset, yoffset); setCommonBlitState(); - if (setFormatConvertShaders(destFormat)) + + error = setFormatConvertShaders(destFormat); + if (!error.isError()) { render(); } @@ -340,12 +373,16 @@ bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLe restoreState(); - return true; + return error; } -bool Blit9::setFormatConvertShaders(GLenum destFormat) +gl::Error Blit9::setFormatConvertShaders(GLenum destFormat) { - bool okay = setVertexShader(SHADER_VS_STANDARD); + gl::Error error = setVertexShader(SHADER_VS_STANDARD); + if (error.isError()) + { + return error; + } switch (destFormat) { @@ -356,18 +393,18 @@ bool Blit9::setFormatConvertShaders(GLenum destFormat) case GL_RG_EXT: case GL_RED_EXT: case GL_ALPHA: - okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK); + error = setPixelShader(SHADER_PS_COMPONENTMASK); break; case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: - okay = okay && setPixelShader(SHADER_PS_LUMINANCE); + error = setPixelShader(SHADER_PS_LUMINANCE); break; } - if (!okay) + if (error.isError()) { - return false; + return error; } enum { X = 0, Y = 1, Z = 2, W = 3 }; @@ -463,15 +500,12 @@ bool Blit9::setFormatConvertShaders(GLenum destFormat) mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2); - return true; + return gl::Error(GL_NO_ERROR); } -IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) +gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture) { - if (!surface) - { - return NULL; - } + ASSERT(surface); IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -485,7 +519,7 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for blit, result: 0x%X.", result); } IDirect3DSurface9 *textureSurface; @@ -495,7 +529,7 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(texture); - return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to query surface of internal blit texture, result: 0x%X.", result); } mRenderer->endScene(); @@ -507,10 +541,11 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(texture); - return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy between internal blit textures, result: 0x%X.", result); } - return texture; + *outTexture = texture; + return gl::Error(GL_NO_ERROR); } void Blit9::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h index 46a3ee1cf3..5c7a76ce05 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h @@ -10,6 +10,7 @@ #define LIBGLESV2_BLIT9_H_ #include "common/angleutils.h" +#include "libGLESv2/Error.h" #include @@ -29,32 +30,33 @@ class Blit9 explicit Blit9(Renderer9 *renderer); ~Blit9(); + gl::Error initialize(); + // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - bool copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); - bool copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + gl::Error copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + gl::Error copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) // source is interpreted as RGBA and destFormat specifies the desired result format. For example, if destFormat = GL_RGB, the alpha channel will be forced to 0. - bool formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); + gl::Error formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); // 2x2 box filter sample from source to dest. // Requires that source is RGB(A) and dest has the same format as source. - bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); + gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); private: - rx::Renderer9 *mRenderer; + Renderer9 *mRenderer; + bool mGeometryLoaded; IDirect3DVertexBuffer9 *mQuadVertexBuffer; IDirect3DVertexDeclaration9 *mQuadVertexDeclaration; - void initGeometry(); + gl::Error setFormatConvertShaders(GLenum destFormat); - bool setFormatConvertShaders(GLenum destFormat); - - bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); - IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect); + gl::Error copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); + gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture); void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset); void setCommonBlitState(); RECT getSurfaceRect(IDirect3DSurface9 *surface) const; @@ -74,12 +76,12 @@ class Blit9 IUnknown *mCompiledShaders[SHADER_COUNT]; template - bool setShader(ShaderId source, const char *profile, - D3DShaderType *(Renderer9::*createShader)(const DWORD *, size_t length), - HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)); + gl::Error setShader(ShaderId source, const char *profile, + gl::Error (Renderer9::*createShader)(const DWORD *, size_t length, D3DShaderType **outShader), + HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)); - bool setVertexShader(ShaderId shader); - bool setPixelShader(ShaderId shader); + gl::Error setVertexShader(ShaderId shader); + gl::Error setPixelShader(ShaderId shader); void render(); void saveState(); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp index c02db515a2..430fe81e50 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp @@ -13,7 +13,7 @@ namespace rx { -Buffer9::Buffer9(rx::Renderer9 *renderer) +Buffer9::Buffer9(Renderer9 *renderer) : BufferD3D(), mRenderer(renderer), mSize(0) @@ -41,7 +41,7 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) } mSize = size; - if (data) + if (data && size > 0) { memcpy(mMemory.data(), data, size); } @@ -56,9 +56,10 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) return gl::Error(GL_NO_ERROR); } -void *Buffer9::getData() +gl::Error Buffer9::getData(const uint8_t **outData) { - return mMemory.data(); + *outData = mMemory.data(); + return gl::Error(GL_NO_ERROR); } gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) @@ -72,7 +73,7 @@ gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) } mSize = std::max(mSize, offset + size); - if (data) + if (data && size > 0) { memcpy(mMemory.data() + offset, data, size); } @@ -113,7 +114,7 @@ void Buffer9::markTransformFeedbackUsage() UNREACHABLE(); } -Renderer* Buffer9::getRenderer() +RendererD3D *Buffer9::getRenderer() { return mRenderer; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h index e78182f905..c80b009738 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h @@ -20,7 +20,7 @@ class Renderer9; class Buffer9 : public BufferD3D { public: - Buffer9(rx::Renderer9 *renderer); + Buffer9(Renderer9 *renderer); virtual ~Buffer9(); static Buffer9 *makeBuffer9(BufferImpl *buffer); @@ -28,11 +28,11 @@ class Buffer9 : public BufferD3D // BufferD3D implementation virtual size_t getSize() const { return mSize; } virtual bool supportsDirectBinding() const { return false; } - virtual Renderer* getRenderer(); + RendererD3D *getRenderer() override; // BufferImpl implementation virtual gl::Error setData(const void* data, size_t size, GLenum usage); - virtual void *getData(); + gl::Error getData(const uint8_t **outData) override; virtual gl::Error setSubData(const void* data, size_t size, size_t offset); virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); @@ -42,7 +42,7 @@ class Buffer9 : public BufferD3D private: DISALLOW_COPY_AND_ASSIGN(Buffer9); - rx::Renderer9 *mRenderer; + Renderer9 *mRenderer; MemoryBuffer mMemory; size_t mSize; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp index e352a5f50a..66263fe110 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// Fence9.cpp: Defines the rx::Fence9 class. +// Fence9.cpp: Defines the rx::FenceNV9 class. #include "libGLESv2/renderer/d3d/d3d9/Fence9.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" @@ -14,39 +14,41 @@ namespace rx { -Fence9::Fence9(rx::Renderer9 *renderer) +FenceNV9::FenceNV9(Renderer9 *renderer) + : FenceNVImpl(), + mRenderer(renderer), + mQuery(NULL) { - mRenderer = renderer; - mQuery = NULL; } -Fence9::~Fence9() +FenceNV9::~FenceNV9() { SafeRelease(mQuery); } -bool Fence9::isSet() const -{ - return mQuery != NULL; -} - -void Fence9::set() +gl::Error FenceNV9::set() { if (!mQuery) { - mQuery = mRenderer->allocateEventQuery(); - if (!mQuery) + gl::Error error = mRenderer->allocateEventQuery(&mQuery); + if (error.isError()) { - return gl::error(GL_OUT_OF_MEMORY); + return error; } } HRESULT result = mQuery->Issue(D3DISSUE_END); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + SafeRelease(mQuery); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to end event query, result: 0x%X.", result); + } + + return gl::Error(GL_NO_ERROR); } -bool Fence9::test(bool flushCommandBuffer) +gl::Error FenceNV9::test(bool flushCommandBuffer, GLboolean *outFinished) { ASSERT(mQuery); @@ -56,17 +58,34 @@ bool Fence9::test(bool flushCommandBuffer) if (d3d9::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY, true); + return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query."); + } + else if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result); } ASSERT(result == S_OK || result == S_FALSE); - - return (result == S_OK); + *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); + return gl::Error(GL_NO_ERROR); } -bool Fence9::hasError() const +gl::Error FenceNV9::finishFence(GLboolean *outFinished) { - return mRenderer->isDeviceLost(); + ASSERT(outFinished); + + while (*outFinished != GL_TRUE) + { + gl::Error error = test(true, outFinished); + if (error.isError()) + { + return error; + } + + Sleep(0); + } + + return gl::Error(GL_NO_ERROR); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h index e923a2178c..d7873d5264 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// Fence9.h: Defines the rx::Fence9 class which implements rx::FenceImpl. +// Fence9.h: Defines the rx::FenceNV9 class which implements rx::FenceNVImpl. #ifndef LIBGLESV2_RENDERER_FENCE9_H_ #define LIBGLESV2_RENDERER_FENCE9_H_ @@ -15,21 +15,20 @@ namespace rx { class Renderer9; -class Fence9 : public FenceImpl +class FenceNV9 : public FenceNVImpl { public: - explicit Fence9(rx::Renderer9 *renderer); - virtual ~Fence9(); + explicit FenceNV9(Renderer9 *renderer); + virtual ~FenceNV9(); - bool isSet() const; - void set(); - bool test(bool flushCommandBuffer); - bool hasError() const; + gl::Error set(); + gl::Error test(bool flushCommandBuffer, GLboolean *outFinished); + gl::Error finishFence(GLboolean *outFinished); private: - DISALLOW_COPY_AND_ASSIGN(Fence9); + DISALLOW_COPY_AND_ASSIGN(FenceNV9); - rx::Renderer9 *mRenderer; + Renderer9 *mRenderer; IDirect3DQuery9 *mQuery; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp index 18383fba78..2a06d12942 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp @@ -17,7 +17,7 @@ #include "libGLESv2/Framebuffer.h" #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/Renderbuffer.h" - +#include "common/utilities.h" namespace rx { @@ -36,15 +36,23 @@ Image9::~Image9() SafeRelease(mSurface); } -void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface) +gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface) { D3DSURFACE_DESC destDesc; HRESULT result = destSurface->GetDesc(&destDesc); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the source surface description for mipmap generation, result: 0x%X.", result); + } D3DSURFACE_DESC sourceDesc; result = sourceSurface->GetDesc(&sourceDesc); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the destination surface description for mipmap generation, result: 0x%X.", result); + } ASSERT(sourceDesc.Format == destDesc.Format); ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width); @@ -56,74 +64,111 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour D3DLOCKED_RECT sourceLocked = {0}; result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface for mipmap generation, result: 0x%X.", result); + } D3DLOCKED_RECT destLocked = {0}; result = destSurface->LockRect(&destLocked, NULL, 0); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + sourceSurface->UnlockRect(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the destination surface for mipmap generation, result: 0x%X.", result); + } const uint8_t *sourceData = reinterpret_cast(sourceLocked.pBits); uint8_t *destData = reinterpret_cast(destLocked.pBits); - if (sourceData && destData) - { - d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, - destData, destLocked.Pitch, 0); - } + ASSERT(sourceData && destData); + + d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, + destData, destLocked.Pitch, 0); destSurface->UnlockRect(); sourceSurface->UnlockRect(); + + return gl::Error(GL_NO_ERROR); } Image9 *Image9::makeImage9(Image *img) { - ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img)); - return static_cast(img); + ASSERT(HAS_DYNAMIC_TYPE(Image9*, img)); + return static_cast(img); } -void Image9::generateMipmap(Image9 *dest, Image9 *source) +gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source) { - IDirect3DSurface9 *sourceSurface = source->getSurface(); - if (sourceSurface == NULL) - return gl::error(GL_OUT_OF_MEMORY); + IDirect3DSurface9 *sourceSurface = NULL; + gl::Error error = source->getSurface(&sourceSurface); + if (error.isError()) + { + return error; + } - IDirect3DSurface9 *destSurface = dest->getSurface(); - generateMip(destSurface, sourceSurface); + IDirect3DSurface9 *destSurface = NULL; + error = dest->getSurface(&destSurface); + if (error.isError()) + { + return error; + } + + error = generateMip(destSurface, sourceSurface); + if (error.isError()) + { + return error; + } dest->markDirty(); + + return gl::Error(GL_NO_ERROR); } -void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source) +gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source) { D3DLOCKED_RECT sourceLock = {0}; D3DLOCKED_RECT destLock = {0}; - source->LockRect(&sourceLock, NULL, 0); - dest->LockRect(&destLock, NULL, 0); + HRESULT result; - if (sourceLock.pBits && destLock.pBits) + result = source->LockRect(&sourceLock, NULL, 0); + if (FAILED(result)) { - D3DSURFACE_DESC desc; - source->GetDesc(&desc); - - const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); - unsigned int rows = desc.Height / d3dFormatInfo.blockHeight; - - unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight); - ASSERT(bytes <= static_cast(sourceLock.Pitch) && - bytes <= static_cast(destLock.Pitch)); - - for(unsigned int i = 0; i < rows; i++) - { - memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes); - } - - source->UnlockRect(); - dest->UnlockRect(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result); } - else UNREACHABLE(); + + result = dest->LockRect(&destLock, NULL, 0); + if (FAILED(result)) + { + source->UnlockRect(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result); + } + + ASSERT(sourceLock.pBits && destLock.pBits); + + D3DSURFACE_DESC desc; + source->GetDesc(&desc); + + const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + unsigned int rows = desc.Height / d3dFormatInfo.blockHeight; + + unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight); + ASSERT(bytes <= static_cast(sourceLock.Pitch) && + bytes <= static_cast(destLock.Pitch)); + + for(unsigned int i = 0; i < rows; i++) + { + memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes); + } + + source->UnlockRect(); + dest->UnlockRect(); + + return gl::Error(GL_NO_ERROR); } -bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) +bool Image9::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) { // 3D textures are not supported by the D3D9 backend. ASSERT(depth <= 1); @@ -160,11 +205,11 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform return false; } -void Image9::createSurface() +gl::Error Image9::createSurface() { - if(mSurface) + if (mSurface) { - return; + return gl::Error(GL_NO_ERROR); } IDirect3DTexture9 *newTexture = NULL; @@ -187,8 +232,7 @@ void Image9::createSurface() if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - ERR("Creating image surface failed."); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create image surface, result: 0x%X.", result); } newTexture->GetSurfaceLevel(levelToFetch, &newSurface); @@ -206,35 +250,51 @@ void Image9::createSurface() D3DLOCKED_RECT lockedRect; result = newSurface->LockRect(&lockedRect, &entireRect, 0); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result); + } d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast(lockedRect.pBits), lockedRect.Pitch, 0); result = newSurface->UnlockRect(); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock image surface, result: 0x%X.", result); + } } } mSurface = newSurface; mDirty = false; mD3DPool = poolToUse; + + return gl::Error(GL_NO_ERROR); } -HRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect) +gl::Error Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT &rect) { - createSurface(); - - HRESULT result = D3DERR_INVALIDCALL; + gl::Error error = createSurface(); + if (error.isError()) + { + return error; + } if (mSurface) { - result = mSurface->LockRect(lockedRect, rect, 0); + HRESULT result = mSurface->LockRect(lockedRect, &rect, 0); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result); + } mDirty = true; } - return result; + return gl::Error(GL_NO_ERROR); } void Image9::unlock() @@ -263,26 +323,43 @@ bool Image9::isDirty() const return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty; } -IDirect3DSurface9 *Image9::getSurface() +gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface) { - createSurface(); + gl::Error error = createSurface(); + if (error.isError()) + { + return error; + } - return mSurface; + *outSurface = mSurface; + return gl::Error(GL_NO_ERROR); } -void Image9::setManagedSurface2D(TextureStorage *storage, int level) +gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) { + IDirect3DSurface9 *surface = NULL; TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); - setManagedSurface(storage9->getSurfaceLevel(level, false)); + gl::Error error = storage9->getSurfaceLevel(level, false, &surface); + if (error.isError()) + { + return error; + } + return setManagedSurface(surface); } -void Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) +gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) { + IDirect3DSurface9 *surface = NULL; TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); - setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false)); + gl::Error error = storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface); + if (error.isError()) + { + return error; + } + return setManagedSurface(surface); } -void Image9::setManagedSurface(IDirect3DSurface9 *surface) +gl::Error Image9::setManagedSurface(IDirect3DSurface9 *surface) { D3DSURFACE_DESC desc; surface->GetDesc(&desc); @@ -292,97 +369,119 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface) { if (mSurface) { - copyLockableSurfaces(surface, mSurface); + gl::Error error = copyLockableSurfaces(surface, mSurface); SafeRelease(mSurface); + if (error.isError()) + { + return error; + } } mSurface = surface; mD3DPool = desc.Pool; } + + return gl::Error(GL_NO_ERROR); } -bool Image9::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) { - ASSERT(getSurface() != NULL); - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); - return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height); -} - -bool Image9::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - ASSERT(getSurface() != NULL); - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); - return copyToSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height); -} - -bool Image9::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) -{ - // 3D textures are not supported by the D3D9 backend. - UNREACHABLE(); - return false; -} - -bool Image9::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) -{ - // 2D array textures are not supported by the D3D9 backend. - UNREACHABLE(); - return false; -} - -bool Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - ASSERT(width > 0 && height > 0); - - if (!destSurface) - return false; - - IDirect3DSurface9 *sourceSurface = getSurface(); - - if (sourceSurface && sourceSurface != destSurface) + gl::Error error = createSurface(); + if (error.isError()) { - RECT rect; - rect.left = xoffset; - rect.top = yoffset; - rect.right = xoffset + width; - rect.bottom = yoffset + height; + return error; + } - POINT point = {rect.left, rect.top}; + IDirect3DSurface9 *destSurface = NULL; - IDirect3DDevice9 *device = mRenderer->getDevice(); - - if (mD3DPool == D3DPOOL_MANAGED) + if (index.type == GL_TEXTURE_2D) + { + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage); + gl::Error error = storage9->getSurfaceLevel(index.mipIndex, true, &destSurface); + if (error.isError()) { - D3DSURFACE_DESC desc; - sourceSurface->GetDesc(&desc); - - IDirect3DSurface9 *surf = 0; - HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); - - if (SUCCEEDED(result)) - { - copyLockableSurfaces(surf, sourceSurface); - result = device->UpdateSurface(surf, &rect, destSurface, &point); - ASSERT(SUCCEEDED(result)); - SafeRelease(surf); - } + return error; } - else + } + else + { + ASSERT(gl::IsCubemapTextureTarget(index.type)); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage); + gl::Error error = storage9->getCubeMapSurface(index.type, index.mipIndex, true, &destSurface); + if (error.isError()) { - // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools - HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); + return error; } } + error = copyToSurface(destSurface, region.x, region.y, region.width, region.height); SafeRelease(destSurface); - return true; + return error; +} + +gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + ASSERT(width > 0 && height > 0); + ASSERT(destSurface); + + IDirect3DSurface9 *sourceSurface = NULL; + gl::Error error = getSurface(&sourceSurface); + if (error.isError()) + { + return error; + } + + ASSERT(sourceSurface && sourceSurface != destSurface); + + RECT rect; + rect.left = xoffset; + rect.top = yoffset; + rect.right = xoffset + width; + rect.bottom = yoffset + height; + + POINT point = {rect.left, rect.top}; + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + if (mD3DPool == D3DPOOL_MANAGED) + { + D3DSURFACE_DESC desc; + sourceSurface->GetDesc(&desc); + + IDirect3DSurface9 *surf = 0; + HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Internal CreateOffscreenPlainSurface call failed, result: 0x%X.", result); + } + + copyLockableSurfaces(surf, sourceSurface); + result = device->UpdateSurface(surf, &rect, destSurface, &point); + SafeRelease(surf); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result); + } + } + else + { + // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools + HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result); + } + } + + return gl::Error(GL_NO_ERROR); } // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // into the target pixel rectangle. -void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input) +gl::Error Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input) { // 3D textures are not supported by the D3D9 backend. ASSERT(zoffset == 0 && depth == 1); @@ -400,10 +499,10 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width }; D3DLOCKED_RECT locked; - HRESULT result = lock(&locked, &lockRect); - if (FAILED(result)) + gl::Error error = lock(&locked, lockRect); + if (error.isError()) { - return; + return error; } d3dFormatInfo.loadFunction(width, height, depth, @@ -411,10 +510,12 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width reinterpret_cast(locked.pBits), locked.Pitch, 0); unlock(); + + return gl::Error(GL_NO_ERROR); } -void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input) +gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input) { // 3D textures are not supported by the D3D9 backend. ASSERT(zoffset == 0 && depth == 1); @@ -437,10 +538,10 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs }; D3DLOCKED_RECT locked; - HRESULT result = lock(&locked, &lockRect); - if (FAILED(result)) + gl::Error error = lock(&locked, lockRect); + if (error.isError()) { - return; + return error; } d3d9FormatInfo.loadFunction(width, height, depth, @@ -448,33 +549,22 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs reinterpret_cast(locked.pBits), locked.Pitch, 0); unlock(); + + return gl::Error(GL_NO_ERROR); } // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures -void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) { + ASSERT(source); + // ES3.0 only behaviour to copy into a 3d texture ASSERT(zoffset == 0); - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *surface = NULL; - gl::FramebufferAttachment *colorbuffer = source->getColorbuffer(0); + RenderTarget9 *renderTarget = RenderTarget9::makeRenderTarget9(source); - if (colorbuffer) - { - renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); - } - - if (renderTarget) - { - surface = renderTarget->getSurface(); - } - - if (!surface) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY); - } + IDirect3DSurface9 *surface = renderTarget->getSurface(); + ASSERT(surface); IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -486,212 +576,200 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, if (FAILED(result)) { - ERR("Could not create matching destination surface."); SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Could not create matching destination surface, result: 0x%X.", result); } result = device->GetRenderTargetData(surface, renderTargetData); if (FAILED(result)) { - ERR("GetRenderTargetData unexpectedly failed."); SafeRelease(renderTargetData); SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "GetRenderTargetData unexpectedly failed, result: 0x%X.", result); } - RECT sourceRect = {x, y, x + width, y + height}; - RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height}; + int width = sourceArea.width; + int height = sourceArea.height; + + RECT sourceRect = { sourceArea.x, sourceArea.y, sourceArea.x + width, sourceArea.y + height }; + RECT destRect = { xoffset, yoffset, xoffset + width, yoffset + height }; D3DLOCKED_RECT sourceLock = {0}; result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0); if (FAILED(result)) { - ERR("Failed to lock the source surface (rectangle might be invalid)."); SafeRelease(renderTargetData); SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface (rectangle might be invalid), result: 0x%X.", result); } D3DLOCKED_RECT destLock = {0}; - result = lock(&destLock, &destRect); - - if (FAILED(result)) + gl::Error error = lock(&destLock, destRect); + if (error.isError()) { - ERR("Failed to lock the destination surface (rectangle might be invalid)."); renderTargetData->UnlockRect(); SafeRelease(renderTargetData); SafeRelease(surface); - return gl::error(GL_OUT_OF_MEMORY); + return error; } - if (destLock.pBits && sourceLock.pBits) - { - unsigned char *source = (unsigned char*)sourceLock.pBits; - unsigned char *dest = (unsigned char*)destLock.pBits; + ASSERT(destLock.pBits && sourceLock.pBits); - switch (description.Format) + unsigned char *sourcePixels = (unsigned char*)sourceLock.pBits; + unsigned char *destPixels = (unsigned char*)destLock.pBits; + + switch (description.Format) + { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + switch (getD3DFormat()) { case D3DFMT_X8R8G8B8: case D3DFMT_A8R8G8B8: - switch(getD3DFormat()) + for (int y = 0; y < height; y++) { - case D3DFMT_X8R8G8B8: - case D3DFMT_A8R8G8B8: - for(int y = 0; y < height; y++) - { - memcpy(dest, source, 4 * width); - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - dest[x] = source[x * 4 + 2]; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_A8L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - dest[x * 2 + 0] = source[x * 4 + 2]; - dest[x * 2 + 1] = source[x * 4 + 3]; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - default: - UNREACHABLE(); + memcpy(destPixels, sourcePixels, 4 * width); + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; } break; - case D3DFMT_R5G6B5: - switch(getD3DFormat()) + case D3DFMT_L8: + for (int y = 0; y < height; y++) { - case D3DFMT_X8R8G8B8: - for(int y = 0; y < height; y++) + for (int x = 0; x < width; x++) { - for(int x = 0; x < width; x++) - { - unsigned short rgb = ((unsigned short*)source)[x]; - unsigned char red = (rgb & 0xF800) >> 8; - unsigned char green = (rgb & 0x07E0) >> 3; - unsigned char blue = (rgb & 0x001F) << 3; - dest[x + 0] = blue | (blue >> 5); - dest[x + 1] = green | (green >> 6); - dest[x + 2] = red | (red >> 5); - dest[x + 3] = 0xFF; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; + destPixels[x] = sourcePixels[x * 4 + 2]; } - break; - case D3DFMT_L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned char red = source[x * 2 + 1] & 0xF8; - dest[x] = red | (red >> 5); - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - default: - UNREACHABLE(); + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; } break; - case D3DFMT_A1R5G5B5: - switch(getD3DFormat()) + case D3DFMT_A8L8: + for (int y = 0; y < height; y++) { - case D3DFMT_X8R8G8B8: - for(int y = 0; y < height; y++) + for (int x = 0; x < width; x++) { - for(int x = 0; x < width; x++) - { - unsigned short argb = ((unsigned short*)source)[x]; - unsigned char red = (argb & 0x7C00) >> 7; - unsigned char green = (argb & 0x03E0) >> 2; - unsigned char blue = (argb & 0x001F) << 3; - dest[x + 0] = blue | (blue >> 5); - dest[x + 1] = green | (green >> 5); - dest[x + 2] = red | (red >> 5); - dest[x + 3] = 0xFF; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; + destPixels[x * 2 + 0] = sourcePixels[x * 4 + 2]; + destPixels[x * 2 + 1] = sourcePixels[x * 4 + 3]; } - break; - case D3DFMT_A8R8G8B8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned short argb = ((unsigned short*)source)[x]; - unsigned char red = (argb & 0x7C00) >> 7; - unsigned char green = (argb & 0x03E0) >> 2; - unsigned char blue = (argb & 0x001F) << 3; - unsigned char alpha = (signed short)argb >> 15; - dest[x + 0] = blue | (blue >> 5); - dest[x + 1] = green | (green >> 5); - dest[x + 2] = red | (red >> 5); - dest[x + 3] = alpha; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned char red = source[x * 2 + 1] & 0x7C; - dest[x] = (red << 1) | (red >> 4); - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_A8L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned char red = source[x * 2 + 1] & 0x7C; - dest[x * 2 + 0] = (red << 1) | (red >> 4); - dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - default: - UNREACHABLE(); + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; } break; default: UNREACHABLE(); } + break; + case D3DFMT_R5G6B5: + switch (getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned short rgb = ((unsigned short*)sourcePixels)[x]; + unsigned char red = (rgb & 0xF800) >> 8; + unsigned char green = (rgb & 0x07E0) >> 3; + unsigned char blue = (rgb & 0x001F) << 3; + destPixels[x + 0] = blue | (blue >> 5); + destPixels[x + 1] = green | (green >> 6); + destPixels[x + 2] = red | (red >> 5); + destPixels[x + 3] = 0xFF; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned char red = sourcePixels[x * 2 + 1] & 0xF8; + destPixels[x] = red | (red >> 5); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + case D3DFMT_A1R5G5B5: + switch (getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned short argb = ((unsigned short*)sourcePixels)[x]; + unsigned char red = (argb & 0x7C00) >> 7; + unsigned char green = (argb & 0x03E0) >> 2; + unsigned char blue = (argb & 0x001F) << 3; + destPixels[x + 0] = blue | (blue >> 5); + destPixels[x + 1] = green | (green >> 5); + destPixels[x + 2] = red | (red >> 5); + destPixels[x + 3] = 0xFF; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_A8R8G8B8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned short argb = ((unsigned short*)sourcePixels)[x]; + unsigned char red = (argb & 0x7C00) >> 7; + unsigned char green = (argb & 0x03E0) >> 2; + unsigned char blue = (argb & 0x001F) << 3; + unsigned char alpha = (signed short)argb >> 15; + destPixels[x + 0] = blue | (blue >> 5); + destPixels[x + 1] = green | (green >> 5); + destPixels[x + 2] = red | (red >> 5); + destPixels[x + 3] = alpha; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned char red = sourcePixels[x * 2 + 1] & 0x7C; + destPixels[x] = (red << 1) | (red >> 4); + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + case D3DFMT_A8L8: + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + unsigned char red = sourcePixels[x * 2 + 1] & 0x7C; + destPixels[x * 2 + 0] = (red << 1) | (red >> 4); + destPixels[x * 2 + 1] = (signed char)sourcePixels[x * 2 + 1] >> 7; + } + sourcePixels += sourceLock.Pitch; + destPixels += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + default: + UNREACHABLE(); } unlock(); @@ -701,6 +779,14 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, SafeRelease(surface); mDirty = true; + return gl::Error(GL_NO_ERROR); +} + +gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage) +{ + // Currently unreachable, due to only being used in a D3D11-only workaround + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h index 08d8ee3545..8cc2258859 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h @@ -20,7 +20,6 @@ class Framebuffer; namespace rx { -class Renderer; class Renderer9; class Image9 : public ImageD3D @@ -31,41 +30,41 @@ class Image9 : public ImageD3D static Image9 *makeImage9(Image *img); - static void generateMipmap(Image9 *dest, Image9 *source); - static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); - static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); + static gl::Error generateMipmap(Image9 *dest, Image9 *source); + static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); + static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); - virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease); + bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override; D3DFORMAT getD3DFormat() const; virtual bool isDirty() const; - IDirect3DSurface9 *getSurface(); - virtual void setManagedSurface2D(TextureStorage *storage, int level); - virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level); - virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); - virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height); + virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level); + virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level); + virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion); - virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLint unpackAlignment, GLenum type, const void *input); - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - const void *input); + virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLint unpackAlignment, GLenum type, const void *input); + virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + const void *input); - virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset,GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source); + virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, + const gl::ImageIndex &sourceIndex, TextureStorage *source); private: DISALLOW_COPY_AND_ASSIGN(Image9); - void createSurface(); - void setManagedSurface(IDirect3DSurface9 *surface); - bool copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + gl::Error getSurface(IDirect3DSurface9 **outSurface); - HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); + gl::Error createSurface(); + gl::Error setManagedSurface(IDirect3DSurface9 *surface); + gl::Error copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + + gl::Error lock(D3DLOCKED_RECT *lockedRect, const RECT &rect); void unlock(); - + Renderer9 *mRenderer; D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable. diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h index d0970d6ac5..2375fcf4b0 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h @@ -40,7 +40,7 @@ class IndexBuffer9 : public IndexBuffer private: DISALLOW_COPY_AND_ASSIGN(IndexBuffer9); - rx::Renderer9 *const mRenderer; + Renderer9 *const mRenderer; IDirect3DIndexBuffer9 *mIndexBuffer; unsigned int mBufferSize; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp index 815fc01a9b..a3cab578be 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp @@ -15,7 +15,7 @@ namespace rx { -Query9::Query9(rx::Renderer9 *renderer, GLenum type) +Query9::Query9(Renderer9 *renderer, GLenum type) : QueryImpl(type), mResult(GL_FALSE), mQueryFinished(false), diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h index 513e0ba6fd..36851c6c6c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h @@ -18,7 +18,7 @@ class Renderer9; class Query9 : public QueryImpl { public: - Query9(rx::Renderer9 *renderer, GLenum type); + Query9(Renderer9 *renderer, GLenum type); virtual ~Query9(); virtual gl::Error begin(); @@ -34,7 +34,7 @@ class Query9 : public QueryImpl GLuint mResult; bool mQueryFinished; - rx::Renderer9 *mRenderer; + Renderer9 *mRenderer; IDirect3DQuery9 *mQuery; }; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp index 13321ac8cd..53d1f752fa 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp @@ -10,115 +10,83 @@ #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/main.h" namespace rx { -// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given. -RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) +RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target) { - mRenderer = Renderer9::makeRenderer9(renderer); - mRenderTarget = surface; + ASSERT(HAS_DYNAMIC_TYPE(RenderTarget9*, target)); + return static_cast(target); +} + +void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) +{ + // Currently a no-op +} + +// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given. +TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + GLsizei samples) + : mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mActualFormat(internalFormat), + mSamples(samples), + mRenderTarget(surface) +{ + ASSERT(mDepth == 1); if (mRenderTarget) { D3DSURFACE_DESC description; mRenderTarget->GetDesc(&description); - mWidth = description.Width; - mHeight = description.Height; - mDepth = 1; - const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format); - mInternalFormat = d3dFormatInfo.internalFormat; mActualFormat = d3dFormatInfo.internalFormat; - mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType); } } -RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples) -{ - mRenderer = Renderer9::makeRenderer9(renderer); - mRenderTarget = NULL; - - const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat); - const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat); - - const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat); - GLuint supportedSamples = textureCaps.getNearestSamples(samples); - - HRESULT result = D3DERR_INVALIDCALL; - - if (width > 0 && height > 0) - { - IDirect3DDevice9 *device = mRenderer->getDevice(); - - bool requiresInitialization = false; - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) - { - result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat, - gl_d3d9::GetMultisampleType(supportedSamples), - 0, FALSE, &mRenderTarget, NULL); - } - else - { - requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); - result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, - gl_d3d9::GetMultisampleType(supportedSamples), - 0, FALSE, &mRenderTarget, NULL); - } - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - gl::error(GL_OUT_OF_MEMORY); - - return; - } - - ASSERT(SUCCEEDED(result)); - - if (requiresInitialization) - { - // This format requires that the data be initialized before the render target can be used - // Unfortunately this requires a Get call on the d3d device but it is far better than having - // to mark the render target as lockable and copy data to the gpu. - IDirect3DSurface9 *prevRenderTarget = NULL; - device->GetRenderTarget(0, &prevRenderTarget); - device->SetRenderTarget(0, mRenderTarget); - device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); - device->SetRenderTarget(0, prevRenderTarget); - } - } - - mWidth = width; - mHeight = height; - mDepth = 1; - mInternalFormat = internalFormat; - mSamples = supportedSamples; - mActualFormat = d3dFormatInfo.internalFormat; -} - -RenderTarget9::~RenderTarget9() +TextureRenderTarget9::~TextureRenderTarget9() { SafeRelease(mRenderTarget); } -RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target) +GLsizei TextureRenderTarget9::getWidth() const { - ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target)); - return static_cast(target); + return mWidth; } -void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) +GLsizei TextureRenderTarget9::getHeight() const { - // Currently a no-op + return mHeight; } -IDirect3DSurface9 *RenderTarget9::getSurface() +GLsizei TextureRenderTarget9::getDepth() const +{ + return mDepth; +} + +GLenum TextureRenderTarget9::getInternalFormat() const +{ + return mInternalFormat; +} + +GLenum TextureRenderTarget9::getActualFormat() const +{ + return mActualFormat; +} + +GLsizei TextureRenderTarget9::getSamples() const +{ + return mSamples; +} + +IDirect3DSurface9 *TextureRenderTarget9::getSurface() { // Caller is responsible for releasing the returned surface reference. // TODO: remove the AddRef to match RenderTarget11 @@ -130,4 +98,51 @@ IDirect3DSurface9 *RenderTarget9::getSurface() return mRenderTarget; } + +SurfaceRenderTarget9::SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth) + : mSwapChain(swapChain), + mDepth(depth) +{ +} + +SurfaceRenderTarget9::~SurfaceRenderTarget9() +{ +} + +GLsizei SurfaceRenderTarget9::getWidth() const +{ + return mSwapChain->getWidth(); +} + +GLsizei SurfaceRenderTarget9::getHeight() const +{ + return mSwapChain->getHeight(); +} + +GLsizei SurfaceRenderTarget9::getDepth() const +{ + return 1; +} + +GLenum SurfaceRenderTarget9::getInternalFormat() const +{ + return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); +} + +GLenum SurfaceRenderTarget9::getActualFormat() const +{ + return d3d9::GetD3DFormatInfo(d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat; +} + +GLsizei SurfaceRenderTarget9::getSamples() const +{ + // Our EGL surfaces do not support multisampling. + return 0; +} + +IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() +{ + return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget()); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h index 68d7adb49e..4585697f4c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h @@ -14,28 +14,74 @@ namespace rx { -class Renderer; class Renderer9; +class SwapChain9; class RenderTarget9 : public RenderTarget { public: - RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface); - RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples); - virtual ~RenderTarget9(); + RenderTarget9() { } + virtual ~RenderTarget9() { } static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget); - virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height); + void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override; - IDirect3DSurface9 *getSurface(); + virtual IDirect3DSurface9 *getSurface() = 0; private: DISALLOW_COPY_AND_ASSIGN(RenderTarget9); +}; + +class TextureRenderTarget9 : public RenderTarget9 +{ + public: + TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + GLsizei samples); + virtual ~TextureRenderTarget9(); + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLenum getActualFormat() const override; + GLsizei getSamples() const override; + + IDirect3DSurface9 *getSurface() override; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget9); + + GLsizei mWidth; + GLsizei mHeight; + GLsizei mDepth; + GLenum mInternalFormat; + GLenum mActualFormat; + GLsizei mSamples; IDirect3DSurface9 *mRenderTarget; +}; - Renderer9 *mRenderer; +class SurfaceRenderTarget9 : public RenderTarget9 +{ + public: + SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth); + virtual ~SurfaceRenderTarget9(); + + GLsizei getWidth() const override; + GLsizei getHeight() const override; + GLsizei getDepth() const override; + GLenum getInternalFormat() const override; + GLenum getActualFormat() const override; + GLsizei getSamples() const override; + + IDirect3DSurface9 *getSurface() override; + + private: + DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget9); + + SwapChain9 *mSwapChain; + bool mDepth; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp index d63f9b8582..601cd24b10 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp @@ -26,6 +26,7 @@ #include "libGLESv2/renderer/d3d/ShaderD3D.h" #include "libGLESv2/renderer/d3d/TextureD3D.h" #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" +#include "libGLESv2/renderer/d3d/RenderbufferD3D.h" #include "libGLESv2/main.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/Texture.h" @@ -33,10 +34,12 @@ #include "libGLESv2/FramebufferAttachment.h" #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/State.h" #include "libGLESv2/angletypes.h" #include "libEGL/Display.h" +#include "common/features.h" #include "common/utilities.h" #include @@ -44,14 +47,6 @@ // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros #define REF_RAST 0 -// The "Debug This Pixel..." feature in PIX often fails when using the -// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 -// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file. -#if !defined(ANGLE_ENABLE_D3D9EX) -// Enables use of the IDirect3D9Ex interface, when available -#define ANGLE_ENABLE_D3D9EX 1 -#endif // !defined(ANGLE_ENABLE_D3D9EX) - #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 #endif @@ -96,8 +91,8 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; -Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay) - : Renderer(display), +Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes) + : RendererD3D(display), mDc(hDc) { mD3d9Module = NULL; @@ -177,8 +172,8 @@ void Renderer9::release() Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) { - ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer)); - return static_cast(renderer); + ASSERT(HAS_DYNAMIC_TYPE(Renderer9*, renderer)); + return static_cast(renderer); } EGLint Renderer9::initialize() @@ -202,7 +197,7 @@ EGLint Renderer9::initialize() // Use Direct3D9Ex if available. Among other things, this version is less // inclined to report a lost context, for example when the user switches // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. - if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) + if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { ASSERT(mD3d9Ex); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast(&mD3d9)); @@ -386,10 +381,13 @@ void Renderer9::initializeDevice() mSceneStarted = false; - ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager); + ASSERT(!mBlit); mBlit = new Blit9(this); - mVertexDataManager = new rx::VertexDataManager(this); - mIndexDataManager = new rx::IndexDataManager(this); + mBlit->initialize(); + + ASSERT(!mVertexDataManager && !mIndexDataManager); + mVertexDataManager = new VertexDataManager(this); + mIndexDataManager = new IndexDataManager(this); } D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() @@ -481,68 +479,92 @@ void Renderer9::endScene() } } -void Renderer9::sync(bool block) +gl::Error Renderer9::sync(bool block) { - HRESULT result; - - IDirect3DQuery9* query = allocateEventQuery(); - if (!query) + IDirect3DQuery9* query = NULL; + gl::Error error = allocateEventQuery(&query); + if (error.isError()) { - return; + return error; } - result = query->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); - - do + HRESULT result = query->Issue(D3DISSUE_END); + if (FAILED(result)) { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result); + } + + // Grab the query data once in blocking and non-blocking case + result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + if (FAILED(result)) + { + if (d3d9::isDeviceLostError(result)) + { + notifyDeviceLost(); + } + + freeEventQuery(query); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + } + + // If blocking, loop until the query completes + while (block && result == S_FALSE) + { + // Keep polling, but allow other threads to do something useful first + Sleep(0); + result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); - if(block && result == S_FALSE) + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + if (result == S_FALSE && testDeviceLost(false)) { - // Keep polling, but allow other threads to do something useful first - Sleep(0); - // explicitly check for device loss - // some drivers seem to return S_FALSE even if the device is lost - // instead of D3DERR_DEVICELOST like they should - if (testDeviceLost(false)) - { - result = D3DERR_DEVICELOST; - } + result = D3DERR_DEVICELOST; } + + if (FAILED(result)) + { + if (d3d9::isDeviceLostError(result)) + { + notifyDeviceLost(); + } + + freeEventQuery(query); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + } + } - while(block && result == S_FALSE); freeEventQuery(query); - if (d3d9::isDeviceLostError(result)) - { - notifyDeviceLost(); - } + return gl::Error(GL_NO_ERROR); } -SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +SwapChain *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) { - return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat); + return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); } -IDirect3DQuery9* Renderer9::allocateEventQuery() +gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) { - IDirect3DQuery9 *query = NULL; - if (mEventQueryPool.empty()) { - HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, outQuery); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate event query, result: 0x%X.", result); + } } else { - query = mEventQueryPool.back(); + *outQuery = mEventQueryPool.back(); mEventQueryPool.pop_back(); } - return query; + return gl::Error(GL_NO_ERROR); } void Renderer9::freeEventQuery(IDirect3DQuery9* query) @@ -557,14 +579,14 @@ void Renderer9::freeEventQuery(IDirect3DQuery9* query) } } -IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length) +gl::Error Renderer9::createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader) { - return mVertexShaderCache.create(function, length); + return mVertexShaderCache.create(function, length, outShader); } -IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length) +gl::Error Renderer9::createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader) { - return mPixelShaderCache.create(function, length); + return mPixelShaderCache.create(function, length, outShader); } HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer) @@ -604,9 +626,16 @@ QueryImpl *Renderer9::createQuery(GLenum type) return new Query9(this, type); } -FenceImpl *Renderer9::createFence() +FenceNVImpl *Renderer9::createFenceNV() { - return new Fence9(this); + return new FenceNV9(this); +} + +FenceSyncImpl *Renderer9::createFenceSync() +{ + // Renderer9 doesn't support ES 3.0 and its sync objects. + UNREACHABLE(); + return NULL; } TransformFeedbackImpl* Renderer9::createTransformFeedback() @@ -620,12 +649,12 @@ bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const return false; } -bool Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION); } gl::Error Renderer9::generateSwizzle(gl::Texture *texture) @@ -635,7 +664,7 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture) return gl::Error(GL_INVALID_OPERATION); } -gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState) { std::vector &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; std::vector &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; @@ -645,6 +674,10 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl:: int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSampler = index + d3dSamplerOffset; + // Make sure to add the level offset for our tiny compressed texture workaround + TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation()); + DWORD baseLevel = samplerState.baseLevel + textureD3D->getNativeTexture()->getTopLevel(); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); @@ -653,7 +686,7 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl:: gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.baseLevel); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); if (getRendererExtensions().textureFilterAnisotropic) { mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); @@ -684,7 +717,12 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te if (texStorage) { TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage); - d3dTexture = storage9->getBaseTexture(); + + gl::Error error = storage9->getBaseTexture(&d3dTexture); + if (error.isError()) + { + return error; + } } // If we get NULL back from getBaseTexture here, something went wrong // in the texture class and we're unexpectedly missing the d3d texture @@ -751,7 +789,7 @@ gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, +gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, unsigned int sampleMask) { bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; @@ -1097,13 +1135,9 @@ bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count) } -gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer) +gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer) { - if (!depthbuffer) - { - ERR("Unexpected null depthbuffer for depth-only FBO."); - return NULL; - } + ASSERT(depthbuffer); GLsizei width = depthbuffer->getWidth(); GLsizei height = depthbuffer->getHeight(); @@ -1116,11 +1150,19 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme mNullColorbufferCache[i].height == height) { mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; - return mNullColorbufferCache[i].buffer; + *outColorBuffer = mNullColorbufferCache[i].buffer; + return gl::Error(GL_NO_ERROR); } } - gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); + gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0); + gl::Error error = nullRenderbuffer->setStorage(width, height, GL_NONE, 0); + if (error.isError()) + { + SafeDelete(nullRenderbuffer); + return error; + } + gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer); // add nullbuffer to the cache @@ -1139,40 +1181,40 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme oldest->width = width; oldest->height = height; - return nullbuffer; + *outColorBuffer = nullbuffer; + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) +gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) { // if there is no color attachment we must synthesize a NULL colorattachment // to keep the D3D runtime happy. This should only be possible if depth texturing. gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(0); if (!attachment) { - attachment = getNullColorbuffer(framebuffer->getDepthbuffer()); - } - if (!attachment) - { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to locate renderbuffer for FBO."); + gl::Error error = getNullColorbuffer(framebuffer->getDepthbuffer(), &attachment); + if (error.isError()) + { + return error; + } } + ASSERT(attachment); bool renderTargetChanged = false; unsigned int renderTargetSerial = GetAttachmentSerial(attachment); if (renderTargetSerial != mAppliedRenderTargetSerial) { // Apply the render target on the device - IDirect3DSurface9 *renderTargetSurface = NULL; - - RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment); - if (renderTarget) + RenderTarget9 *renderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) { - renderTargetSurface = renderTarget->getSurface(); + return error; } + ASSERT(renderTarget); - if (!renderTargetSurface) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null."); - } + IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface(); + ASSERT(renderTargetSurface); mDevice->SetRenderTarget(0, renderTargetSurface); SafeRelease(renderTargetSurface); @@ -1204,18 +1246,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) // Apply the depth stencil on the device if (depthStencil) { - IDirect3DSurface9 *depthStencilSurface = NULL; - rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil); - - if (depthStencilRenderTarget) + RenderTarget9 *depthStencilRenderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget); + if (error.isError()) { - depthStencilSurface = depthStencilRenderTarget->getSurface(); + return error; } + ASSERT(depthStencilRenderTarget); - if (!depthStencilSurface) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil pointer unexpectedly null."); - } + IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface(); + ASSERT(depthStencilSurface); mDevice->SetDepthStencilSurface(depthStencilSurface); SafeRelease(depthStencilSurface); @@ -1260,17 +1300,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) { TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); + gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); if (error.isError()) { return error; } - return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw); + return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getCurrentProgramBinary(), instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device @@ -1296,7 +1335,7 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element return gl::Error(GL_NO_ERROR); } -void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) +void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) { UNREACHABLE(); } @@ -1373,10 +1412,15 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferImpl *storage = indexBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + indices = bufferData + offset; } unsigned int startIndex = 0; @@ -1570,9 +1614,17 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid if (elementArrayBuffer) { - BufferImpl *storage = elementArrayBuffer->getImplementation(); + BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer); intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; + + const uint8_t *bufferData = NULL; + gl::Error error = storage->getData(&bufferData); + if (error.isError()) + { + return error; + } + + indices = bufferData + offset; } switch (type) @@ -1662,8 +1714,21 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve ASSERT(!transformFeedbackActive); ASSERT(!rasterizerDiscard); - ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); - ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); + ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation()); + + ShaderExecutable *vertexExe = NULL; + gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe); + if (error.isError()) + { + return error; + } + + ShaderExecutable *pixelExe = NULL; + error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + if (error.isError()) + { + return error; + } IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL); IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL); @@ -1688,7 +1753,7 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve unsigned int programSerial = programBinary->getSerial(); if (programSerial != mAppliedProgramSerial) { - programBinary->dirtyAllUniforms(); + programD3D->dirtyAllUniforms(); mDxUniformsDirty = true; mAppliedProgramSerial = programSerial; } @@ -1696,10 +1761,8 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyUniforms(const gl::ProgramBinary &programBinary) +gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector &uniformArray) { - const std::vector &uniformArray = programBinary.getUniforms(); - for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) { gl::LinkedUniform *targetUniform = uniformArray[uniformIndex]; @@ -1797,7 +1860,7 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v applyUniformnfv(targetUniform, (GLfloat*)vector); } -gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) { if (clearParams.colorClearType != GL_FLOAT) { @@ -2219,7 +2282,7 @@ bool Renderer9::isRemovedDeviceResettable() const { bool success = false; -#ifdef ANGLE_ENABLE_D3D9EX +#if ANGLE_D3D9EX == ANGLE_ENABLED IDirect3D9Ex *d3d9Ex = NULL; typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); @@ -2330,82 +2393,6 @@ int Renderer9::getMaxSwapInterval() const return mMaxSwapInterval; } -bool Renderer9::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) -{ - bool result = false; - - if (source && dest) - { - TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source); - TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest); - - int levels = source9->getLevelCount(); - for (int i = 0; i < levels; ++i) - { - IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false); - IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false); - - result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - - SafeRelease(srcSurf); - SafeRelease(dstSurf); - - if (!result) - { - return false; - } - } - } - - return result; -} - -bool Renderer9::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) -{ - bool result = false; - - if (source && dest) - { - TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source); - TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest); - int levels = source9->getLevelCount(); - for (int f = 0; f < 6; f++) - { - for (int i = 0; i < levels; i++) - { - IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false); - IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true); - - result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - - SafeRelease(srcSurf); - SafeRelease(dstSurf); - - if (!result) - { - return false; - } - } - } - } - - return result; -} - -bool Renderer9::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) -{ - // 3D textures are not available in the D3D9 backend. - UNREACHABLE(); - return false; -} - -bool Renderer9::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) -{ - // 2D array textures are not supported by the D3D9 backend. - UNREACHABLE(); - return false; -} - D3DPOOL Renderer9::getBufferPool(DWORD usage) const { if (mD3d9Ex != NULL) @@ -2423,8 +2410,8 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2435,8 +2422,8 @@ bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &s return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); } -bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) { RECT rect; rect.left = sourceRect.x; @@ -2447,24 +2434,26 @@ bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle return mBlit->copyCube(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); } -bool Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { // 3D textures are not available in the D3D9 backend. UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION); } -bool Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) { // 2D array textures are not available in the D3D9 backend. UNREACHABLE(); - return false; + return gl::Error(GL_INVALID_OPERATION); } -bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, - const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) +gl::Error Renderer9::blitRect(const gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, + const gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, + bool blitDepth, bool blitStencil, GLenum filter) { ASSERT(filter == GL_NEAREST); @@ -2473,35 +2462,33 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (blitRenderTarget) { gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0); - gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0); + ASSERT(readBuffer); + RenderTarget9 *readRenderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(readRenderTarget); + + gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0); + ASSERT(drawBuffer); + RenderTarget9 *drawRenderTarget = NULL; - IDirect3DSurface9* readSurface = NULL; - IDirect3DSurface9* drawSurface = NULL; + error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(drawRenderTarget); - if (readBuffer) - { - readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer); - } - if (drawBuffer) - { - drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer); - } + // The getSurface calls do an AddRef so save them until after no errors are possible + IDirect3DSurface9* readSurface = readRenderTarget->getSurface(); + ASSERT(readSurface); - if (readRenderTarget) - { - readSurface = readRenderTarget->getSurface(); - } - if (drawRenderTarget) - { - drawSurface = drawRenderTarget->getSurface(); - } - - if (!readSurface || !drawSurface) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface(); + ASSERT(drawSurface); gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); @@ -2594,43 +2581,40 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (FAILED(result)) { - ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); } } if (blitDepth || blitStencil) { gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer(); - gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); + ASSERT(readBuffer); + RenderTarget9 *readDepthStencil = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil); + if (error.isError()) + { + return error; + } + ASSERT(readDepthStencil); + + gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); + ASSERT(drawBuffer); + RenderTarget9 *drawDepthStencil = NULL; - IDirect3DSurface9* readSurface = NULL; - IDirect3DSurface9* drawSurface = NULL; + error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil); + if (error.isError()) + { + return error; + } + ASSERT(drawDepthStencil); - if (readBuffer) - { - readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer); - } - if (drawBuffer) - { - drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer); - } + // The getSurface calls do an AddRef so save them until after no errors are possible + IDirect3DSurface9* readSurface = readDepthStencil->getSurface(); + ASSERT(readDepthStencil); - if (readDepthStencil) - { - readSurface = readDepthStencil->getSurface(); - } - if (drawDepthStencil) - { - drawSurface = drawDepthStencil->getSurface(); - } - - if (!readSurface || !drawSurface) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } + IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface(); + ASSERT(drawDepthStencil); HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE); @@ -2639,38 +2623,31 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle & if (FAILED(result)) { - ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); - return false; + return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); } } - return true; + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, +gl::Error Renderer9::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) { ASSERT(pack.pixelBuffer.get() == NULL); - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *surface = NULL; gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); + ASSERT(colorbuffer); - if (colorbuffer) + RenderTarget9 *renderTarget = NULL; + gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget); + if (error.isError()) { - renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer); + return error; } + ASSERT(renderTarget); - if (renderTarget) - { - surface = renderTarget->getSurface(); - } - - if (!surface) - { - // context must be lost - return gl::Error(GL_NO_ERROR); - } + IDirect3DSurface9 *surface = renderTarget->getSurface(); + ASSERT(surface); D3DSURFACE_DESC desc; surface->GetDesc(&desc); @@ -2825,33 +2802,67 @@ gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, return gl::Error(GL_NO_ERROR); } -RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) +gl::Error Renderer9::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) { SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); - IDirect3DSurface9 *surface = NULL; - if (depth) - { - surface = swapChain9->getDepthStencil(); - } - else - { - surface = swapChain9->getRenderTarget(); - } - - RenderTarget9 *renderTarget = new RenderTarget9(this, surface); - - return renderTarget; + *outRT = new SurfaceRenderTarget9(swapChain9, depth); + return gl::Error(GL_NO_ERROR); } -RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples) +gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) { - RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples); - return renderTarget; + const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format); + + const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); + + IDirect3DSurface9 *renderTarget = NULL; + if (width > 0 && height > 0) + { + bool requiresInitialization = false; + HRESULT result = D3DERR_INVALIDCALL; + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); + if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) + { + result = mDevice->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &renderTarget, NULL); + } + else + { + requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); + result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), + 0, FALSE, &renderTarget, NULL); + } + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target, result: 0x%X.", result); + } + + if (requiresInitialization) + { + // This format requires that the data be initialized before the render target can be used + // Unfortunately this requires a Get call on the d3d device but it is far better than having + // to mark the render target as lockable and copy data to the gpu. + IDirect3DSurface9 *prevRenderTarget = NULL; + mDevice->GetRenderTarget(0, &prevRenderTarget); + mDevice->SetRenderTarget(0, renderTarget); + mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); + mDevice->SetRenderTarget(0, prevRenderTarget); + } + } + + *outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples); + return gl::Error(GL_NO_ERROR); } -ShaderImpl *Renderer9::createShader(GLenum type) +ShaderImpl *Renderer9::createShader(const gl::Data &data, GLenum type) { - return new ShaderD3D(type, this); + return new ShaderD3D(data, type, this); } ProgramImpl *Renderer9::createProgram() @@ -2864,64 +2875,69 @@ void Renderer9::releaseShaderCompiler() ShaderD3D::releaseCompiler(); } -ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers) +gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable) { // Transform feedback is not supported in ES2 or D3D9 ASSERT(transformFeedbackVaryings.size() == 0); - ShaderExecutable9 *executable = NULL; - switch (type) { - case rx::SHADER_VERTEX: + case SHADER_VERTEX: { - IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length); - if (vshader) + IDirect3DVertexShader9 *vshader = NULL; + gl::Error error = createVertexShader((DWORD*)function, length, &vshader); + if (error.isError()) { - executable = new ShaderExecutable9(function, length, vshader); + return error; } + *outExecutable = new ShaderExecutable9(function, length, vshader); } break; - case rx::SHADER_PIXEL: + case SHADER_PIXEL: { - IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length); - if (pshader) + IDirect3DPixelShader9 *pshader = NULL; + gl::Error error = createPixelShader((DWORD*)function, length, &pshader); + if (error.isError()) { - executable = new ShaderExecutable9(function, length, pshader); + return error; } + *outExecutable = new ShaderExecutable9(function, length, pshader); } break; default: UNREACHABLE(); - break; + return gl::Error(GL_INVALID_OPERATION); } - return executable; + return gl::Error(GL_NO_ERROR); } -ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround) +gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable) { // Transform feedback is not supported in ES2 or D3D9 ASSERT(transformFeedbackVaryings.size() == 0); - const char *profile = NULL; - + const char *profileType = NULL; switch (type) { - case rx::SHADER_VERTEX: - profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0"; + case SHADER_VERTEX: + profileType = "vs"; break; - case rx::SHADER_PIXEL: - profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0"; + case SHADER_PIXEL: + profileType = "ps"; break; default: UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } + unsigned int profileMajorVersion = (getMajorShaderModel() >= 3) ? 3 : 2; + unsigned int profileMinorVersion = 0; + std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL; @@ -2942,49 +2958,54 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha #endif flags |= D3DCOMPILE_DEBUG; - - std::string sourcePath = getTempPath(); - std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL); - writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); } // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. // Try the default flags first and if compilation fails, try some alternatives. - const UINT extraFlags[] = - { - flags, - flags | D3DCOMPILE_AVOID_FLOW_CONTROL, - flags | D3DCOMPILE_PREFER_FLOW_CONTROL - }; + std::vector configs; + configs.push_back(CompileConfig(flags, "default" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control" )); + configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control")); - const static char *extraFlagNames[] = + ID3DBlob *binary = NULL; + std::string debugInfo; + gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary, &debugInfo); + if (error.isError()) { - "default", - "avoid flow control", - "prefer flow control" - }; - - int attempts = ArraySize(extraFlags); - - ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts); - if (!binary) - { - return NULL; + return error; } - ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers); - SafeRelease(binary); + // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL + // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK. + if (!binary) + { + *outExectuable = NULL; + return gl::Error(GL_NO_ERROR); + } - return executable; + error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, + transformFeedbackVaryings, separatedOutputBuffers, outExectuable); + + SafeRelease(binary); + if (error.isError()) + { + return error; + } + + if (!debugInfo.empty()) + { + (*outExectuable)->appendDebugInfo(debugInfo); + } + + return gl::Error(GL_NO_ERROR); } -rx::UniformStorage *Renderer9::createUniformStorage(size_t storageSize) +UniformStorage *Renderer9::createUniformStorage(size_t storageSize) { return new UniformStorage(storageSize); } -bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) +gl::Error Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) { return mBlit->boxFilter(source, dest); } @@ -3006,41 +3027,40 @@ D3DPOOL Renderer9::getTexturePool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) +gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) { - if (source && dest) + ASSERT(source && dest); + + HRESULT result = D3DERR_OUTOFVIDEOMEMORY; + + if (fromManaged) { - HRESULT result = D3DERR_OUTOFVIDEOMEMORY; + D3DSURFACE_DESC desc; + source->GetDesc(&desc); - if (fromManaged) + IDirect3DSurface9 *surf = 0; + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + + if (SUCCEEDED(result)) { - D3DSURFACE_DESC desc; - source->GetDesc(&desc); - - IDirect3DSurface9 *surf = 0; - result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); - - if (SUCCEEDED(result)) - { - Image9::copyLockableSurfaces(surf, source); - result = mDevice->UpdateSurface(surf, NULL, dest, NULL); - SafeRelease(surf); - } - } - else - { - endScene(); - result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); - } - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return false; + Image9::copyLockableSurfaces(surf, source); + result = mDevice->UpdateSurface(surf, NULL, dest, NULL); + SafeRelease(surf); } } + else + { + endScene(); + result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); + } - return true; + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit internal texture, result: 0x%X.", result); + } + + return gl::Error(GL_NO_ERROR); } Image *Renderer9::createImage() @@ -3048,11 +3068,11 @@ Image *Renderer9::createImage() return new Image9(); } -void Renderer9::generateMipmap(Image *dest, Image *src) +gl::Error Renderer9::generateMipmap(Image *dest, Image *src) { Image9 *src9 = Image9::makeImage9(src); Image9 *dst9 = Image9::makeImage9(dest); - Image9::generateMipmap(dst9, src9); + return Image9::generateMipmap(dst9, src9); } TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain) @@ -3099,6 +3119,19 @@ TextureImpl *Renderer9::createTexture(GLenum target) return NULL; } +RenderbufferImpl *Renderer9::createRenderbuffer() +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + return renderbuffer; +} + +RenderbufferImpl *Renderer9::createRenderbuffer(SwapChain *swapChain, bool depth) +{ + RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); + renderbuffer->setStorage(swapChain, depth); + return renderbuffer; +} + bool Renderer9::getLUID(LUID *adapterLuid) const { adapterLuid->HighPart = 0; @@ -3113,7 +3146,7 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } -rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const { return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType; } @@ -3128,4 +3161,9 @@ void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCa d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, outExtensions); } +Workarounds Renderer9::generateWorkarounds() const +{ + return d3d9::GenerateWorkarounds(); +} + } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h index dd5f30268a..10d2fb11e8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h @@ -11,10 +11,10 @@ #include "common/angleutils.h" #include "common/mathutil.h" -#include "libGLESv2/renderer/d3d/HLSLCompiler.h" #include "libGLESv2/renderer/d3d/d3d9/ShaderCache.h" #include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h" -#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d/HLSLCompiler.h" +#include "libGLESv2/renderer/d3d/RendererD3D.h" #include "libGLESv2/renderer/RenderTarget.h" namespace gl @@ -22,6 +22,11 @@ namespace gl class FramebufferAttachment; } +namespace egl +{ +class AttributeMap; +} + namespace rx { class VertexDataManager; @@ -31,10 +36,10 @@ class StaticIndexBufferInterface; struct TranslatedAttribute; class Blit9; -class Renderer9 : public Renderer +class Renderer9 : public RendererD3D { public: - Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay); + Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes); virtual ~Renderer9(); static Renderer9 *makeRenderer9(Renderer *renderer); @@ -48,27 +53,27 @@ class Renderer9 : public Renderer void startScene(); void endScene(); - virtual void sync(bool block); + virtual gl::Error sync(bool block); - virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); - IDirect3DQuery9* allocateEventQuery(); + gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery); void freeEventQuery(IDirect3DQuery9* query); // resource creation - IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length); - IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length); + gl::Error createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader); + gl::Error createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader); HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); virtual gl::Error generateSwizzle(gl::Texture *texture); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]); virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); - virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask); + gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, + unsigned int sampleMask) override; virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, int stencilBackRef, bool frontFaceCCW); @@ -76,35 +81,35 @@ class Renderer9 : public Renderer virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport); - virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer); + gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, bool rasterizerDiscard, bool transformFeedbackActive); - virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary); + virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector &uniformArray); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); - virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], - GLint first, GLsizei count, GLsizei instances); + virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances); virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); + virtual void applyTransformFeedbackBuffers(const gl::State& state); virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive); virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override; virtual void markAllStateDirty(); // lost device - void notifyDeviceLost(); - virtual bool isDeviceLost(); - virtual bool testDeviceLost(bool notify); - virtual bool testDeviceResettable(); + void notifyDeviceLost() override; + bool isDeviceLost() override; + bool testDeviceLost(bool notify) override; + bool testDeviceResettable() override; + + DWORD getAdapterVendor() const override; + std::string getRendererDescription() const override; + GUID getAdapterIdentifier() const override; IDirect3DDevice9 *getDevice() { return mDevice; } - virtual DWORD getAdapterVendor() const; - virtual std::string getRendererDescription() const; - virtual GUID getAdapterIdentifier() const; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; @@ -119,47 +124,45 @@ class Renderer9 : public Renderer virtual int getMaxSwapInterval() const; // Pixel operations - virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source); - virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source); - virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source); - virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source); - - virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); - virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); - virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); - virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level); + virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level); + virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); + virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level); - virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter); + gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, + const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + const gl::Rectangle *scissor, bool blitRenderTarget, + bool blitDepth, bool blitStencil, GLenum filter) override; - virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); // RenderTarget creation - virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples); + virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT); + virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT); // Shader creation - virtual ShaderImpl *createShader(GLenum type); + virtual ShaderImpl *createShader(const gl::Data &data, GLenum type); virtual ProgramImpl *createProgram(); // Shader operations - virtual void releaseShaderCompiler(); - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers); - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, D3DWorkaroundType workaround); + void releaseShaderCompiler() override; + virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, ShaderExecutable **outExecutable); + virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, + const std::vector &transformFeedbackVaryings, + bool separatedOutputBuffers, D3DWorkaroundType workaround, + ShaderExecutable **outExectuable); virtual UniformStorage *createUniformStorage(size_t storageSize); // Image operations virtual Image *createImage(); - virtual void generateMipmap(Image *dest, Image *source); + gl::Error generateMipmap(Image *dest, Image *source) override; virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels); @@ -169,6 +172,10 @@ class Renderer9 : public Renderer // Texture creation virtual TextureImpl *createTexture(GLenum target); + // Renderbuffer creation + virtual RenderbufferImpl *createRenderbuffer(); + virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth); + // Buffer creation virtual BufferImpl *createBuffer(); virtual VertexBuffer *createVertexBuffer(); @@ -179,29 +186,33 @@ class Renderer9 : public Renderer // Query and Fence creation virtual QueryImpl *createQuery(GLenum type); - virtual FenceImpl *createFence(); + virtual FenceNVImpl *createFenceNV(); + virtual FenceSyncImpl *createFenceSync(); // Transform Feedback creation virtual TransformFeedbackImpl* createTransformFeedback(); // Buffer-to-texture and Texture-to-buffer copies virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, + GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); // D3D9-renderer specific methods - bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); + gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); D3DPOOL getTexturePool(DWORD usage) const; virtual bool getLUID(LUID *adapterLuid) const; - virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; + virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; + gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); + private: DISALLOW_COPY_AND_ASSIGN(Renderer9); - virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const; + void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override; + Workarounds generateWorkarounds() const override; void release(); @@ -214,8 +225,7 @@ class Renderer9 : public Renderer gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB); - bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); - gl::FramebufferAttachment *getNullColorbuffer(gl::FramebufferAttachment *depthbuffer); + gl::Error getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer); D3DPOOL getBufferPool(DWORD usage) const; @@ -263,7 +273,7 @@ class Renderer9 : public Renderer unsigned int mAppliedStencilbufferSerial; bool mDepthStencilInitialized; bool mRenderTargetDescInitialized; - rx::RenderTarget::Desc mRenderTargetDesc; + RenderTarget::Desc mRenderTargetDesc; unsigned int mCurStencilSize; unsigned int mCurDepthSize; @@ -310,8 +320,8 @@ class Renderer9 : public Renderer IDirect3DPixelShader9 *mAppliedPixelShader; unsigned int mAppliedProgramSerial; - rx::dx_VertexConstants mVertexConstants; - rx::dx_PixelConstants mPixelConstants; + dx_VertexConstants mVertexConstants; + dx_PixelConstants mPixelConstants; bool mDxUniformsDirty; // A pool of event queries that are currently unused. diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h index 2ad3022839..6d7d2d648f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h @@ -10,6 +10,8 @@ #ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_ #define LIBGLESV2_RENDERER_SHADER_CACHE_H_ +#include "libGLESv2/Error.h" + #include "common/debug.h" #include @@ -37,21 +39,22 @@ class ShaderCache mDevice = device; } - ShaderObject *create(const DWORD *function, size_t length) + gl::Error create(const DWORD *function, size_t length, ShaderObject **outShaderObject) { std::string key(reinterpret_cast(function), length); typename Map::iterator it = mMap.find(key); if (it != mMap.end()) { it->second->AddRef(); - return it->second; + *outShaderObject = it->second; + return gl::Error(GL_NO_ERROR); } ShaderObject *shader; HRESULT result = createShader(function, &shader); if (FAILED(result)) { - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader, result: 0x%X.", result); } // Random eviction policy. @@ -64,7 +67,8 @@ class ShaderCache shader->AddRef(); mMap[key] = shader; - return shader; + *outShaderObject = shader; + return gl::Error(GL_NO_ERROR); } void clear() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp index 0aeaabb1ca..95eb1a4371 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp @@ -11,12 +11,15 @@ #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" +#include "common/features.h" + namespace rx { -SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle, +SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) + : mRenderer(renderer), + SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat) { mSwapChain = NULL; mBackBuffer = NULL; @@ -41,7 +44,7 @@ void SwapChain9::release() SafeRelease(mRenderTarget); SafeRelease(mOffscreenTexture); - if (mWindow) + if (mNativeWindow.getNativeWindow()) { mShareHandle = NULL; } @@ -49,7 +52,7 @@ void SwapChain9::release() static DWORD convertInterval(EGLint interval) { -#ifdef ANGLE_FORCE_VSYNC_OFF +#if ANGLE_VSYNC == ANGLE_DISABLED return D3DPRESENT_INTERVAL_IMMEDIATE; #else switch(interval) @@ -95,7 +98,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI SafeRelease(mDepthStencil); HANDLE *pShareHandle = NULL; - if (!mWindow && mRenderer->getShareHandleSupport()) + if (!mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport()) { pShareHandle = &mShareHandle; } @@ -152,7 +155,8 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat); - if (mWindow) + EGLNativeWindowType window = mNativeWindow.getNativeWindow(); + if (window) { D3DPRESENT_PARAMETERS presentParameters = {0}; presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat; @@ -160,7 +164,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat; presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; - presentParameters.hDeviceWindow = mWindow; + presentParameters.hDeviceWindow = window; presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = convertInterval(swapInterval); @@ -203,7 +207,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); ASSERT(SUCCEEDED(result)); - InvalidateRect(mWindow, NULL, FALSE); + InvalidateRect(window, NULL, FALSE); } if (mDepthBufferFormat != GL_NONE) @@ -238,7 +242,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI } // parameters should be validated/clamped by caller -EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint) +EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { @@ -379,8 +383,8 @@ IDirect3DTexture9 *SwapChain9::getOffscreenTexture() SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain) { - ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain)); - return static_cast(swapChain); + ASSERT(HAS_DYNAMIC_TYPE(SwapChain9*, swapChain)); + return static_cast(swapChain); } void SwapChain9::recreate() diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h index 4d756f80d1..cb33bfbc0c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h @@ -19,19 +19,22 @@ class Renderer9; class SwapChain9 : public SwapChain { public: - SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle, + SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); virtual ~SwapChain9(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint); + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); virtual void recreate(); virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getDepthStencil(); virtual IDirect3DTexture9 *getOffscreenTexture(); + EGLint getWidth() const { return mWidth; } + EGLint getHeight() const { return mHeight; } + static SwapChain9 *makeSwapChain9(SwapChain *swapChain); private: diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp index f44e33db18..0ff4fd3b0f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp @@ -20,8 +20,13 @@ namespace rx { -TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage) +TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage) : mTopLevel(0), + mMipLevels(0), + mTextureWidth(0), + mTextureHeight(0), + mInternalFormat(GL_NONE), + mTextureFormat(D3DFMT_UNKNOWN), mRenderer(Renderer9::makeRenderer9(renderer)), mD3DUsage(usage), mD3DPool(mRenderer->getTexturePool(usage)) @@ -84,44 +89,52 @@ int TextureStorage9::getTopLevel() const int TextureStorage9::getLevelCount() const { - return getBaseTexture() ? (getBaseTexture()->GetLevelCount() - getTopLevel()) : 0; + return mMipLevels - mTopLevel; } -TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) +gl::Error TextureStorage9::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type, + const gl::PixelUnpackState &unpack, const uint8_t *pixelData) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET) { IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture(); mTexture = surfaceTexture; + mMipLevels = surfaceTexture->GetLevelCount(); + + mInternalFormat = swapchain->GetBackBufferInternalFormat(); + + D3DSURFACE_DESC surfaceDesc; + surfaceTexture->GetLevelDesc(0, &surfaceDesc); + mTextureWidth = surfaceDesc.Width; + mTextureHeight = surfaceDesc.Height; + mTextureFormat = surfaceDesc.Format; + mRenderTarget = NULL; - initializeRenderTarget(); initializeSerials(1, 1); } -TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) +TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { mTexture = NULL; mRenderTarget = NULL; - // if the width or height is not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (width > 0 && height > 0) - { - IDirect3DDevice9 *device = mRenderer->getDevice(); - const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); - d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel); - UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; - HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL); + mInternalFormat = internalformat; - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - gl::error(GL_OUT_OF_MEMORY); - } - } + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + mTextureFormat = d3dFormatInfo.texFormat; + + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel); + mTextureWidth = width; + mTextureHeight = height; + mMipLevels = mTopLevel + levels; - initializeRenderTarget(); initializeSerials(getLevelCount(), 1); } @@ -139,104 +152,168 @@ TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *s // Increments refcount on surface. // caller must Release() the returned surface -IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) +gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface) { - IDirect3DSurface9 *surface = NULL; - - if (mTexture) + IDirect3DBaseTexture9 *baseTexture = NULL; + gl::Error error = getBaseTexture(&baseTexture); + if (error.isError()) { - HRESULT result = mTexture->GetSurfaceLevel(level + mTopLevel, &surface); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); - - // With managed textures the driver needs to be informed of updates to the lower mipmap levels - if (level + mTopLevel != 0 && isManaged() && dirty) - { - mTexture->AddDirtyRect(NULL); - } + return error; } - return surface; -} + IDirect3DTexture9 *texture = static_cast(baseTexture); -RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/) -{ - return mRenderTarget; -} + HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface); -void TextureStorage9_2D::generateMipmaps() -{ - // Base level must already be defined - - for (int level = 1; level < getLevelCount(); level++) + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) { - IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false); - IDirect3DSurface9 *lower = getSurfaceLevel(level, true); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result); + } - if (upper != NULL && lower != NULL) + // With managed textures the driver needs to be informed of updates to the lower mipmap levels + if (level + mTopLevel != 0 && isManaged() && dirty) + { + texture->AddDirtyRect(NULL); + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTarget **outRT) +{ + if (!mRenderTarget && isRenderTarget()) + { + IDirect3DSurface9 *surface = NULL; + gl::Error error = getSurfaceLevel(0, false, &surface); + if (error.isError()) { - mRenderer->boxFilter(upper, lower); + return error; } + mRenderTarget = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0); + } + + ASSERT(outRT); + *outRT = mRenderTarget; + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +{ + IDirect3DSurface9 *upper = NULL; + gl::Error error = getSurfaceLevel(sourceIndex.mipIndex, false, &upper); + if (error.isError()) + { + return error; + } + + IDirect3DSurface9 *lower = NULL; + error = getSurfaceLevel(destIndex.mipIndex, true, &lower); + if (error.isError()) + { SafeRelease(upper); - SafeRelease(lower); - } -} - -IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const -{ - return mTexture; -} - -void TextureStorage9_2D::initializeRenderTarget() -{ - ASSERT(mRenderTarget == NULL); - - if (mTexture != NULL && isRenderTarget()) - { - IDirect3DSurface9 *surface = getSurfaceLevel(0, false); - - mRenderTarget = new RenderTarget9(mRenderer, surface); - } -} - -TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels) - : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) -{ - mTexture = NULL; - for (int i = 0; i < 6; ++i) - { - mRenderTarget[i] = NULL; + return error; } - // if the size is not positive this should be treated as an incomplete texture + ASSERT(upper && lower); + error = mRenderer->boxFilter(upper, lower); + + SafeRelease(upper); + SafeRelease(lower); + + return error; +} + +gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +{ + // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (size > 0) + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) { - IDirect3DDevice9 *device = mRenderer->getDevice(); - int height = size; - const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); - d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel); - UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; + ASSERT(mMipLevels > 0); - HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL); + IDirect3DDevice9 *device = mRenderer->getDevice(); + HRESULT result = device->CreateTexture(mTextureWidth, mTextureHeight, mMipLevels, getUsage(), mTextureFormat, + getPool(), &mTexture, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D storage texture, result: 0x%X.", result); } } - initializeRenderTarget(); - initializeSerials(getLevelCount() * 6, 6); + *outTexture = mTexture; + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) +{ + ASSERT(destStorage); + + TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(destStorage); + + int levels = getLevelCount(); + for (int i = 0; i < levels; ++i) + { + IDirect3DSurface9 *srcSurf = NULL; + gl::Error error = getSurfaceLevel(i, false, &srcSurf); + if (error.isError()) + { + return error; + } + + IDirect3DSurface9 *dstSurf = NULL; + error = dest9->getSurfaceLevel(i, true, &dstSurf); + if (error.isError()) + { + SafeRelease(srcSurf); + return error; + } + + error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged()); + + SafeRelease(srcSurf); + SafeRelease(dstSurf); + + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels) + : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) +{ + mTexture = NULL; + for (int i = 0; i < CUBE_FACE_COUNT; ++i) + { + mRenderTarget[i] = NULL; + } + + mInternalFormat = internalformat; + + const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); + mTextureFormat = d3dFormatInfo.texFormat; + + int height = size; + d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel); + mTextureWidth = size; + mTextureHeight = size; + mMipLevels = mTopLevel + levels; + + initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT); } TextureStorage9_Cube::~TextureStorage9_Cube() { SafeRelease(mTexture); - for (int i = 0; i < 6; ++i) + for (int i = 0; i < CUBE_FACE_COUNT; ++i) { SafeDelete(mRenderTarget[i]); } @@ -250,74 +327,146 @@ TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStor // Increments refcount on surface. // caller must Release() the returned surface -IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty) +gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface) { - IDirect3DSurface9 *surface = NULL; - - if (mTexture) + IDirect3DBaseTexture9 *baseTexture = NULL; + gl::Error error = getBaseTexture(&baseTexture); + if (error.isError()) { - D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); - HRESULT result = mTexture->GetCubeMapSurface(face, level + mTopLevel, &surface); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); - - // With managed textures the driver needs to be informed of updates to the lower mipmap levels - if (level != 0 && isManaged() && dirty) - { - mTexture->AddDirtyRect(face, NULL); - } + return error; } - return surface; -} + IDirect3DCubeTexture9 *texture = static_cast(baseTexture); -RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index) -{ - return mRenderTarget[index.layerIndex]; -} + D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); + HRESULT result = texture->GetCubeMapSurface(face, level + mTopLevel, outSurface); -void TextureStorage9_Cube::generateMipmaps() -{ - // Base level must already be defined - - for (int faceIndex = 0; faceIndex < 6; faceIndex++) + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) { - for (int level = 1; level < getLevelCount(); level++) - { - IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false); - IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true); - - if (upper != NULL && lower != NULL) - { - mRenderer->boxFilter(upper, lower); - } - - SafeRelease(upper); - SafeRelease(lower); - } + return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result); } + + // With managed textures the driver needs to be informed of updates to the lower mipmap levels + if (level != 0 && isManaged() && dirty) + { + texture->AddDirtyRect(face, NULL); + } + + return gl::Error(GL_NO_ERROR); } -IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const +gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) { - return mTexture; -} + ASSERT(outRT); + ASSERT(index.mipIndex == 0); + ASSERT(index.layerIndex >= 0 && index.layerIndex < CUBE_FACE_COUNT); -void TextureStorage9_Cube::initializeRenderTarget() -{ - if (mTexture != NULL && isRenderTarget()) + if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget()) { IDirect3DSurface9 *surface = NULL; - - for (int i = 0; i < 6; ++i) + gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, 0, false, &surface); + if (error.isError()) { - ASSERT(mRenderTarget[i] == NULL); - - surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false); - - mRenderTarget[i] = new RenderTarget9(mRenderer, surface); + return error; } + + mRenderTarget[index.layerIndex] = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0); } + + *outRT = mRenderTarget[index.layerIndex]; + return gl::Error(GL_NO_ERROR); } -} \ No newline at end of file +gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +{ + IDirect3DSurface9 *upper = NULL; + gl::Error error = getCubeMapSurface(sourceIndex.type, sourceIndex.mipIndex, false, &upper); + if (error.isError()) + { + return error; + } + + IDirect3DSurface9 *lower = NULL; + error = getCubeMapSurface(destIndex.type, destIndex.mipIndex, true, &lower); + if (error.isError()) + { + SafeRelease(upper); + return error; + } + + ASSERT(upper && lower); + error = mRenderer->boxFilter(upper, lower); + + SafeRelease(upper); + SafeRelease(lower); + + return error; +} + +gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +{ + // if the size is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + { + ASSERT(mMipLevels > 0); + ASSERT(mTextureWidth == mTextureHeight); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + HRESULT result = device->CreateCubeTexture(mTextureWidth, mMipLevels, getUsage(), mTextureFormat, getPool(), + &mTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube storage texture, result: 0x%X.", result); + } + } + + *outTexture = mTexture; + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) +{ + ASSERT(destStorage); + + TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(destStorage); + + int levels = getLevelCount(); + for (int f = 0; f < CUBE_FACE_COUNT; f++) + { + for (int i = 0; i < levels; i++) + { + IDirect3DSurface9 *srcSurf = NULL; + gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); + if (error.isError()) + { + return error; + } + + IDirect3DSurface9 *dstSurf = NULL; + error = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf); + if (error.isError()) + { + SafeRelease(srcSurf); + return error; + } + + error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged()); + + SafeRelease(srcSurf); + SafeRelease(dstSurf); + + if (error.isError()) + { + return error; + } + } + } + + return gl::Error(GL_NO_ERROR); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h index e698c7dd56..da0e1f2f18 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h @@ -33,20 +33,28 @@ class TextureStorage9 : public TextureStorage D3DPOOL getPool() const; DWORD getUsage() const; - virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; - virtual void generateMipmaps() = 0; + virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0; + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0; virtual int getTopLevel() const; virtual bool isRenderTarget() const; virtual bool isManaged() const; virtual int getLevelCount() const; + virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type, + const gl::PixelUnpackState &unpack, const uint8_t *pixelData); + protected: int mTopLevel; + size_t mMipLevels; + size_t mTextureWidth; + size_t mTextureHeight; + GLenum mInternalFormat; + D3DFORMAT mTextureFormat; + Renderer9 *mRenderer; - TextureStorage9(Renderer *renderer, DWORD usage); + TextureStorage9(Renderer9 *renderer, DWORD usage); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9); @@ -58,22 +66,21 @@ class TextureStorage9 : public TextureStorage class TextureStorage9_2D : public TextureStorage9 { public: - TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain); - TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); + TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain); + TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual ~TextureStorage9_2D(); static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage); - IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty); - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmaps(); + gl::Error getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); + virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); + virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); + virtual gl::Error copyToStorage(TextureStorage *destStorage); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D); - void initializeRenderTarget(); - IDirect3DTexture9 *mTexture; RenderTarget9 *mRenderTarget; }; @@ -81,23 +88,24 @@ class TextureStorage9_2D : public TextureStorage9 class TextureStorage9_Cube : public TextureStorage9 { public: - TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels); + TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels); virtual ~TextureStorage9_Cube(); static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage); - IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty); - virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); - virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmaps(); + gl::Error getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface); + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT); + virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); + virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); + virtual gl::Error copyToStorage(TextureStorage *destStorage); private: DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube); - void initializeRenderTarget(); + static const size_t CUBE_FACE_COUNT = 6; IDirect3DCubeTexture9 *mTexture; - RenderTarget9 *mRenderTarget[6]; + RenderTarget9 *mRenderTarget[CUBE_FACE_COUNT]; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h index 66a6c64d81..791c108462 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h @@ -19,7 +19,7 @@ class Renderer9; class VertexArray9 : public VertexArrayImpl { public: - VertexArray9(rx::Renderer9 *renderer) + VertexArray9(Renderer9 *renderer) : VertexArrayImpl(), mRenderer(renderer) { @@ -35,7 +35,7 @@ class VertexArray9 : public VertexArrayImpl private: DISALLOW_COPY_AND_ASSIGN(VertexArray9); - rx::Renderer9 *mRenderer; + Renderer9 *mRenderer; }; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp index 4cf7779118..b90133097c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -10,14 +10,14 @@ #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" #include "libGLESv2/renderer/vertexconversion.h" -#include "libGLESv2/renderer/BufferImpl.h" +#include "libGLESv2/renderer/d3d/BufferD3D.h" #include "libGLESv2/VertexAttribute.h" #include "libGLESv2/Buffer.h" namespace rx { -VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer) +VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer) { mVertexBuffer = NULL; mBufferSize = 0; @@ -97,8 +97,14 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib { if (buffer) { - BufferImpl *storage = buffer->getImplementation(); - input = static_cast(storage->getData()) + static_cast(attrib.offset); + BufferD3D *storage = BufferD3D::makeFromBuffer(buffer); + ASSERT(storage); + gl::Error error = storage->getData(&input); + if (error.isError()) + { + return error; + } + input += static_cast(attrib.offset); } else { @@ -203,7 +209,7 @@ gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::s else { // Round up to divisor, if possible - elementCount = rx::UnsignedCeilDivide(static_cast(instances), attrib.divisor); + elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); } if (d3d9VertexInfo.outputElementSize <= std::numeric_limits::max() / elementCount) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h index bdcf4bb64a..9af2b98a6e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h @@ -18,7 +18,7 @@ class Renderer9; class VertexBuffer9 : public VertexBuffer { public: - explicit VertexBuffer9(rx::Renderer9 *renderer); + explicit VertexBuffer9(Renderer9 *renderer); virtual ~VertexBuffer9(); virtual gl::Error initialize(unsigned int size, bool dynamicUsage); @@ -39,7 +39,7 @@ class VertexBuffer9 : public VertexBuffer private: DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); - rx::Renderer9 *mRenderer; + Renderer9 *mRenderer; IDirect3DVertexBuffer9 *mVertexBuffer; unsigned int mBufferSize; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp index e7a91e62d6..a98b2081f3 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp @@ -9,6 +9,7 @@ #include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" #include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/renderer/Workarounds.h" #include "libGLESv2/formatutils.h" #include "libGLESv2/Framebuffer.h" #include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h" @@ -390,8 +391,9 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT caps->maxVertexUniformBlocks = 0; - const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 10; - const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 8; + // SM3 only supports 11 output variables, with a special 12th register for PSIZE. + const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 9; + const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 7; caps->maxVertexOutputComponents = ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3 : MAX_VERTEX_OUTPUT_VECTORS_SM2) * 4; @@ -459,7 +461,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && - !(isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD); + !(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD); } else { @@ -531,10 +533,24 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize *levelOffset = upsampleCount; } -RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT) { - RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); - return RenderTarget9::makeRenderTarget9(renderTarget); + RenderTarget *renderTarget = NULL; + gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget); + if (error.isError()) + { + return error; + } + *outRT = RenderTarget9::makeRenderTarget9(renderTarget); + return gl::Error(GL_NO_ERROR); +} + +Workarounds GenerateWorkarounds() +{ + Workarounds workarounds; + workarounds.mrtPerfWorkaround = true; + workarounds.setDataFasterThanImageUpload = false; + return workarounds; } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h index b0a940e60a..9760b9735a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h @@ -12,6 +12,7 @@ #include "libGLESv2/angletypes.h" #include "libGLESv2/Caps.h" +#include "libGLESv2/Error.h" namespace gl { @@ -21,6 +22,7 @@ class FramebufferAttachment; namespace rx { class RenderTarget9; +struct Workarounds; namespace gl_d3d9 { @@ -74,7 +76,8 @@ inline bool isDeviceLostError(HRESULT errorCode) } } -RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment); +gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT); +Workarounds GenerateWorkarounds(); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp index f777b30be6..159b4c7e9f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp @@ -10,10 +10,6 @@ #include "libGLESv2/renderer/loadimage.h" -#if !defined(__SSE2__) && (defined(_M_X64) || _M_IX86_FP == 2) -#define __SSE2__ -#endif - namespace rx { @@ -21,7 +17,12 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { -#ifdef __SSE2__ +#if defined(_M_ARM) + // Ensure that this function is reported as not implemented for ARM builds because + // the instructions below are not present for that architecture. + UNIMPLEMENTED(); + return; +#else __m128i zeroWide = _mm_setzero_si128(); for (size_t z = 0; z < depth; z++) @@ -66,7 +67,12 @@ void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) { -#ifdef __SSE2__ +#if defined(_M_ARM) + // Ensure that this function is reported as not implemented for ARM builds because + // the instructions below are not present for that architecture. + UNIMPLEMENTED(); + return; +#else __m128i brMask = _mm_set1_epi32(0x00ff00ff); for (size_t z = 0; z < depth; z++) diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.cpp b/src/3rdparty/angle/src/libGLESv2/validationES.cpp index f79bc97e4f..265f4b4fba 100644 --- a/src/3rdparty/angle/src/libGLESv2/validationES.cpp +++ b/src/3rdparty/angle/src/libGLESv2/validationES.cpp @@ -24,6 +24,9 @@ #include "common/mathutil.h" #include "common/utilities.h" +// FIXME(jmadill): remove this when we support buffer data caching +#include "libGLESv2/renderer/d3d/BufferD3D.h" + namespace gl { @@ -497,14 +500,26 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); gl::Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer(); - if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE || - !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + + if (!readFramebuffer || !drawFramebuffer) { context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; } - if (drawFramebuffer->getSamples() != 0) + if (!readFramebuffer->completeness(context->getData())) + { + context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + return false; + } + + if (!drawFramebuffer->completeness(context->getData())) + { + context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + return false; + } + + if (drawFramebuffer->getSamples(context->getData()) != 0) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -588,16 +603,20 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint return false; } - if (attachment->getActualFormat() != readColorBuffer->getActualFormat()) + // Return an error if the destination formats do not match + if (attachment->getInternalFormat() != readColorBuffer->getInternalFormat()) { context->recordError(Error(GL_INVALID_OPERATION)); return false; } } } - if (readFramebuffer->getSamples() != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1)) + + int readSamples = readFramebuffer->getSamples(context->getData()); + + if (readSamples != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1)) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -912,13 +931,14 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); ASSERT(framebuffer); - if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; } - if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0) + if (context->getState().getReadFramebuffer()->id() != 0 && + framebuffer->getSamples(context->getData()) != 0) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -1172,7 +1192,7 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, { Framebuffer *framebuffer = context->getState().getReadFramebuffer(); ASSERT(framebuffer); - if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -1236,13 +1256,13 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi } gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; } - if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0) + if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples(context->getData()) != 0) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -1441,7 +1461,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz } const gl::Framebuffer *fbo = state.getDrawFramebuffer(); - if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (!fbo || fbo->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; @@ -1667,11 +1687,20 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t // TODO: also disable index checking on back-ends that are robust to out-of-range accesses. if (elementArrayBuffer) { - GLint64 offset = reinterpret_cast(indices); + uintptr_t offset = reinterpret_cast(indices); if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL)) { - const void *dataPointer = elementArrayBuffer->getImplementation()->getData(); - const uint8_t *offsetPointer = static_cast(dataPointer) + offset; + // FIXME(jmadill): Use buffer data caching instead of the D3D back-end + rx::BufferD3D *bufferD3D = rx::BufferD3D::makeBufferD3D(elementArrayBuffer->getImplementation()); + const uint8_t *dataPointer = NULL; + Error error = bufferD3D->getData(&dataPointer); + if (error.isError()) + { + context->recordError(error); + return false; + } + + const uint8_t *offsetPointer = dataPointer + offset; *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, offsetPointer, count); } } @@ -1850,6 +1879,11 @@ bool ValidateGetUniformBase(Context *context, GLuint program, GLint location) return false; } + if (!ValidProgram(context, program)) + { + return false; + } + gl::Program *programObject = context->getProgram(program); if (!programObject || !programObject->isLinked()) diff --git a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp b/src/3rdparty/angle/src/libGLESv2/validationES3.cpp index 251c6ad2c4..2d3a039e13 100644 --- a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp +++ b/src/3rdparty/angle/src/libGLESv2/validationES3.cpp @@ -542,7 +542,8 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, return false; } - size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes; + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat); + size_t copyBytes = formatInfo.computeBlockSize(type, width, height); size_t offset = reinterpret_cast(pixels); if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) || @@ -555,12 +556,15 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, // ...data is not evenly divisible into the number of bytes needed to store in memory a datum // indicated by type. - size_t dataBytesPerPixel = static_cast(gl::GetTypeInfo(type).bytes); - - if ((offset % dataBytesPerPixel) != 0) + if (!isCompressed) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; + size_t dataBytesPerPixel = static_cast(gl::GetTypeInfo(type).bytes); + + if ((offset % dataBytesPerPixel) != 0) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } } // ...the buffer object's data store is currently mapped. @@ -872,13 +876,14 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; } - if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0) + if (context->getState().getReadFramebuffer()->id() != 0 && + framebuffer->getSamples(context->getData()) != 0) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -1258,7 +1263,7 @@ bool ValidateClearBuffer(Context *context) } const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer(); - if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE) + if (!fbo || fbo->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; diff --git a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp index 19a9644d70..97dfcaac51 100644 --- a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp +++ b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp @@ -24,6 +24,7 @@ */ #include +#include "common/platform.h" #if _WIN32_WINNT_WINBLUE #include @@ -52,7 +53,11 @@ bool isWindowsVistaOrGreater() if (!initialized) { initialized = true; +#if defined(ANGLE_ENABLE_WINDOWS_STORE) + cachedIsWindowsVistaOrGreater = true; +#else cachedIsWindowsVistaOrGreater = IsWindowsVistaOrGreater(); +#endif } return cachedIsWindowsVistaOrGreater; } diff --git a/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch b/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch index d5e3697c4f..ad3187ec7c 100644 --- a/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch +++ b/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch @@ -1,178 +1,49 @@ -From f409f6837ce80d722eb6d2ff178b61b713d3e8c7 Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Thu, 25 Sep 2014 13:23:19 +0300 +From bd27c33a4a7c48bd14b9b6c18c8cdce1c3aae155 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Fri, 14 Nov 2014 10:53:40 +0200 Subject: [PATCH] General fixes for ANGLE 2.1 - Fix commit.h include (use hard-coded version) -- Fix undefined intptr_t in egl.h and eglext.h - Fix export mismatch in libEGL.cpp and libGLESv2.cpp -- Remove D3D9 d3dcompiler.h include requirement in the translator - Normalize all precompiled shader names and includes - Remove third-party event tracing; it was hardly used in ANGLE and not enabled in Qt builds anyway. Change-Id: I22254aed62e89a26756ca0784bae95909189c0f9 --- - src/3rdparty/angle/include/EGL/egl.h | 2 +- - src/3rdparty/angle/include/EGL/eglext.h | 2 +- - src/3rdparty/angle/src/common/event_tracer.cpp | 49 -- - src/3rdparty/angle/src/common/event_tracer.h | 43 -- - src/3rdparty/angle/src/common/version.h | 2 +- - src/3rdparty/angle/src/libEGL/libEGL.cpp | 3 + - src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 5 + - src/3rdparty/angle/src/libGLESv2/libGLESv2.def | 3 - - .../angle/src/libGLESv2/libGLESv2_mingw32.def | 3 - - src/3rdparty/angle/src/libGLESv2/libGLESv2d.def | 3 - - .../angle/src/libGLESv2/libGLESv2d_mingw32.def | 3 - - .../angle/src/libGLESv2/renderer/Renderer.cpp | 1 - - .../angle/src/libGLESv2/renderer/SwapChain.h | 4 - - .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 6 +- - .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 66 +- - .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 12 +- - .../renderer/d3d/d3d11/PixelTransfer11.cpp | 10 +- - .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 4 +- - .../renderer/d3d/d3d11/shaders/Clear11.hlsl | 4 + - .../src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp | 20 +- - .../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 12 - - .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps | 6 +- - .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs | 4 +- - .../src/third_party/trace_event/trace_event.h | 826 --------------------- - src/angle/src/common/common.pri | 2 - - 25 files changed, 80 insertions(+), 1015 deletions(-) - delete mode 100644 src/3rdparty/angle/src/common/event_tracer.cpp - delete mode 100644 src/3rdparty/angle/src/common/event_tracer.h - delete mode 100644 src/3rdparty/angle/src/third_party/trace_event/trace_event.h + src/3rdparty/angle/src/commit.h | 6 +- + src/3rdparty/angle/src/common/version.h | 2 +- + .../src/common/winrt/CoreWindowNativeWindow.cpp | 2 +- + src/3rdparty/angle/src/libEGL/libEGL.cpp | 3 + + src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 4 ++ + src/3rdparty/angle/src/libGLESv2/libGLESv2.def | 3 - + .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 3 - + .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 66 +++++++++++----------- + .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 12 ++-- + .../renderer/d3d/d3d11/PixelTransfer11.cpp | 10 ++-- + .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 4 +- + .../renderer/d3d/d3d11/shaders/Clear11.hlsl | 4 ++ + .../src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp | 20 +++---- + .../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 12 ---- + .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps | 6 +- + .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs | 4 +- + 16 files changed, 76 insertions(+), 85 deletions(-) -diff --git a/src/3rdparty/angle/include/EGL/egl.h b/src/3rdparty/angle/include/EGL/egl.h -index 12590a0..ab2f0cd 100644 ---- a/src/3rdparty/angle/include/EGL/egl.h -+++ b/src/3rdparty/angle/include/EGL/egl.h -@@ -238,7 +238,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); - #ifndef EGL_VERSION_1_5 - #define EGL_VERSION_1_5 1 - typedef void *EGLSync; --typedef intptr_t EGLAttrib; -+typedef khronos_intptr_t EGLAttrib; - typedef khronos_utime_nanoseconds_t EGLTime; - #define EGL_CONTEXT_MAJOR_VERSION 0x3098 - #define EGL_CONTEXT_MINOR_VERSION 0x30FB -diff --git a/src/3rdparty/angle/include/EGL/eglext.h b/src/3rdparty/angle/include/EGL/eglext.h -index 9e29605..989359b 100644 ---- a/src/3rdparty/angle/include/EGL/eglext.h -+++ b/src/3rdparty/angle/include/EGL/eglext.h -@@ -59,7 +59,7 @@ extern "C" { - #ifndef EGL_KHR_cl_event2 - #define EGL_KHR_cl_event2 1 - typedef void *EGLSyncKHR; --typedef intptr_t EGLAttribKHR; -+typedef khronos_intptr_t EGLAttribKHR; - typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); - #ifdef EGL_EGLEXT_PROTOTYPES - EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); -diff --git a/src/3rdparty/angle/src/common/event_tracer.cpp b/src/3rdparty/angle/src/common/event_tracer.cpp -deleted file mode 100644 -index 353c69d..0000000 ---- a/src/3rdparty/angle/src/common/event_tracer.cpp -+++ /dev/null -@@ -1,49 +0,0 @@ --// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. --// Use of this source code is governed by a BSD-style license that can be --// found in the LICENSE file. +diff --git a/src/3rdparty/angle/src/commit.h b/src/3rdparty/angle/src/commit.h +index 4c89a65..08fc893 100644 +--- a/src/3rdparty/angle/src/commit.h ++++ b/src/3rdparty/angle/src/commit.h +@@ -7,8 +7,6 @@ + // This is a default commit hash header, when git is not available. + // + +-#define ANGLE_COMMIT_HASH "unknown hash" ++#define ANGLE_COMMIT_HASH "30d6c255d238" + #define ANGLE_COMMIT_HASH_SIZE 12 +-#define ANGLE_COMMIT_DATE "unknown date" - --#include "common/event_tracer.h" -- --namespace gl --{ -- --GetCategoryEnabledFlagFunc g_getCategoryEnabledFlag; --AddTraceEventFunc g_addTraceEvent; -- --} // namespace gl -- --extern "C" { -- --void TRACE_ENTRY SetTraceFunctionPointers(GetCategoryEnabledFlagFunc getCategoryEnabledFlag, -- AddTraceEventFunc addTraceEvent) --{ -- gl::g_getCategoryEnabledFlag = getCategoryEnabledFlag; -- gl::g_addTraceEvent = addTraceEvent; --} -- --} // extern "C" -- --namespace gl --{ -- --const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name) --{ -- if (g_getCategoryEnabledFlag) -- { -- return g_getCategoryEnabledFlag(name); -- } -- static unsigned char disabled = 0; -- return &disabled; --} -- --void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id, -- int numArgs, const char** argNames, const unsigned char* argTypes, -- const unsigned long long* argValues, unsigned char flags) --{ -- if (g_addTraceEvent) -- { -- g_addTraceEvent(phase, categoryGroupEnabled, name, id, numArgs, argNames, argTypes, argValues, flags); -- } --} -- --} // namespace gl -diff --git a/src/3rdparty/angle/src/common/event_tracer.h b/src/3rdparty/angle/src/common/event_tracer.h -deleted file mode 100644 -index fa97435..0000000 ---- a/src/3rdparty/angle/src/common/event_tracer.h -+++ /dev/null -@@ -1,43 +0,0 @@ --// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. --// Use of this source code is governed by a BSD-style license that can be --// found in the LICENSE file. -- --#ifndef COMMON_EVENT_TRACER_H_ --#define COMMON_EVENT_TRACER_H_ -- --#include "common/platform.h" -- --#if !defined(TRACE_ENTRY) --# ifdef ANGLE_PLATFORM_WINDOWS --# define TRACE_ENTRY __stdcall --# else --# define TRACE_ENTRY --# endif // ANGLE_PLATFORM_WINDOWS --#endif //TRACE_ENTRY -- --extern "C" { -- --typedef const unsigned char* (*GetCategoryEnabledFlagFunc)(const char* name); --typedef void (*AddTraceEventFunc)(char phase, const unsigned char* categoryGroupEnabled, const char* name, -- unsigned long long id, int numArgs, const char** argNames, -- const unsigned char* argTypes, const unsigned long long* argValues, -- unsigned char flags); -- --// extern "C" so that it has a reasonable name for GetProcAddress. --void TRACE_ENTRY SetTraceFunctionPointers(GetCategoryEnabledFlagFunc get_category_enabled_flag, -- AddTraceEventFunc add_trace_event_func); -- --} -- --namespace gl --{ -- --const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name); -- --void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id, -- int numArgs, const char** argNames, const unsigned char* argTypes, -- const unsigned long long* argValues, unsigned char flags); -- --} -- --#endif // COMMON_EVENT_TRACER_H_ +-#define ANGLE_DISABLE_PROGRAM_BINARY_LOAD ++#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000" diff --git a/src/3rdparty/angle/src/common/version.h b/src/3rdparty/angle/src/common/version.h index d9148d1..f01e024 100644 --- a/src/3rdparty/angle/src/common/version.h @@ -183,8 +54,19 @@ index d9148d1..f01e024 100644 #define ANGLE_MAJOR_VERSION 2 #define ANGLE_MINOR_VERSION 1 +diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp +index 0de16f4..0e63fa5 100644 +--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp ++++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp +@@ -184,4 +184,4 @@ long ConvertDipsToPixels(float dips) + static const float dipsPerInch = 96.0f; + return lround((dips * GetLogicalDpi() / dipsPerInch)); + } +-} +\ No newline at end of file ++} diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp -index f9a4780..7ce2b93 100644 +index 851b723..6110698 100644 --- a/src/3rdparty/angle/src/libEGL/libEGL.cpp +++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp @@ -6,6 +6,9 @@ @@ -198,7 +80,7 @@ index f9a4780..7ce2b93 100644 #include "common/debug.h" diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp -index 198c0ee..07f5d47 100644 +index 2306168..587950a 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp @@ -6,6 +6,10 @@ @@ -212,14 +94,6 @@ index 198c0ee..07f5d47 100644 #include "common/version.h" #include "common/utilities.h" -@@ -30,6 +34,7 @@ - #include "libGLESv2/validationES3.h" - #include "libGLESv2/queryconversions.h" - -+ - extern "C" - { - diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def index 88dceb3..33557eb 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def @@ -231,93 +105,29 @@ index 88dceb3..33557eb 100644 - - ; Setting up TRACE macro callbacks - SetTraceFunctionPointers @284 -diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def -index d6272c4d..18ffcf6 100644 ---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def -+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def -@@ -294,6 +294,3 @@ EXPORTS - glBindTexImage@4 @158 NONAME - glCreateRenderer @177 NONAME - glDestroyRenderer @178 NONAME -- -- ; Setting up TRACE macro callbacks -- SetTraceFunctionPointers@8 @284 -diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def -index d301aa0..120371e 100644 ---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def -+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def -@@ -294,6 +294,3 @@ EXPORTS - glBindTexImage @158 NONAME - glCreateRenderer @177 NONAME - glDestroyRenderer @178 NONAME -- -- ; Setting up TRACE macro callbacks -- SetTraceFunctionPointers @284 -diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def -index a82d629..8c1306a 100644 ---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def -+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def -@@ -294,6 +294,3 @@ EXPORTS - glBindTexImage@4 @158 NONAME - glCreateRenderer @177 NONAME - glDestroyRenderer @178 NONAME -- -- ; Setting up TRACE macro callbacks -- SetTraceFunctionPointers@8 @284 -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp -index df43012..910d028 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp -@@ -10,7 +10,6 @@ - #include "libGLESv2/Program.h" - #include "libGLESv2/renderer/Renderer.h" - #include "common/utilities.h" --#include "third_party/trace_event/trace_event.h" - #include "libGLESv2/Shader.h" - - #if defined (ANGLE_ENABLE_D3D9) -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h -index c53b2af..12be9b3 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h -@@ -16,10 +16,6 @@ - #include - #include - --#if !defined(ANGLE_FORCE_VSYNC_OFF) --#define ANGLE_FORCE_VSYNC_OFF 0 --#endif -- - namespace rx - { - diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -index df2e46c..acbd852 100644 +index 5c44fe0..bfeaf51 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -@@ -10,8 +10,6 @@ - +@@ -11,8 +11,6 @@ + #include "common/features.h" #include "common/utilities.h" -#include "third_party/trace_event/trace_event.h" - - namespace rx + // Definitions local to the translation unit + namespace { - -@@ -28,7 +26,11 @@ HLSLCompiler::~HLSLCompiler() +@@ -120,7 +118,6 @@ HLSLCompiler::~HLSLCompiler() bool HLSLCompiler::initialize() { -+<<<<<<< HEAD - TRACE_EVENT0("gpu", "initializeCompiler"); -+======= -+#if !defined(ANGLE_PLATFORM_WINRT) -+>>>>>>> 429814a... ANGLE: remove event tracing +- TRACE_EVENT0("gpu", "initializeCompiler"); + #if !defined(ANGLE_ENABLE_WINDOWS_STORE) #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. - static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp -index 3bdb9e7..72820a4 100644 +index 8ed1650..91e7552 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp @@ -13,39 +13,39 @@ @@ -394,7 +204,7 @@ index 3bdb9e7..72820a4 100644 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h" #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h" diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp -index c60b7a6..5caa427 100644 +index 12905d0..4630762 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp @@ -15,14 +15,14 @@ @@ -419,7 +229,7 @@ index c60b7a6..5caa427 100644 namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp -index f54bacc..edaafec 100644 +index 1bc2bd8..a4072d8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -22,11 +22,11 @@ @@ -440,7 +250,7 @@ index f54bacc..edaafec 100644 namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp -index 5ec132e..50dae4e 100644 +index 3fcacf6..834b7bd 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp @@ -12,8 +12,8 @@ @@ -452,8 +262,8 @@ index 5ec132e..50dae4e 100644 +#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h" +#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h" - namespace rx - { + #include "common/features.h" + #include "common/NativeWindow.h" diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl index 6deef2b..b4cf380 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl @@ -485,7 +295,7 @@ index 6deef2b..b4cf380 100644 } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp -index 80503d5..f061a32 100644 +index d4fcd17..2ca7a9c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp @@ -27,20 +27,20 @@ namespace @@ -520,11 +330,11 @@ index 80503d5..f061a32 100644 } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp -index 73c1abc..e8564bd 100644 +index 3bac4ba..82963ec 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp -@@ -39,8 +39,6 @@ - +@@ -42,8 +42,6 @@ + #include "common/features.h" #include "common/utilities.h" -#include "third_party/trace_event/trace_event.h" @@ -532,7 +342,7 @@ index 73c1abc..e8564bd 100644 #include // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros -@@ -190,7 +188,6 @@ EGLint Renderer9::initialize() +@@ -185,7 +183,6 @@ EGLint Renderer9::initialize() return EGL_NOT_INITIALIZED; } @@ -540,9 +350,9 @@ index 73c1abc..e8564bd 100644 mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); if (mD3d9Module == NULL) -@@ -207,14 +204,12 @@ EGLint Renderer9::initialize() +@@ -202,14 +199,12 @@ EGLint Renderer9::initialize() // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. - if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) + if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { - TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); @@ -555,7 +365,7 @@ index 73c1abc..e8564bd 100644 mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } -@@ -233,7 +228,6 @@ EGLint Renderer9::initialize() +@@ -228,7 +223,6 @@ EGLint Renderer9::initialize() // Give up on getting device caps after about one second. { @@ -563,7 +373,7 @@ index 73c1abc..e8564bd 100644 for (int i = 0; i < 10; ++i) { result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); -@@ -268,7 +262,6 @@ EGLint Renderer9::initialize() +@@ -263,7 +257,6 @@ EGLint Renderer9::initialize() } { @@ -571,7 +381,7 @@ index 73c1abc..e8564bd 100644 mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); } -@@ -305,7 +298,6 @@ EGLint Renderer9::initialize() +@@ -300,7 +293,6 @@ EGLint Renderer9::initialize() static const TCHAR className[] = TEXT("STATIC"); { @@ -579,7 +389,7 @@ index 73c1abc..e8564bd 100644 mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); } -@@ -313,7 +305,6 @@ EGLint Renderer9::initialize() +@@ -308,7 +300,6 @@ EGLint Renderer9::initialize() DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES; { @@ -587,7 +397,7 @@ index 73c1abc..e8564bd 100644 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); } if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) -@@ -323,7 +314,6 @@ EGLint Renderer9::initialize() +@@ -318,7 +309,6 @@ EGLint Renderer9::initialize() if (FAILED(result)) { @@ -595,7 +405,7 @@ index 73c1abc..e8564bd 100644 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); if (FAILED(result)) -@@ -335,13 +325,11 @@ EGLint Renderer9::initialize() +@@ -330,13 +320,11 @@ EGLint Renderer9::initialize() if (mD3d9Ex) { @@ -662,858 +472,6 @@ index 3a36980..3bd611b 100644 { VS_OUTPUT Out; -diff --git a/src/3rdparty/angle/src/third_party/trace_event/trace_event.h b/src/3rdparty/angle/src/third_party/trace_event/trace_event.h -deleted file mode 100644 -index 1880056..0000000 ---- a/src/3rdparty/angle/src/third_party/trace_event/trace_event.h -+++ /dev/null -@@ -1,826 +0,0 @@ --// Copyright (c) 2013 The Chromium Authors. All rights reserved. --// Use of this source code is governed by a BSD-style license that can be --// found in the LICENSE file. -- --// Trace events are for tracking application performance and resource usage. --// Macros are provided to track: --// Begin and end of function calls --// Counters --// --// Events are issued against categories. Whereas LOG's --// categories are statically defined, TRACE categories are created --// implicitly with a string. For example: --// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") --// --// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope: --// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly") --// doSomethingCostly() --// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly") --// Note: our tools can't always determine the correct BEGIN/END pairs unless --// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you need them --// to be in separate scopes. --// --// A common use case is to trace entire function scopes. This --// issues a trace BEGIN and END automatically: --// void doSomethingCostly() { --// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly"); --// ... --// } --// --// Additional parameters can be associated with an event: --// void doSomethingCostly2(int howMuch) { --// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", --// "howMuch", howMuch); --// ... --// } --// --// The trace system will automatically add to this information the --// current process id, thread id, and a timestamp in microseconds. --// --// To trace an asynchronous procedure such as an IPC send/receive, use ASYNC_BEGIN and --// ASYNC_END: --// [single threaded sender code] --// static int send_count = 0; --// ++send_count; --// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count); --// Send(new MyMessage(send_count)); --// [receive code] --// void OnMyMessage(send_count) { --// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count); --// } --// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs. --// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. Pointers can --// be used for the ID parameter, and they will be mangled internally so that --// the same pointer on two different processes will not match. For example: --// class MyTracedClass { --// public: --// MyTracedClass() { --// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this); --// } --// ~MyTracedClass() { --// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this); --// } --// } --// --// Trace event also supports counters, which is a way to track a quantity --// as it varies over time. Counters are created with the following macro: --// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue); --// --// Counters are process-specific. The macro itself can be issued from any --// thread, however. --// --// Sometimes, you want to track two counters at once. You can do this with two --// counter macros: --// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]); --// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]); --// Or you can do it with a combined macro: --// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter", --// "bytesPinned", g_myCounterValue[0], --// "bytesAllocated", g_myCounterValue[1]); --// This indicates to the tracing UI that these counters should be displayed --// in a single graph, as a summed area chart. --// --// Since counters are in a global namespace, you may want to disembiguate with a --// unique ID, by using the TRACE_COUNTER_ID* variations. --// --// By default, trace collection is compiled in, but turned off at runtime. --// Collecting trace data is the responsibility of the embedding --// application. In Chrome's case, navigating to about:tracing will turn on --// tracing and display data collected across all active processes. --// --// --// Memory scoping note: --// Tracing copies the pointers, not the string content, of the strings passed --// in for category, name, and arg_names. Thus, the following code will --// cause problems: --// char* str = strdup("impprtantName"); --// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD! --// free(str); // Trace system now has dangling pointer --// --// To avoid this issue with the |name| and |arg_name| parameters, use the --// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead. --// Notes: The category must always be in a long-lived char* (i.e. static const). --// The |arg_values|, when used, are always deep copied with the _COPY --// macros. --// --// When are string argument values copied: --// const char* arg_values are only referenced by default: --// TRACE_EVENT1("category", "name", --// "arg1", "literal string is only referenced"); --// Use TRACE_STR_COPY to force copying of a const char*: --// TRACE_EVENT1("category", "name", --// "arg1", TRACE_STR_COPY("string will be copied")); --// std::string arg_values are always copied: --// TRACE_EVENT1("category", "name", --// "arg1", std::string("string will be copied")); --// --// --// Thread Safety: --// A thread safe singleton and mutex are used for thread safety. Category --// enabled flags are used to limit the performance impact when the system --// is not enabled. --// --// TRACE_EVENT macros first cache a pointer to a category. The categories are --// statically allocated and safe at all times, even after exit. Fetching a --// category is protected by the TraceLog::lock_. Multiple threads initializing --// the static variable is safe, as they will be serialized by the lock and --// multiple calls will return the same pointer to the category. --// --// Then the category_enabled flag is checked. This is a unsigned char, and --// not intended to be multithread safe. It optimizes access to addTraceEvent --// which is threadsafe internally via TraceLog::lock_. The enabled flag may --// cause some threads to incorrectly call or skip calling addTraceEvent near --// the time of the system being enabled or disabled. This is acceptable as --// we tolerate some data loss while the system is being enabled/disabled and --// because addTraceEvent is threadsafe internally and checks the enabled state --// again under lock. --// --// Without the use of these static category pointers and enabled flags all --// trace points would carry a significant performance cost of aquiring a lock --// and resolving the category. -- --#ifndef COMMON_TRACE_EVENT_H_ --#define COMMON_TRACE_EVENT_H_ -- --#include -- --#include "common/event_tracer.h" -- --// By default, const char* argument values are assumed to have long-lived scope --// and will not be copied. Use this macro to force a const char* to be copied. --#define TRACE_STR_COPY(str) \ -- WebCore::TraceEvent::TraceStringWithCopy(str) -- --// Records a pair of begin and end events called "name" for the current --// scope, with 0, 1 or 2 associated arguments. If the category is not --// enabled, then this does nothing. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --#define TRACE_EVENT0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name) --#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val) --#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) -- --// Records a single event called "name" immediately, with 0, 1 or 2 --// associated arguments. If the category is not enabled, then this --// does nothing. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --#define TRACE_EVENT_INSTANT0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ -- arg2_name, arg2_val) --#define TRACE_EVENT_COPY_INSTANT0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) --#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ -- arg2_name, arg2_val) -- --// Records a single BEGIN event called "name" immediately, with 0, 1 or 2 --// associated arguments. If the category is not enabled, then this --// does nothing. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --#define TRACE_EVENT_BEGIN0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ -- arg2_name, arg2_val) --#define TRACE_EVENT_COPY_BEGIN0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) --#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ -- arg2_name, arg2_val) -- --// Records a single END event for "name" immediately. If the category --// is not enabled, then this does nothing. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --#define TRACE_EVENT_END0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ -- arg2_name, arg2_val) --#define TRACE_EVENT_COPY_END0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) --#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ -- arg2_name, arg2_val) -- --// Records the value of a counter called "name" immediately. Value --// must be representable as a 32 bit integer. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --#define TRACE_COUNTER1(category, name, value) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_NONE, \ -- "value", static_cast(value)) --#define TRACE_COPY_COUNTER1(category, name, value) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_COPY, \ -- "value", static_cast(value)) -- --// Records the values of a multi-parted counter called "name" immediately. --// The UI will treat value1 and value2 as parts of a whole, displaying their --// values as a stacked-bar chart. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --#define TRACE_COUNTER2(category, name, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_NONE, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) --#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_COPY, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) -- --// Records the value of a counter called "name" immediately. Value --// must be representable as a 32 bit integer. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --// - |id| is used to disambiguate counters with the same name. It must either --// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits --// will be xored with a hash of the process ID so that the same pointer on --// two different processes will not collide. --#define TRACE_COUNTER_ID1(category, name, id, value) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- "value", static_cast(value)) --#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- "value", static_cast(value)) -- --// Records the values of a multi-parted counter called "name" immediately. --// The UI will treat value1 and value2 as parts of a whole, displaying their --// values as a stacked-bar chart. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --// - |id| is used to disambiguate counters with the same name. It must either --// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits --// will be xored with a hash of the process ID so that the same pointer on --// two different processes will not collide. --#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) --#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) -- --// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2 --// associated arguments. If the category is not enabled, then this --// does nothing. --// - category and name strings must have application lifetime (statics or --// literals). They may not include " chars. --// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC --// events are considered to match if their category, name and id values all --// match. |id| must either be a pointer or an integer value up to 64 bits. If --// it's a pointer, the bits will be xored with a hash of the process ID so --// that the same pointer on two different processes will not collide. --// An asynchronous operation can consist of multiple phases. The first phase is --// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the --// ASYNC_STEP_BEGIN macros. When the operation completes, call ASYNC_END. --// An async operation can span threads and processes, but all events in that --// operation must use the same |name| and |id|. Each event can have its own --// args. --#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- arg1_name, arg1_val, arg2_name, arg2_val) --#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val, arg2_name, arg2_val) -- --// Records a single ASYNC_STEP event for |step| immediately. If the category --// is not enabled, then this does nothing. The |name| and |id| must match the --// ASYNC_BEGIN event above. The |step| param identifies this step within the --// async event. This should be called at the beginning of the next phase of an --// asynchronous operation. --#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step) --#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step) --#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ -- arg1_name, arg1_val) -- --// Records a single ASYNC_END event for "name" immediately. If the category --// is not enabled, then this does nothing. --#define TRACE_EVENT_ASYNC_END0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- arg1_name, arg1_val, arg2_name, arg2_val) --#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val, arg2_name, arg2_val) -- --// Creates a scope of a sampling state with the given category and name (both must --// be constant strings). These states are intended for a sampling profiler. --// Implementation note: we store category and name together because we don't --// want the inconsistency/expense of storing two pointers. --// |thread_bucket| is [0..2] and is used to statically isolate samples in one --// thread from others. --// --// { // The sampling state is set within this scope. --// TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name"); --// ...; --// } --#define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \ -- TraceEvent::SamplingStateScope traceEventSamplingScope(category "\0" name); -- --// Returns a current sampling state of the given bucket. --// The format of the returned string is "category\0name". --#define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \ -- TraceEvent::SamplingStateScope::current() -- --// Sets a current sampling state of the given bucket. --// |category| and |name| have to be constant strings. --#define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \ -- TraceEvent::SamplingStateScope::set(category "\0" name) -- --// Sets a current sampling state of the given bucket. --// |categoryAndName| doesn't need to be a constant string. --// The format of the string is "category\0name". --#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(bucket_number, categoryAndName) \ -- TraceEvent::SamplingStateScope::set(categoryAndName) -- --// Syntactic sugars for the sampling tracing in the main thread. --#define TRACE_EVENT_SCOPED_SAMPLING_STATE(category, name) \ -- TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(0, category, name) --#define TRACE_EVENT_GET_SAMPLING_STATE() \ -- TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(0) --#define TRACE_EVENT_SET_SAMPLING_STATE(category, name) \ -- TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(0, category, name) --#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(categoryAndName) \ -- TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(0, categoryAndName) -- --//////////////////////////////////////////////////////////////////////////////// --// Implementation specific tracing API definitions. -- --// Get a pointer to the enabled state of the given trace category. Only --// long-lived literal strings should be given as the category name. The returned --// pointer can be held permanently in a local static for example. If the --// unsigned char is non-zero, tracing is enabled. If tracing is enabled, --// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled --// between the load of the tracing state and the call to --// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out --// for best performance when tracing is disabled. --// const unsigned char* --// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) --#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ -- gl::TraceGetTraceCategoryEnabledFlag -- --// Add a trace event to the platform tracing system. --// void TRACE_EVENT_API_ADD_TRACE_EVENT( --// char phase, --// const unsigned char* category_enabled, --// const char* name, --// unsigned long long id, --// int num_args, --// const char** arg_names, --// const unsigned char* arg_types, --// const unsigned long long* arg_values, --// unsigned char flags) --#define TRACE_EVENT_API_ADD_TRACE_EVENT \ -- gl::TraceAddTraceEvent -- --//////////////////////////////////////////////////////////////////////////////// -- --// Implementation detail: trace event macros create temporary variables --// to keep instrumentation overhead low. These macros give each temporary --// variable a unique name based on the line number to prevent name collissions. --#define INTERNAL_TRACE_EVENT_UID3(a, b) \ -- trace_event_unique_##a##b --#define INTERNAL_TRACE_EVENT_UID2(a, b) \ -- INTERNAL_TRACE_EVENT_UID3(a, b) --#define INTERNALTRACEEVENTUID(name_prefix) \ -- INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__) -- --// Implementation detail: internal macro to create static category. --#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \ -- static const unsigned char* INTERNALTRACEEVENTUID(catstatic) = 0; \ -- if (!INTERNALTRACEEVENTUID(catstatic)) \ -- INTERNALTRACEEVENTUID(catstatic) = \ -- TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); -- --// Implementation detail: internal macro to create static category and add --// event if the category is enabled. --#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \ -- do { \ -- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ -- if (*INTERNALTRACEEVENTUID(catstatic)) { \ -- gl::TraceEvent::addTraceEvent( \ -- phase, INTERNALTRACEEVENTUID(catstatic), name, \ -- gl::TraceEvent::noEventId, flags, ##__VA_ARGS__); \ -- } \ -- } while (0) -- --// Implementation detail: internal macro to create static category and add begin --// event if the category is enabled. Also adds the end event when the scope --// ends. --#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \ -- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ -- gl::TraceEvent::TraceEndOnScopeClose \ -- INTERNALTRACEEVENTUID(profileScope); \ -- if (*INTERNALTRACEEVENTUID(catstatic)) { \ -- gl::TraceEvent::addTraceEvent( \ -- TRACE_EVENT_PHASE_BEGIN, \ -- INTERNALTRACEEVENTUID(catstatic), \ -- name, gl::TraceEvent::noEventId, \ -- TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \ -- INTERNALTRACEEVENTUID(profileScope).initialize( \ -- INTERNALTRACEEVENTUID(catstatic), name); \ -- } -- --// Implementation detail: internal macro to create static category and add --// event if the category is enabled. --#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \ -- ...) \ -- do { \ -- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ -- if (*INTERNALTRACEEVENTUID(catstatic)) { \ -- unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \ -- gl::TraceEvent::TraceID traceEventTraceID( \ -- id, &traceEventFlags); \ -- gl::TraceEvent::addTraceEvent( \ -- phase, INTERNALTRACEEVENTUID(catstatic), \ -- name, traceEventTraceID.data(), traceEventFlags, \ -- ##__VA_ARGS__); \ -- } \ -- } while (0) -- --// Notes regarding the following definitions: --// New values can be added and propagated to third party libraries, but existing --// definitions must never be changed, because third party libraries may use old --// definitions. -- --// Phase indicates the nature of an event entry. E.g. part of a begin/end pair. --#define TRACE_EVENT_PHASE_BEGIN ('B') --#define TRACE_EVENT_PHASE_END ('E') --#define TRACE_EVENT_PHASE_INSTANT ('I') --#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S') --#define TRACE_EVENT_PHASE_ASYNC_STEP ('T') --#define TRACE_EVENT_PHASE_ASYNC_END ('F') --#define TRACE_EVENT_PHASE_METADATA ('M') --#define TRACE_EVENT_PHASE_COUNTER ('C') --#define TRACE_EVENT_PHASE_SAMPLE ('P') -- --// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT. --#define TRACE_EVENT_FLAG_NONE (static_cast(0)) --#define TRACE_EVENT_FLAG_COPY (static_cast(1 << 0)) --#define TRACE_EVENT_FLAG_HAS_ID (static_cast(1 << 1)) --#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast(1 << 2)) -- --// Type values for identifying types in the TraceValue union. --#define TRACE_VALUE_TYPE_BOOL (static_cast(1)) --#define TRACE_VALUE_TYPE_UINT (static_cast(2)) --#define TRACE_VALUE_TYPE_INT (static_cast(3)) --#define TRACE_VALUE_TYPE_DOUBLE (static_cast(4)) --#define TRACE_VALUE_TYPE_POINTER (static_cast(5)) --#define TRACE_VALUE_TYPE_STRING (static_cast(6)) --#define TRACE_VALUE_TYPE_COPY_STRING (static_cast(7)) -- -- --namespace gl { -- --namespace TraceEvent { -- --// Specify these values when the corresponding argument of addTraceEvent is not --// used. --const int zeroNumArgs = 0; --const unsigned long long noEventId = 0; -- --// TraceID encapsulates an ID that can either be an integer or pointer. Pointers --// are mangled with the Process ID so that they are unlikely to collide when the --// same pointer is used on different processes. --class TraceID { --public: -- explicit TraceID(const void* id, unsigned char* flags) : -- m_data(static_cast(reinterpret_cast(id))) -- { -- *flags |= TRACE_EVENT_FLAG_MANGLE_ID; -- } -- explicit TraceID(unsigned long long id, unsigned char* flags) : m_data(id) { (void)flags; } -- explicit TraceID(unsigned long id, unsigned char* flags) : m_data(id) { (void)flags; } -- explicit TraceID(unsigned int id, unsigned char* flags) : m_data(id) { (void)flags; } -- explicit TraceID(unsigned short id, unsigned char* flags) : m_data(id) { (void)flags; } -- explicit TraceID(unsigned char id, unsigned char* flags) : m_data(id) { (void)flags; } -- explicit TraceID(long long id, unsigned char* flags) : -- m_data(static_cast(id)) { (void)flags; } -- explicit TraceID(long id, unsigned char* flags) : -- m_data(static_cast(id)) { (void)flags; } -- explicit TraceID(int id, unsigned char* flags) : -- m_data(static_cast(id)) { (void)flags; } -- explicit TraceID(short id, unsigned char* flags) : -- m_data(static_cast(id)) { (void)flags; } -- explicit TraceID(signed char id, unsigned char* flags) : -- m_data(static_cast(id)) { (void)flags; } -- -- unsigned long long data() const { return m_data; } -- --private: -- unsigned long long m_data; --}; -- --// Simple union to store various types as unsigned long long. --union TraceValueUnion { -- bool m_bool; -- unsigned long long m_uint; -- long long m_int; -- double m_double; -- const void* m_pointer; -- const char* m_string; --}; -- --// Simple container for const char* that should be copied instead of retained. --class TraceStringWithCopy { --public: -- explicit TraceStringWithCopy(const char* str) : m_str(str) { } -- operator const char* () const { return m_str; } --private: -- const char* m_str; --}; -- --// Define setTraceValue for each allowed type. It stores the type and --// value in the return arguments. This allows this API to avoid declaring any --// structures so that it is portable to third_party libraries. --#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \ -- union_member, \ -- value_type_id) \ -- static inline void setTraceValue(actual_type arg, \ -- unsigned char* type, \ -- unsigned long long* value) { \ -- TraceValueUnion typeValue; \ -- typeValue.union_member = arg; \ -- *type = value_type_id; \ -- *value = typeValue.m_uint; \ -- } --// Simpler form for int types that can be safely casted. --#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \ -- value_type_id) \ -- static inline void setTraceValue(actual_type arg, \ -- unsigned char* type, \ -- unsigned long long* value) { \ -- *type = value_type_id; \ -- *value = static_cast(arg); \ -- } -- --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT) --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT) --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT) --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT) --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT) --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT) --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT) --INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT) --INTERNAL_DECLARE_SET_TRACE_VALUE(bool, m_bool, TRACE_VALUE_TYPE_BOOL) --INTERNAL_DECLARE_SET_TRACE_VALUE(double, m_double, TRACE_VALUE_TYPE_DOUBLE) --INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, m_pointer, -- TRACE_VALUE_TYPE_POINTER) --INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, m_string, -- TRACE_VALUE_TYPE_STRING) --INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, m_string, -- TRACE_VALUE_TYPE_COPY_STRING) -- --#undef INTERNAL_DECLARE_SET_TRACE_VALUE --#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT -- --static inline void setTraceValue(const std::string& arg, -- unsigned char* type, -- unsigned long long* value) { -- TraceValueUnion typeValue; -- typeValue.m_string = arg.data(); -- *type = TRACE_VALUE_TYPE_COPY_STRING; -- *value = typeValue.m_uint; --} -- --// These addTraceEvent template functions are defined here instead of in the --// macro, because the arg values could be temporary string objects. In order to --// store pointers to the internal c_str and pass through to the tracing API, the --// arg values must live throughout these procedures. -- --static inline void addTraceEvent(char phase, -- const unsigned char* categoryEnabled, -- const char* name, -- unsigned long long id, -- unsigned char flags) { -- TRACE_EVENT_API_ADD_TRACE_EVENT( -- phase, categoryEnabled, name, id, -- zeroNumArgs, 0, 0, 0, -- flags); --} -- --template --static inline void addTraceEvent(char phase, -- const unsigned char* categoryEnabled, -- const char* name, -- unsigned long long id, -- unsigned char flags, -- const char* arg1Name, -- const ARG1_TYPE& arg1Val) { -- const int numArgs = 1; -- unsigned char argTypes[1]; -- unsigned long long argValues[1]; -- setTraceValue(arg1Val, &argTypes[0], &argValues[0]); -- TRACE_EVENT_API_ADD_TRACE_EVENT( -- phase, categoryEnabled, name, id, -- numArgs, &arg1Name, argTypes, argValues, -- flags); --} -- --template --static inline void addTraceEvent(char phase, -- const unsigned char* categoryEnabled, -- const char* name, -- unsigned long long id, -- unsigned char flags, -- const char* arg1Name, -- const ARG1_TYPE& arg1Val, -- const char* arg2Name, -- const ARG2_TYPE& arg2Val) { -- const int numArgs = 2; -- const char* argNames[2] = { arg1Name, arg2Name }; -- unsigned char argTypes[2]; -- unsigned long long argValues[2]; -- setTraceValue(arg1Val, &argTypes[0], &argValues[0]); -- setTraceValue(arg2Val, &argTypes[1], &argValues[1]); -- return TRACE_EVENT_API_ADD_TRACE_EVENT( -- phase, categoryEnabled, name, id, -- numArgs, argNames, argTypes, argValues, -- flags); --} -- --// Used by TRACE_EVENTx macro. Do not use directly. --class TraceEndOnScopeClose { --public: -- // Note: members of m_data intentionally left uninitialized. See initialize. -- TraceEndOnScopeClose() : m_pdata(0) { } -- ~TraceEndOnScopeClose() -- { -- if (m_pdata) -- addEventIfEnabled(); -- } -- -- void initialize(const unsigned char* categoryEnabled, -- const char* name) -- { -- m_data.categoryEnabled = categoryEnabled; -- m_data.name = name; -- m_pdata = &m_data; -- } -- --private: -- // Add the end event if the category is still enabled. -- void addEventIfEnabled() -- { -- // Only called when m_pdata is non-null. -- if (*m_pdata->categoryEnabled) { -- TRACE_EVENT_API_ADD_TRACE_EVENT( -- TRACE_EVENT_PHASE_END, -- m_pdata->categoryEnabled, -- m_pdata->name, noEventId, -- zeroNumArgs, 0, 0, 0, -- TRACE_EVENT_FLAG_NONE); -- } -- } -- -- // This Data struct workaround is to avoid initializing all the members -- // in Data during construction of this object, since this object is always -- // constructed, even when tracing is disabled. If the members of Data were -- // members of this class instead, compiler warnings occur about potential -- // uninitialized accesses. -- struct Data { -- const unsigned char* categoryEnabled; -- const char* name; -- }; -- Data* m_pdata; -- Data m_data; --}; -- --// TraceEventSamplingStateScope records the current sampling state --// and sets a new sampling state. When the scope exists, it restores --// the sampling state having recorded. --template --class SamplingStateScope { --public: -- SamplingStateScope(const char* categoryAndName) -- { -- m_previousState = SamplingStateScope::current(); -- SamplingStateScope::set(categoryAndName); -- } -- -- ~SamplingStateScope() -- { -- SamplingStateScope::set(m_previousState); -- } -- -- // FIXME: Make load/store to traceSamplingState[] thread-safe and atomic. -- static inline const char* current() -- { -- return reinterpret_cast(*gl::traceSamplingState[BucketNumber]); -- } -- static inline void set(const char* categoryAndName) -- { -- *gl::traceSamplingState[BucketNumber] = reinterpret_cast(const_cast(categoryAndName)); -- } -- --private: -- const char* m_previousState; --}; -- --} // namespace TraceEvent -- --} // namespace gl -- --#endif -diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri -index fd1c31c..8baedc5 100644 ---- a/src/angle/src/common/common.pri -+++ b/src/angle/src/common/common.pri -@@ -51,7 +51,6 @@ static: DEFINES *= QT_OPENGL_ES_2_ANGLE_STATIC - HEADERS += \ - $$ANGLE_DIR/src/common/angleutils.h \ - $$ANGLE_DIR/src/common/debug.h \ -- $$ANGLE_DIR/src/common/event_tracer.h \ - $$ANGLE_DIR/src/common/mathutil.h \ - $$ANGLE_DIR/src/common/platform.h \ - $$ANGLE_DIR/src/common/RefCountObject.h \ -@@ -61,7 +60,6 @@ HEADERS += \ - SOURCES += \ - $$ANGLE_DIR/src/common/angleutils.cpp \ - $$ANGLE_DIR/src/common/debug.cpp \ -- $$ANGLE_DIR/src/common/event_tracer.cpp \ - $$ANGLE_DIR/src/common/RefCountObject.cpp \ - $$ANGLE_DIR/src/common/tls.cpp - -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch deleted file mode 100644 index f2252540eb..0000000000 --- a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 3ea314039783d2e6e558cb10aa86dbf278631eef Mon Sep 17 00:00:00 2001 -From: Thomas Hartmann -Date: Tue, 16 Sep 2014 23:24:24 +0300 -Subject: [PATCH 01/16] Fix compilation for MSVC 2008 and std::tuple - -For MSVC 2008 make_tuple is in the tr1 namespace. - -Change-Id: I4a51f6cabdf068993869b404b12ed1484a21a9d4 ---- - src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp -index d472e14..f68ac38 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp -@@ -111,7 +111,11 @@ IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c) - - bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const - { -+#if defined(_MSC_VER) && _MSC_VER < 1600 -+ return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count); -+#else - return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count); -+#endif - } - - IndexRangeCache::IndexBounds::IndexBounds() --- -1.9.0.msysgit.0 - diff --git a/src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch b/src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch deleted file mode 100644 index 322d121149..0000000000 --- a/src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9f1217589c029d2f91e863c54f7f9d52ef496f71 Mon Sep 17 00:00:00 2001 -From: Kai Koehne -Date: Tue, 16 Sep 2014 23:33:42 +0300 -Subject: [PATCH 02/16] Fix compilation of ANGLE with mingw-tdm64 gcc 4.8.1 - -Do not rely on sprintf_s being declared/defined. This also fixes -deployment to Windows XP. - -See https://chromium-review.googlesource.com/#/c/182975/ for a similar -commit proposed upstream. - -Task-number: QTBUG-36242 -Change-Id: I520e2f61aeab34963e7a57baafd413c7db93f110 ---- - src/3rdparty/angle/src/libEGL/Display.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp -index ecf3395..aaebdb3 100644 ---- a/src/3rdparty/angle/src/libEGL/Display.cpp -+++ b/src/3rdparty/angle/src/libEGL/Display.cpp -@@ -597,7 +597,7 @@ void Display::initVendorString() - if (mRenderer && mRenderer->getLUID(&adapterLuid)) - { - char adapterLuidString[64]; -- sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart); -+ snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart); - - mVendorString += adapterLuidString; - } --- -1.9.0.msysgit.0 - diff --git a/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch b/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch index 1dfe6154e7..45a3f17cca 100644 --- a/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch +++ b/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch @@ -1,6 +1,6 @@ -From cb00356bad800ca2397301cb8b79ad0b097bddd8 Mon Sep 17 00:00:00 2001 +From 3a39939b5eba9f788789961c4800ba62618f758c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint -Date: Tue, 16 Sep 2014 23:43:00 +0300 +Date: Tue, 11 Nov 2014 10:26:32 +0200 Subject: [PATCH 04/16] Make it possible to link ANGLE statically for single-thread use. @@ -11,8 +11,8 @@ Change-Id: Ifab25a820adf5953bb3b09036de53dbf7f1a7fd5 --- src/3rdparty/angle/include/KHR/khrplatform.h | 2 +- src/3rdparty/angle/src/libEGL/main.cpp | 10 ++++++++++ - src/3rdparty/angle/src/libGLESv2/main.cpp | 10 ++++++++++ - 3 files changed, 21 insertions(+), 1 deletion(-) + src/3rdparty/angle/src/libGLESv2/main.cpp | 10 ++++++++-- + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/angle/include/KHR/khrplatform.h b/src/3rdparty/angle/include/KHR/khrplatform.h index c9e6f17..1ac2d3f 100644 @@ -28,7 +28,7 @@ index c9e6f17..1ac2d3f 100644 #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp -index 0f8439c..8a1baef 100644 +index d1489f2..e88cad7 100644 --- a/src/3rdparty/angle/src/libEGL/main.cpp +++ b/src/3rdparty/angle/src/libEGL/main.cpp @@ -49,6 +49,8 @@ void DeallocateCurrent() @@ -40,7 +40,7 @@ index 0f8439c..8a1baef 100644 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) -@@ -100,16 +102,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved +@@ -108,16 +110,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved return TRUE; } @@ -64,26 +64,27 @@ index 0f8439c..8a1baef 100644 +#endif } - void setCurrentError(EGLint error) + void recordError(const Error &error) diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp -index 4444d1a..1c577bc 100644 +index 3ac00d5..00f63ae 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.cpp +++ b/src/3rdparty/angle/src/libGLESv2/main.cpp -@@ -46,6 +46,8 @@ void DeallocateCurrent() +@@ -74,7 +74,7 @@ void DeallocateCurrent() } -+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC -+ +-#ifdef ANGLE_PLATFORM_WINDOWS ++#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC) extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) -@@ -82,16 +84,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved +@@ -117,18 +117,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved + return TRUE; } +-#endif ++#endif // ANGLE_PLATFORM_WINDOWS && !QT_OPENGL_ES_2_ANGLE_STATIC -+#endif // !QT_OPENGL_ES_2_ANGLE_STATIC -+ namespace gl { @@ -104,5 +105,5 @@ index 4444d1a..1c577bc 100644 void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch b/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch deleted file mode 100644 index 78c3e0fbe8..0000000000 --- a/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch +++ /dev/null @@ -1,84 +0,0 @@ -From df225c023963f37737b7e2d020c8f89a5d5f878e Mon Sep 17 00:00:00 2001 -From: Andy Shaw -Date: Tue, 16 Sep 2014 23:49:50 +0300 -Subject: [PATCH 05/16] Fix build when SSE2 is not available. - -Although SSE2 support is detected at runtime it still may not be -available at build time, so we have to ensure it only uses SSE2 -when it is available at build time too. - -Change-Id: I86c45a6466ab4cec79aa0f62b0d5230a78ad825a ---- - src/3rdparty/angle/src/common/mathutil.h | 2 ++ - src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp | 8 ++++++++ - 2 files changed, 10 insertions(+) - -diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h -index ffcb908..52f2bc1 100644 ---- a/src/3rdparty/angle/src/common/mathutil.h -+++ b/src/3rdparty/angle/src/common/mathutil.h -@@ -118,6 +118,7 @@ inline bool supportsSSE2() - return supports; - } - -+#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid() - int info[4]; - __cpuid(info, 0); - -@@ -127,6 +128,7 @@ inline bool supportsSSE2() - - supports = (info[3] >> 26) & 1; - } -+#endif - - checked = true; - -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp -index cc20d94..f777b30 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp -@@ -10,6 +10,10 @@ - - #include "libGLESv2/renderer/loadimage.h" - -+#if !defined(__SSE2__) && (defined(_M_X64) || _M_IX86_FP == 2) -+#define __SSE2__ -+#endif -+ - namespace rx - { - -@@ -17,6 +21,7 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) - { -+#ifdef __SSE2__ - __m128i zeroWide = _mm_setzero_si128(); - - for (size_t z = 0; z < depth; z++) -@@ -54,12 +59,14 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - } - } - } -+#endif - } - - void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) - { -+#ifdef __SSE2__ - __m128i brMask = _mm_set1_epi32(0x00ff00ff); - - for (size_t z = 0; z < depth; z++) -@@ -99,6 +106,7 @@ void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - } - } - } -+#endif - } - - } --- -1.9.0.msysgit.0 - diff --git a/src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch b/src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch deleted file mode 100644 index e60bebd233..0000000000 --- a/src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 2a8568e6f44731df96f6567ffcc59a65ad2b3f29 Mon Sep 17 00:00:00 2001 -From: Kai Koehne -Date: Tue, 16 Sep 2014 23:55:25 +0300 -Subject: [PATCH 06/16] Fix compilation of libGLESv2 with older MinGW-w64 - headers - -Fix compilation of libGLESv2 for mingw-headers predating MinGW-w64 -svn commit 5567 (like MinGW-builds gcc 4.7.2-rev8, the toolchain -we officially support). - -Commit 5567 added the D3DCOMPILER_DLL define to d3dcompiler.h, but with -a trailing semicolon that has then fixed in commit 5783. Any toolchain -that ships MinGW-w64 headers from a version in between (like -MinGW-builds gcc 4.7.2-rev11) will unfortunately remain broken. - -Change-Id: I31272a1a991c4fc0f1611f8fb7510be51d6bb925 ---- - .../angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -index acbd852..eb0dfa5 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -@@ -10,6 +10,21 @@ - - #include "common/utilities.h" - -+#if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL) -+ -+// Add define + typedefs for older MinGW-w64 headers (pre 5783) -+ -+#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" -+ -+HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, -+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, -+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages); -+typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const char *filename, -+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, -+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages); -+ -+#endif // __MINGW32__ && !D3DCOMPILER_DLL -+ - namespace rx - { - --- -1.9.0.msysgit.0 - diff --git a/src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch b/src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch deleted file mode 100644 index c796ebc95e..0000000000 --- a/src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 76152feea8265f40fec8c6e53f976dbd82fb6c80 Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Tue, 16 Sep 2014 23:56:43 +0300 -Subject: [PATCH 07/16] Fix ANGLE build with Microsoft Visual Studio "14" CTP - -This version has a few new C99 support added, including snprintf. - -Change-Id: I5776456fd94254a64f08791f59bc775cb24c9b7f ---- - src/3rdparty/angle/src/common/angleutils.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h -index 50a4132..ddbbd5f 100644 ---- a/src/3rdparty/angle/src/common/angleutils.h -+++ b/src/3rdparty/angle/src/common/angleutils.h -@@ -135,7 +135,7 @@ inline std::string Str(int i) - std::string FormatString(const char *fmt, va_list vararg); - std::string FormatString(const char *fmt, ...); - --#if defined(_MSC_VER) -+#if defined(_MSC_VER) && _MSC_VER < 1900 - #define snprintf _snprintf - #endif - --- -1.9.0.msysgit.0 - diff --git a/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch b/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch index 7c821580d0..801db67682 100644 --- a/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch +++ b/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch @@ -1,6 +1,6 @@ -From 4f6dd1f7cdce3340723cc23e0aea27b156fa3497 Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Tue, 16 Sep 2014 23:59:40 +0300 +From 4a5960465d1632ab089320fcbba4af294d58fd9a Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Fri, 7 Nov 2014 14:05:36 +0200 Subject: [PATCH 08/16] ANGLE: Dynamically load D3D compiler from a list or the environment @@ -11,29 +11,28 @@ QT_D3DCOMPILER_DLL. Change-Id: I0d7a8a8a36cc571836f8fa59ea14513b9b19c19b --- - .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 27 +++++++++++++++++++--- - 1 file changed, 24 insertions(+), 3 deletions(-) + .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 27 ++++++++++++++++++++++ + 1 file changed, 27 insertions(+) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -index eb0dfa5..5715d5f 100644 +index bfeaf51..9d003b4 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -@@ -25,6 +25,10 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const - - #endif // __MINGW32__ && !D3DCOMPILER_DLL +@@ -11,6 +11,10 @@ + #include "common/features.h" + #include "common/utilities.h" +#ifndef QT_D3DCOMPILER_DLL +#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL +#endif + - namespace rx + // Definitions local to the translation unit + namespace { - -@@ -59,10 +63,27 @@ bool HLSLCompiler::initialize() +@@ -132,6 +136,29 @@ bool HLSLCompiler::initialize() } #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES -- if (!mD3DCompilerModule) + // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL + const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL"); + if (!defaultCompiler) @@ -51,15 +50,15 @@ index eb0dfa5..5715d5f 100644 + + // Load the first available known compiler DLL + for (int i = 0; compilerDlls[i]; ++i) - { -- // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. -- mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL); ++ { + mD3DCompilerModule = LoadLibrary(compilerDlls[i]); + if (mD3DCompilerModule) + break; - } - ++ } ++ if (!mD3DCompilerModule) + { + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0009-ANGLE-Support-WinRT.patch b/src/angle/patches/0009-ANGLE-Support-WinRT.patch index f4bae46b63..a38fb4ea13 100644 --- a/src/angle/patches/0009-ANGLE-Support-WinRT.patch +++ b/src/angle/patches/0009-ANGLE-Support-WinRT.patch @@ -1,1126 +1,673 @@ -From 7ff7dd46f54e23ae309887366bf477de9c33005b Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Wed, 17 Sep 2014 00:58:29 +0300 +From 4d150ba3814f824f1cadaedbdb83d0ac79d0e1a2 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Fri, 14 Nov 2014 09:28:11 +0200 Subject: [PATCH 09/16] ANGLE: Support WinRT -This enables EGL for WinRT's native types, and adjusts some codepaths -to accommodate differences between desktop Windows and WinRT. +Tweak ANGLE's existing support for WinRT to allow for changing the +window size on Windows Phone. -- WinRT native handles added to eglplatform.h -- References to native handles in libEGL/libGLESv2 follow eglplatform.h -- D3D 11.1 structures and methods used when necessary -- TLS replaced with thread attribute -- LocalAlloc/Free replaced with Heap API - -Change-Id: Ia90377e700d335a1c569c2145008dd4b0dfd84d3 -Reviewed-by: Friedemann Kleint +Change-Id: Ia312b5318b977838a2953f1f530487cbf24974bc --- - src/3rdparty/angle/include/EGL/eglplatform.h | 10 +- - src/3rdparty/angle/src/common/platform.h | 3 + - src/3rdparty/angle/src/common/tls.cpp | 37 ++++- - src/3rdparty/angle/src/common/tls.h | 6 +- - src/3rdparty/angle/src/common/utilities.cpp | 51 +++++- - src/3rdparty/angle/src/libEGL/Display.cpp | 13 +- - src/3rdparty/angle/src/libEGL/Display.h | 6 +- - src/3rdparty/angle/src/libEGL/Surface.cpp | 185 ++++++++++++++++++++- - src/3rdparty/angle/src/libEGL/Surface.h | 37 ++++- - src/3rdparty/angle/src/libEGL/libEGL.cpp | 8 +- - src/3rdparty/angle/src/libEGL/main.cpp | 21 +++ - src/3rdparty/angle/src/libGLESv2/main.cpp | 20 +++ - src/3rdparty/angle/src/libGLESv2/main.h | 4 + - .../angle/src/libGLESv2/renderer/Renderer.h | 2 +- - .../angle/src/libGLESv2/renderer/SwapChain.h | 15 +- - .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 11 +- - .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 13 +- - .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 4 +- - .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 73 ++++++-- - .../src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h | 6 +- - .../src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp | 2 +- - .../src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h | 2 +- - 22 files changed, 481 insertions(+), 48 deletions(-) + src/3rdparty/angle/include/EGL/eglplatform.h | 5 +- + src/3rdparty/angle/src/common/NativeWindow.h | 7 +- + src/3rdparty/angle/src/common/platform.h | 4 +- + .../angle/src/common/win32/NativeWindow.cpp | 2 +- + .../src/common/winrt/CoreWindowNativeWindow.cpp | 87 +++++++++++++--------- + .../src/common/winrt/CoreWindowNativeWindow.h | 48 ++---------- + .../src/common/winrt/InspectableNativeWindow.cpp | 8 +- + .../src/common/winrt/InspectableNativeWindow.h | 7 +- + .../common/winrt/SwapChainPanelNativeWindow.cpp | 2 +- + .../src/common/winrt/SwapChainPanelNativeWindow.h | 2 +- + src/3rdparty/angle/src/libEGL/Display.h | 1 + + src/3rdparty/angle/src/libEGL/Surface.cpp | 45 ++++++++--- + src/3rdparty/angle/src/libEGL/Surface.h | 4 + + src/3rdparty/angle/src/libEGL/libEGL.cpp | 20 +++++ + .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 2 +- + .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 74 +++++++++++------- + .../src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h | 2 + + 17 files changed, 189 insertions(+), 131 deletions(-) diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h -index 3ab8844..ea9f577 100644 +index 3793e57..2eb3674 100644 --- a/src/3rdparty/angle/include/EGL/eglplatform.h +++ b/src/3rdparty/angle/include/EGL/eglplatform.h -@@ -67,7 +67,15 @@ - * implementations. - */ - --#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ -+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */ -+ -+struct IUnknown; -+ -+typedef IUnknown *EGLNativeDisplayType; -+typedef void *EGLNativePixmapType; -+typedef IUnknown *EGLNativeWindowType; -+ -+#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN 1 +@@ -73,13 +73,14 @@ #endif -diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h -index d07297d..387ba41 100644 ---- a/src/3rdparty/angle/src/common/platform.h -+++ b/src/3rdparty/angle/src/common/platform.h -@@ -11,6 +11,9 @@ + #include - #if defined(_WIN32) || defined(_WIN64) - # define ANGLE_PLATFORM_WINDOWS 1 -+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) -+# define ANGLE_PLATFORM_WINRT 1 -+# endif - #elif defined(__APPLE__) - # define ANGLE_PLATFORM_APPLE 1 - # define ANGLE_PLATFORM_POSIX 1 -diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp -index 6b78219..c46fab5 100644 ---- a/src/3rdparty/angle/src/common/tls.cpp -+++ b/src/3rdparty/angle/src/common/tls.cpp -@@ -10,11 +10,28 @@ +-typedef HDC EGLNativeDisplayType; + typedef HBITMAP EGLNativePixmapType; - #include - -+#if defined(ANGLE_PLATFORM_WINRT) -+#include -+std::vector *tls = nullptr; -+std::vector *freeIndices = nullptr; -+#endif -+ - TLSIndex CreateTLSIndex() - { - TLSIndex index; - --#ifdef ANGLE_PLATFORM_WINDOWS -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (!tls) -+ tls = new std::vector; -+ if (freeIndices && !freeIndices->empty()) { -+ index = freeIndices->back(); -+ freeIndices->pop_back(); -+ return index; -+ } else { -+ tls->push_back(nullptr); -+ return tls->size() - 1; -+ } -+#elif defined(ANGLE_PLATFORM_WINDOWS) - index = TlsAlloc(); - #elif defined(ANGLE_PLATFORM_POSIX) - // Create global pool key -@@ -36,7 +53,12 @@ bool DestroyTLSIndex(TLSIndex index) - return false; - } - --#ifdef ANGLE_PLATFORM_WINDOWS -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (!freeIndices) -+ freeIndices = new std::vector; -+ freeIndices->push_back(index); -+ return true; -+#elif ANGLE_PLATFORM_WINDOWS - return (TlsFree(index) == TRUE); - #elif defined(ANGLE_PLATFORM_POSIX) - return (pthread_key_delete(index) == 0); -@@ -51,7 +73,10 @@ bool SetTLSValue(TLSIndex index, void *value) - return false; - } - --#ifdef ANGLE_PLATFORM_WINDOWS -+#if defined(ANGLE_PLATFORM_WINRT) -+ tls->at(index) = value; -+ return true; -+#elif defined(ANGLE_PLATFORM_WINDOWS) - return (TlsSetValue(index, value) == TRUE); - #elif defined(ANGLE_PLATFORM_POSIX) - return (pthread_setspecific(index, value) == 0); -@@ -60,13 +85,17 @@ bool SetTLSValue(TLSIndex index, void *value) - - void *GetTLSValue(TLSIndex index) - { -+#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation - assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index"); -+#endif - if (index == TLS_INVALID_INDEX) - { - return NULL; - } - --#ifdef ANGLE_PLATFORM_WINDOWS -+#if defined(ANGLE_PLATFORM_WINRT) -+ return tls->at(index); -+#elif defined(ANGLE_PLATFORM_WINDOWS) - return TlsGetValue(index); - #elif defined(ANGLE_PLATFORM_POSIX) - return pthread_getspecific(index); -diff --git a/src/3rdparty/angle/src/common/tls.h b/src/3rdparty/angle/src/common/tls.h -index 4b25fbc..c40ae1a 100644 ---- a/src/3rdparty/angle/src/common/tls.h -+++ b/src/3rdparty/angle/src/common/tls.h -@@ -11,7 +11,11 @@ - - #include "common/platform.h" - --#ifdef ANGLE_PLATFORM_WINDOWS -+#if defined(ANGLE_PLATFORM_WINRT) -+ typedef size_t TLSIndex; -+# define TLS_OUT_OF_INDEXES (static_cast(-1)) -+# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES -+#elif defined(ANGLE_PLATFORM_WINDOWS) - typedef DWORD TLSIndex; - # define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES) - #elif defined(ANGLE_PLATFORM_POSIX) -diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp -index 405f119..4b8e325 100644 ---- a/src/3rdparty/angle/src/common/utilities.cpp -+++ b/src/3rdparty/angle/src/common/utilities.cpp -@@ -9,6 +9,14 @@ - #include "common/utilities.h" - #include "common/mathutil.h" - #include "common/platform.h" -+#if defined(ANGLE_PLATFORM_WINRT) -+# include -+# include -+# include -+# include -+ using namespace Microsoft::WRL; -+ using namespace ABI::Windows::Storage; -+#endif - - #include - -@@ -441,7 +449,48 @@ int VariableSortOrder(GLenum type) - - std::string getTempPath() - { --#ifdef ANGLE_PLATFORM_WINDOWS -+#if defined(ANGLE_PLATFORM_WINRT) -+ static std::string path; -+ -+ while (path.empty()) -+ { -+ ComPtr factory; -+ Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData); -+ HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory)); -+ if (FAILED(result)) -+ break; -+ -+ ComPtr applicationData; -+ result = factory->get_Current(&applicationData); -+ if (FAILED(result)) -+ break; -+ -+ ComPtr storageFolder; -+ result = applicationData->get_LocalFolder(&storageFolder); -+ if (FAILED(result)) -+ break; -+ -+ ComPtr localFolder; -+ result = storageFolder.As(&localFolder); -+ if (FAILED(result)) -+ break; -+ -+ HSTRING localFolderPath; -+ result = localFolder->get_Path(&localFolderPath); -+ if (FAILED(result)) -+ break; -+ -+ std::wstring_convert< std::codecvt_utf8 > converter; -+ path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL)); -+ if (path.empty()) -+ { -+ UNREACHABLE(); -+ break; -+ } -+ } -+ -+ return path; -+#elif defined(ANGLE_PLATFORM_WINDOWS) - char path[MAX_PATH]; - DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); - if (pathLen == 0) -diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp -index aaebdb3..ba09631 100644 ---- a/src/3rdparty/angle/src/libEGL/Display.cpp -+++ b/src/3rdparty/angle/src/libEGL/Display.cpp -@@ -56,6 +56,10 @@ Display::Display(EGLNativeDisplayType displayId, EGLint displayType) - mRequestedDisplayType(displayType), - mRenderer(NULL) - { -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (mDisplayId) -+ mDisplayId->AddRef(); -+#endif - } - - Display::~Display() -@@ -68,6 +72,11 @@ Display::~Display() - { - displays->erase(iter); - } -+ -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (mDisplayId) -+ mDisplayId->Release(); -+#endif - } - - bool Display::initialize() -@@ -192,7 +201,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) - - - --EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList) -+EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList) - { - const Config *configuration = mConfigSet.get(config); - EGLint postSubBufferSupported = EGL_FALSE; -@@ -493,7 +502,7 @@ bool Display::isValidSurface(egl::Surface *surface) - return mSurfaceSet.find(surface) != mSurfaceSet.end(); - } - --bool Display::hasExistingWindowSurface(HWND window) -+bool Display::hasExistingWindowSurface(EGLNativeWindowType window) - { - for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) - { -diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h -index 250878f..73ba767 100644 ---- a/src/3rdparty/angle/src/libEGL/Display.h -+++ b/src/3rdparty/angle/src/libEGL/Display.h -@@ -43,7 +43,7 @@ class Display - bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig); - bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value); - -- EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList); -+ EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList); - EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList); - EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess); - -@@ -54,7 +54,7 @@ class Display - bool isValidConfig(EGLConfig config); - bool isValidContext(gl::Context *context); - bool isValidSurface(egl::Surface *surface); -- bool hasExistingWindowSurface(HWND window); -+ bool hasExistingWindowSurface(EGLNativeWindowType window); - - rx::Renderer *getRenderer() { return mRenderer; }; - -@@ -65,6 +65,8 @@ class Display - const char *getExtensionString() const; - const char *getVendorString() const; - -+ EGLNativeDisplayType getDisplayId() const { return mDisplayId; } -+ - private: - DISALLOW_COPY_AND_ASSIGN(Display); - -diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp -index 13b0f20..fa79961 100644 ---- a/src/3rdparty/angle/src/libEGL/Surface.cpp -+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp -@@ -22,10 +22,20 @@ - #include "libEGL/main.h" - #include "libEGL/Display.h" - -+#if defined(ANGLE_PLATFORM_WINRT) -+# include "wrl.h" -+# include "windows.graphics.display.h" -+# include "windows.ui.core.h" -+using namespace ABI::Windows::Graphics::Display; -+using namespace ABI::Windows::Foundation; -+using namespace ABI::Windows::UI::Core; -+using namespace Microsoft::WRL; -+#endif -+ - namespace egl - { - --Surface::Surface(Display *display, const Config *config, HWND window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported) -+Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported) - : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported) - { - mRenderer = mDisplay->getRenderer(); -@@ -43,6 +53,17 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint fix - mHeight = height; - setSwapInterval(1); - mFixedSize = fixedSize; -+ mSwapFlags = rx::SWAP_NORMAL; -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (mWindow) -+ mWindow->AddRef(); -+ mScaleFactor = 1.0; -+ mSizeToken.value = 0; -+ mDpiToken.value = 0; -+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -+ mOrientationToken.value = 0; -+# endif -+#endif - - subclassWindow(); - } -@@ -64,16 +85,86 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL - setSwapInterval(1); - // This constructor is for offscreen surfaces, which are always fixed-size. - mFixedSize = EGL_TRUE; -+ mSwapFlags = rx::SWAP_NORMAL; -+#if defined(ANGLE_PLATFORM_WINRT) -+ mScaleFactor = 1.0; -+ mSizeToken.value = 0; -+ mDpiToken.value = 0; -+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -+ mOrientationToken.value = 0; -+# endif -+#endif - } - - Surface::~Surface() - { -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (mSizeToken.value) { -+ ComPtr coreWindow; -+ HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf()); -+ ASSERT(SUCCEEDED(hr)); -+ -+ hr = coreWindow->remove_SizeChanged(mSizeToken); -+ ASSERT(SUCCEEDED(hr)); -+ } -+ if (mDpiToken.value) { -+ ComPtr displayInformation; -+ HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); -+ ASSERT(SUCCEEDED(hr)); -+ -+ hr = displayInformation->remove_DpiChanged(mDpiToken); -+ ASSERT(SUCCEEDED(hr)); -+ } -+# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -+ if (mOrientationToken.value) { -+ ComPtr displayInformation; -+ HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); -+ ASSERT(SUCCEEDED(hr)); -+ -+ hr = displayInformation->remove_OrientationChanged(mOrientationToken); -+ ASSERT(SUCCEEDED(hr)); -+ } -+# endif -+#endif - unsubclassWindow(); - release(); - } - - bool Surface::initialize() - { -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (!mFixedSize) { -+ HRESULT hr; -+ ComPtr displayInformation; -+ hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); -+ ASSERT(SUCCEEDED(hr)); -+ onDpiChanged(displayInformation.Get(), 0); -+ hr = displayInformation->add_DpiChanged(Callback>(this, &Surface::onDpiChanged).Get(), -+ &mDpiToken); -+ ASSERT(SUCCEEDED(hr)); -+ -+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -+ onOrientationChanged(displayInformation.Get(), 0); -+ hr = displayInformation->add_OrientationChanged(Callback>(this, &Surface::onOrientationChanged).Get(), -+ &mOrientationToken); -+ ASSERT(SUCCEEDED(hr)); -+# endif -+ -+ ComPtr coreWindow; -+ hr = mWindow->QueryInterface(coreWindow.GetAddressOf()); -+ ASSERT(SUCCEEDED(hr)); -+ -+ Rect rect; -+ hr = coreWindow->get_Bounds(&rect); -+ ASSERT(SUCCEEDED(hr)); -+ mWidth = rect.Width * mScaleFactor; -+ mHeight = rect.Height * mScaleFactor; -+ hr = coreWindow->add_SizeChanged(Callback>(this, &Surface::onSizeChanged).Get(), -+ &mSizeToken); -+ ASSERT(SUCCEEDED(hr)); -+ } -+#endif -+ - if (!resetSwapChain()) - return false; - -@@ -90,6 +181,11 @@ void Surface::release() - mTexture->releaseTexImage(); - mTexture = NULL; - } -+ -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (mWindow) -+ mWindow->Release(); -+#endif - } - - bool Surface::resetSwapChain() -@@ -99,6 +195,7 @@ bool Surface::resetSwapChain() - int width; - int height; - -+#if !defined(ANGLE_PLATFORM_WINRT) - if (!mFixedSize) - { - RECT windowRect; -@@ -114,6 +211,7 @@ bool Surface::resetSwapChain() - height = windowRect.bottom - windowRect.top; - } - else -+#endif - { - // non-window surface - size is determined at creation - width = mWidth; -@@ -207,7 +305,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) - return true; - } - -- EGLint status = mSwapChain->swapRect(x, y, width, height); -+ EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags); - - if (status == EGL_CONTEXT_LOST) - { -@@ -224,7 +322,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) - return true; - } - --HWND Surface::getWindowHandle() -+EGLNativeWindowType Surface::getWindowHandle() - { - return mWindow; - } -@@ -233,6 +331,7 @@ HWND Surface::getWindowHandle() - #define kSurfaceProperty _TEXT("Egl::SurfaceOwner") - #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") - -+#if !defined(ANGLE_PLATFORM_WINRT) - static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) - { - if (message == WM_SIZE) -@@ -246,9 +345,11 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam - WNDPROC prevWndFunc = reinterpret_cast(GetProp(hwnd, kParentWndProc)); - return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); - } -+#endif - - void Surface::subclassWindow() - { -+#if !defined(ANGLE_PLATFORM_WINRT) - if (!mWindow) - { - return; -@@ -272,10 +373,14 @@ void Surface::subclassWindow() - SetProp(mWindow, kSurfaceProperty, reinterpret_cast(this)); - SetProp(mWindow, kParentWndProc, reinterpret_cast(oldWndProc)); - mWindowSubclassed = true; -+#else -+ mWindowSubclassed = false; -+#endif - } - - void Surface::unsubclassWindow() - { -+#if !defined(ANGLE_PLATFORM_WINRT) - if(!mWindowSubclassed) - { - return; -@@ -299,16 +404,18 @@ void Surface::unsubclassWindow() - RemoveProp(mWindow, kSurfaceProperty); - RemoveProp(mWindow, kParentWndProc); - mWindowSubclassed = false; -+#endif - } - - bool Surface::checkForOutOfDateSwapChain() - { -- RECT client; - int clientWidth = getWidth(); - int clientHeight = getHeight(); - bool sizeDirty = false; -+#if !defined(ANGLE_PLATFORM_WINRT) - if (!mFixedSize && !IsIconic(getWindowHandle())) - { -+ RECT client; - // The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized - // because that's not a useful size to render to. - if (!GetClientRect(getWindowHandle(), &client)) -@@ -322,6 +429,7 @@ bool Surface::checkForOutOfDateSwapChain() - clientHeight = client.bottom - client.top; - sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); - } -+#endif - - bool wasDirty = (mSwapIntervalDirty || sizeDirty); - -@@ -446,4 +554,73 @@ EGLenum Surface::getFormat() const - { - return mConfig->mRenderTargetFormat; - } -+ -+#if defined(ANGLE_PLATFORM_WINRT) -+ -+HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args) -+{ -+ HRESULT hr; -+ Size size; -+ hr = args->get_Size(&size); -+ ASSERT(SUCCEEDED(hr)); -+ -+ resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5), -+ std::floor(size.Height * mScaleFactor + 0.5)); -+ -+ if (static_cast(getCurrentDrawSurface()) == this) -+ { -+ glMakeCurrent(glGetCurrentContext(), static_cast(getCurrentDisplay()), this); -+ } -+ -+ return S_OK; -+} -+ -+HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *) -+{ -+ HRESULT hr; -+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -+ ComPtr displayInformation2; -+ hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf()); -+ ASSERT(SUCCEEDED(hr)); -+ -+ hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor); -+ ASSERT(SUCCEEDED(hr)); -+# else -+ ResolutionScale resolutionScale; -+ hr = displayInformation->get_ResolutionScale(&resolutionScale); -+ ASSERT(SUCCEEDED(hr)); -+ -+ mScaleFactor = double(resolutionScale) / 100.0; -+# endif -+ return S_OK; -+} -+ -+# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -+HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *) -+{ -+ HRESULT hr; -+ DisplayOrientations orientation; -+ hr = displayInformation->get_CurrentOrientation(&orientation); -+ ASSERT(SUCCEEDED(hr)); -+ switch (orientation) { -+ default: -+ case DisplayOrientations_Portrait: -+ mSwapFlags = rx::SWAP_NORMAL; -+ break; -+ case DisplayOrientations_Landscape: -+ mSwapFlags = rx::SWAP_ROTATE_90; -+ break; -+ case DisplayOrientations_LandscapeFlipped: -+ mSwapFlags = rx::SWAP_ROTATE_270; -+ break; -+ case DisplayOrientations_PortraitFlipped: -+ mSwapFlags = rx::SWAP_ROTATE_180; -+ break; -+ } -+ return S_OK; -+} -+# endif -+ -+#endif -+ - } -diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h -index 24c66b7..ebffce8fe 100644 ---- a/src/3rdparty/angle/src/libEGL/Surface.h -+++ b/src/3rdparty/angle/src/libEGL/Surface.h -@@ -15,6 +15,20 @@ - - #include "common/angleutils.h" - -+#if defined(ANGLE_PLATFORM_WINRT) -+#include -+namespace ABI { namespace Windows { -+ namespace UI { namespace Core { -+ struct ICoreWindow; -+ struct IWindowSizeChangedEventArgs; -+ } } -+ namespace Graphics { namespace Display { -+ struct IDisplayInformation; -+ } } -+} } -+struct IInspectable; -+#endif -+ - namespace gl - { - class Texture2D; -@@ -33,7 +47,7 @@ class Config; - class Surface - { - public: -- Surface(Display *display, const egl::Config *config, HWND window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported); -+ Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported); - Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget); - - virtual ~Surface(); -@@ -42,7 +56,7 @@ class Surface - void release(); - bool resetSwapChain(); - -- HWND getWindowHandle(); -+ EGLNativeWindowType getWindowHandle(); - bool swap(); - bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height); - -@@ -71,6 +85,14 @@ class Surface - private: - DISALLOW_COPY_AND_ASSIGN(Surface); - -+#if defined(ANGLE_PLATFORM_WINRT) -+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); -+ HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); -+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -+ HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); -+# endif -+#endif -+ - Display *const mDisplay; - rx::Renderer *mRenderer; - -@@ -83,7 +105,7 @@ private: - bool resetSwapChain(int backbufferWidth, int backbufferHeight); - bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - -- const HWND mWindow; // Window that the surface is created for. -+ const EGLNativeWindowType mWindow; // Window that the surface is created for. - bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking - const egl::Config *mConfig; // EGL config surface was created with - EGLint mHeight; // Height of surface -@@ -104,9 +126,18 @@ private: - EGLint mSwapInterval; - EGLint mPostSubBufferSupported; - EGLint mFixedSize; -+ EGLint mSwapFlags; - - bool mSwapIntervalDirty; - gl::Texture2D *mTexture; -+#if defined(ANGLE_PLATFORM_WINRT) -+ double mScaleFactor; -+ EventRegistrationToken mSizeToken; -+ EventRegistrationToken mDpiToken; -+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -+ EventRegistrationToken mOrientationToken; -+# endif -+#endif - }; - } - -diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp -index 7ce2b93..7ea11c5 100644 ---- a/src/3rdparty/angle/src/libEGL/libEGL.cpp -+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp -@@ -13,6 +13,7 @@ - - #include "common/debug.h" - #include "common/version.h" -+#include "common/platform.h" - #include "libGLESv2/Context.h" - #include "libGLESv2/Texture.h" - #include "libGLESv2/main.h" -@@ -120,12 +121,13 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis - } - - EGLNativeDisplayType displayId = static_cast(native_display); -- -+#if !defined(ANGLE_PLATFORM_WINRT) - // Validate the display device context - if (WindowFromDC(displayId) == NULL) - { - return egl::success(EGL_NO_DISPLAY); - } -+#endif - - EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; - if (attrib_list) -@@ -327,14 +329,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG - return EGL_NO_SURFACE; - } - -+#if !defined(ANGLE_PLATFORM_WINRT) - HWND window = (HWND)win; - - if (!IsWindow(window)) - { - return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); - } -+#endif - -- return display->createWindowSurface(window, config, attrib_list); -+ return display->createWindowSurface(win, config, attrib_list); - } - - EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) -diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp -index 8a1baef..e74737e 100644 ---- a/src/3rdparty/angle/src/libEGL/main.cpp -+++ b/src/3rdparty/angle/src/libEGL/main.cpp -@@ -11,6 +11,9 @@ - #include "common/debug.h" - #include "common/tls.h" - -+#if defined(ANGLE_PLATFORM_WINRT) -+__declspec(thread) -+#endif - static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; - - namespace egl -@@ -18,6 +21,12 @@ namespace egl - - Current *AllocateCurrent() - { -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (currentTLS == TLS_OUT_OF_INDEXES) -+ { -+ currentTLS = CreateTLSIndex(); -+ } -+#endif - ASSERT(currentTLS != TLS_OUT_OF_INDEXES); - if (currentTLS == TLS_OUT_OF_INDEXES) - { -@@ -42,6 +51,12 @@ Current *AllocateCurrent() - - void DeallocateCurrent() - { -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (currentTLS == TLS_OUT_OF_INDEXES) -+ { -+ return; -+ } -+#endif - Current *current = reinterpret_cast(GetTLSValue(currentTLS)); - SafeDelete(current); - SetTLSValue(currentTLS, NULL); -@@ -72,6 +87,10 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved - } +-#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP /* Windows Store */ ++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */ + #include ++typedef IInspectable* EGLNativeDisplayType; + typedef IInspectable* EGLNativeWindowType; + #else ++typedef HDC EGLNativeDisplayType; + typedef HWND EGLNativeWindowType; #endif -+#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain -+ return DisableThreadLibraryCalls(instance); -+#endif -+ - currentTLS = CreateTLSIndex(); - if (currentTLS == TLS_OUT_OF_INDEXES) - { -@@ -86,7 +105,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved - break; - case DLL_THREAD_DETACH: - { -+#if !defined(ANGLE_PLATFORM_WINRT) - egl::DeallocateCurrent(); -+#endif - } - break; - case DLL_PROCESS_DETACH: -diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp -index 1c577bc..51447e2 100644 ---- a/src/3rdparty/angle/src/libGLESv2/main.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp -@@ -11,6 +11,9 @@ - - #include "common/tls.h" - -+#if defined(ANGLE_PLATFORM_WINRT) -+__declspec(thread) -+#endif - static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; - - namespace gl -@@ -18,6 +21,12 @@ namespace gl - - Current *AllocateCurrent() - { -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (currentTLS == TLS_OUT_OF_INDEXES) -+ { -+ currentTLS = CreateTLSIndex(); -+ } -+#endif - ASSERT(currentTLS != TLS_OUT_OF_INDEXES); - if (currentTLS == TLS_OUT_OF_INDEXES) - { -@@ -39,6 +48,12 @@ Current *AllocateCurrent() - - void DeallocateCurrent() - { -+#if defined(ANGLE_PLATFORM_WINRT) -+ if (currentTLS == TLS_OUT_OF_INDEXES) -+ { -+ return; -+ } -+#endif - Current *current = reinterpret_cast(GetTLSValue(currentTLS)); - SafeDelete(current); - SetTLSValue(currentTLS, NULL); -@@ -54,6 +69,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved - { - case DLL_PROCESS_ATTACH: - { -+#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain -+ return DisableThreadLibraryCalls(instance); -+#endif - currentTLS = CreateTLSIndex(); - if (currentTLS == TLS_OUT_OF_INDEXES) - { -@@ -73,8 +91,10 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved - break; - case DLL_PROCESS_DETACH: - { -+#if !defined(ANGLE_PLATFORM_WINRT) - gl::DeallocateCurrent(); - DestroyTLSIndex(currentTLS); -+#endif - } - break; - default: -diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h -index 684c302..c30ad33 100644 ---- a/src/3rdparty/angle/src/libGLESv2/main.h -+++ b/src/3rdparty/angle/src/libGLESv2/main.h -@@ -14,6 +14,10 @@ - #include - #include - -+#ifndef Sleep -+#define Sleep(ms) WaitForSingleObjectEx(GetCurrentThread(), ms, FALSE) -+#endif -+ - namespace egl - { - class Display; -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h -index 7adbea2..b224974 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h -@@ -107,7 +107,7 @@ class Renderer - - virtual void sync(bool block) = 0; - -- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; -+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; - - virtual gl::Error generateSwizzle(gl::Texture *texture) = 0; - virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0; -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h -index 12be9b3..1ec702f 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h -@@ -15,14 +15,23 @@ - - #include - #include -+#include +diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h +index dc5fc8f..9e93aea 100644 +--- a/src/3rdparty/angle/src/common/NativeWindow.h ++++ b/src/3rdparty/angle/src/common/NativeWindow.h +@@ -44,10 +44,11 @@ typedef IDXGIFactory DXGIFactory; namespace rx { - -+enum SwapFlags -+{ -+ SWAP_NORMAL = 0, -+ SWAP_ROTATE_90 = 1, -+ SWAP_ROTATE_270 = 2, -+ SWAP_ROTATE_180 = SWAP_ROTATE_90|SWAP_ROTATE_270, -+}; + - class SwapChain + class NativeWindow { - public: -- SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) -+ SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat) - { - } -@@ -31,13 +40,13 @@ class SwapChain +- public: +- explicit NativeWindow(EGLNativeWindowType window); ++public: ++ explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display); - virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0; - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; -- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0; -+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) = 0; - virtual void recreate() = 0; + bool initialize(); + bool getClientRect(LPRECT rect); +@@ -58,9 +59,11 @@ class NativeWindow + DXGISwapChain** swapChain); - virtual HANDLE getShareHandle() {return mShareHandle;}; + inline EGLNativeWindowType getNativeWindow() const { return mWindow; } ++ inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; } - protected: -- const HWND mWindow; // Window that the surface is created for. -+ const EGLNativeWindowType mWindow; // Window that the surface is created for. - const GLenum mBackBufferFormat; - const GLenum mDepthBufferFormat; + private: + EGLNativeWindowType mWindow; ++ EGLNativeDisplayType mDisplay; -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -index 5715d5f..d013197 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp -@@ -9,6 +9,7 @@ - #include "libGLESv2/main.h" + #if defined(ANGLE_ENABLE_WINDOWS_STORE) + std::shared_ptr mImpl; +diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h +index cd12dba..0065ec7 100644 +--- a/src/3rdparty/angle/src/common/platform.h ++++ b/src/3rdparty/angle/src/common/platform.h +@@ -34,7 +34,7 @@ + #endif - #include "common/utilities.h" -+#include "common/platform.h" - - #if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL) - -@@ -45,11 +46,7 @@ HLSLCompiler::~HLSLCompiler() - - bool HLSLCompiler::initialize() - { --<<<<<<< HEAD -- TRACE_EVENT0("gpu", "initializeCompiler"); --======= - #if !defined(ANGLE_PLATFORM_WINRT) -->>>>>>> 429814a... ANGLE: remove event tracing - #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) - // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. - static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; -@@ -94,7 +91,9 @@ bool HLSLCompiler::initialize() - - mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); - ASSERT(mD3DCompileFunc); -- -+#else -+ mD3DCompileFunc = reinterpret_cast(&D3DCompile); -+#endif - return mD3DCompileFunc != NULL; + #ifdef ANGLE_PLATFORM_WINDOWS +-# if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP ++# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + # define ANGLE_ENABLE_WINDOWS_STORE 1 + # endif + # ifndef STRICT +@@ -67,7 +67,9 @@ + # if defined(ANGLE_ENABLE_WINDOWS_STORE) + # include + # if defined(_DEBUG) ++# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) + # include ++# endif + # include + # endif + # endif +diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp +index aa2bfa4..2440747 100644 +--- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp ++++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp +@@ -16,7 +16,7 @@ bool IsValidEGLNativeWindowType(EGLNativeWindowType window) + return (IsWindow(window) == TRUE); } -@@ -111,7 +110,9 @@ void HLSLCompiler::release() - ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, - const UINT optimizationFlags[], const char *flagNames[], int attempts) const +-NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window) ++NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display) { -+#if !defined(ANGLE_PLATFORM_WINRT) - ASSERT(mD3DCompilerModule && mD3DCompileFunc); -+#endif + } - if (!hlsl) +diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp +index 0e63fa5..9b65c15 100644 +--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp ++++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp +@@ -6,21 +6,25 @@ + + // CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types. + +-#include ++#include + #include "common/winrt/CoreWindowNativeWindow.h" + using namespace ABI::Windows::Foundation::Collections; + + namespace rx + { ++ ++typedef ITypedEventHandler SizeChangedHandler; ++ + CoreWindowNativeWindow::~CoreWindowNativeWindow() + { + unregisterForSizeChangeEvents(); + } + +-bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet) ++bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) + { + ComPtr props = propertySet; + ComPtr win = window; ++ ComPtr displayInformation = display; + SIZE swapChainSize = {}; + bool swapChainSizeSpecified = false; + HRESULT result = S_OK; +@@ -47,6 +51,29 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet + + if (SUCCEEDED(result)) { -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -index ed880c3..0bb7489 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -@@ -6,6 +6,7 @@ - - // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. - -+#include "common/platform.h" - #include "libGLESv2/main.h" - #include "libGLESv2/Buffer.h" - #include "libGLESv2/FramebufferAttachment.h" -@@ -135,6 +136,7 @@ EGLint Renderer11::initialize() - return EGL_NOT_INITIALIZED; - } - -+#if !defined(ANGLE_PLATFORM_WINRT) - mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); - mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); - -@@ -153,6 +155,7 @@ EGLint Renderer11::initialize() - ERR("Could not retrieve D3D11CreateDevice address - aborting!\n"); - return EGL_NOT_INITIALIZED; - } ++ result = displayInformation.As(&mDisplayInformation); ++ } ++ ++ if (SUCCEEDED(result)) ++ { ++#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP ++ ComPtr displayInformation2; ++ result = mDisplayInformation.As(&displayInformation2); ++ ASSERT(SUCCEEDED(result)); ++ ++ result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor); ++ ASSERT(SUCCEEDED(result)); ++#else ++ ABI::Windows::Graphics::Display::ResolutionScale resolutionScale; ++ result = mDisplayInformation->get_ResolutionScale(&resolutionScale); ++ ASSERT(SUCCEEDED(result)); ++ ++ mScaleFactor = DOUBLE(resolutionScale) / 100.0; +#endif - - D3D_FEATURE_LEVEL featureLevels[] = - { -@@ -207,7 +210,7 @@ EGLint Renderer11::initialize() ++ } ++ ++ if (SUCCEEDED(result)) ++ { + // If a swapchain size is specfied, then the automatic resize + // behaviors implemented by the host should be disabled. The swapchain + // will be still be scaled when being rendered to fit the bounds +@@ -60,7 +87,14 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet + } + else + { +- result = GetCoreWindowSizeInPixels(mCoreWindow, &mClientRect); ++ ABI::Windows::Foundation::Rect rect; ++ HRESULT result = mCoreWindow->get_Bounds(&rect); ++ if (SUCCEEDED(result)) ++ { ++ LONG width = std::floor(rect.Width * mScaleFactor + 0.5); ++ LONG height = std::floor(rect.Height * mScaleFactor + 0.5); ++ mClientRect = { 0, 0, width, height }; ++ } } } --#if !ANGLE_SKIP_DXGI_1_2_CHECK -+#if !ANGLE_SKIP_DXGI_1_2_CHECK && !defined(ANGLE_PLATFORM_WINRT) - // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. - // The easiest way to check is to query for a IDXGIDevice2. - bool requireDXGI1_2 = false; -@@ -237,8 +240,12 @@ EGLint Renderer11::initialize() - } - #endif +@@ -76,12 +110,8 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet -+#if !defined(ANGLE_PLATFORM_WINRT) - IDXGIDevice *dxgiDevice = NULL; -- result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); -+#else -+ IDXGIDevice1 *dxgiDevice = NULL; -+#endif -+ result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); - - if (FAILED(result)) - { -@@ -408,7 +415,7 @@ void Renderer11::sync(bool block) - } - } - --SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) -+SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) + bool CoreWindowNativeWindow::registerForSizeChangeEvents() { - return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); +- ComPtr sizeChangedHandler; +- HRESULT result = Microsoft::WRL::MakeAndInitialize(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this()); +- if (SUCCEEDED(result)) +- { +- result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken); +- } ++ HRESULT result = mCoreWindow->add_SizeChanged(Callback(this, &CoreWindowNativeWindow::onSizeChanged).Get(), ++ &mSizeChangedEventToken); + + if (SUCCEEDED(result)) + { +@@ -126,7 +156,7 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor + if (SUCCEEDED(result)) + { + +-#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) ++#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected + // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On + // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed + // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations. +@@ -152,36 +182,19 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor + return result; } + +-HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, RECT *windowSize) ++// Basically, this shouldn't be used on Phone ++HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e) + { +- ABI::Windows::Foundation::Rect bounds; +- HRESULT result = coreWindow->get_Bounds(&bounds); +- if (SUCCEEDED(result)) ++ ABI::Windows::Foundation::Size size; ++ if (SUCCEEDED(e->get_Size(&size))) + { +- *windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) }; ++ SIZE windowSizeInPixels = { ++ std::floor(size.Width * mScaleFactor + 0.5), ++ std::floor(size.Height * mScaleFactor + 0.5) ++ }; ++ setNewClientSize(windowSizeInPixels); + } + +- return result; +-} +- +-static float GetLogicalDpi() +-{ +- ComPtr displayProperties; +- float dpi = 96.0f; +- +- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf()))) +- { +- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi))) +- { +- return dpi; +- } +- } +- return dpi; +-} +- +-long ConvertDipsToPixels(float dips) +-{ +- static const float dipsPerInch = 96.0f; +- return lround((dips * GetLogicalDpi() / dipsPerInch)); ++ return S_OK; + } + } +diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h +index 0c6222d..1c55124 100644 +--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h ++++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h +@@ -11,67 +11,29 @@ + + #include "common/winrt/InspectableNativeWindow.h" + #include +- +-typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler; ++#include + + namespace rx + { +-long ConvertDipsToPixels(float dips); + + class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this + { + public: + ~CoreWindowNativeWindow(); + +- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet); ++ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet); + bool registerForSizeChangeEvents(); + void unregisterForSizeChangeEvents(); + HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain); + + private: ++ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); ++ + ComPtr mCoreWindow; ++ ComPtr mDisplayInformation; + ComPtr> mPropertyMap; + }; + +-[uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)] +-class CoreWindowSizeChangedHandler : +- public Microsoft::WRL::RuntimeClass, IWindowSizeChangedEventHandler> +-{ +- public: +- CoreWindowSizeChangedHandler() { } +- HRESULT RuntimeClassInitialize(std::shared_ptr host) +- { +- if (!host) +- { +- return E_INVALIDARG; +- } +- +- mHost = host; +- return S_OK; +- } +- +- // IWindowSizeChangedEventHandler +- IFACEMETHOD(Invoke)(ABI::Windows::UI::Core::ICoreWindow *sender, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *sizeChangedEventArgs) +- { +- std::shared_ptr host = mHost.lock(); +- if (host) +- { +- ABI::Windows::Foundation::Size windowSize; +- if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize))) +- { +- SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) }; +- host->setNewClientSize(windowSizeInPixels); +- } +- } +- +- return S_OK; +- } +- +- private: +- std::weak_ptr mHost; +-}; +- +-HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, RECT *windowSize); + } + + #endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_ +diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp +index c062a48..0589f6d 100644 +--- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp ++++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp +@@ -11,9 +11,9 @@ + + namespace rx + { +-NativeWindow::NativeWindow(EGLNativeWindowType window) ++NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) ++ : mWindow(window), mDisplay(display) + { +- mWindow = window; + } + + bool NativeWindow::initialize() +@@ -40,7 +40,7 @@ bool NativeWindow::initialize() + mImpl = std::make_shared(); + if (mImpl) + { +- return mImpl->initialize(mWindow, propertySet.Get()); ++ return mImpl->initialize(mWindow, mDisplay, propertySet.Get()); + } + } + else if (IsSwapChainPanel(mWindow, &swapChainPanel)) +@@ -48,7 +48,7 @@ bool NativeWindow::initialize() + mImpl = std::make_shared(); + if (mImpl) + { +- return mImpl->initialize(mWindow, propertySet.Get()); ++ return mImpl->initialize(mWindow, mDisplay, propertySet.Get()); + } + } + else +diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h +index c625348..402941a 100644 +--- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h ++++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h +@@ -32,13 +32,14 @@ class InspectableNativeWindow + mRequiresSwapChainScaling(false), + mClientRectChanged(false), + mClientRect({0,0,0,0}), +- mNewClientRect({0,0,0,0}) ++ mNewClientRect({0,0,0,0}), ++ mScaleFactor(1.0) + { + mSizeChangedEventToken.value = 0; + } + virtual ~InspectableNativeWindow(){} + +- virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0; ++ virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0; + virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0; + virtual bool registerForSizeChangeEvents() = 0; + virtual void unregisterForSizeChangeEvents() = 0; +@@ -49,6 +50,7 @@ class InspectableNativeWindow + if (mClientRectChanged && mSupportsSwapChainResize) + { + mClientRect = mNewClientRect; ++ mClientRectChanged = false; + } + + *rect = mClientRect; +@@ -76,6 +78,7 @@ protected: + RECT mClientRect; + RECT mNewClientRect; + bool mClientRectChanged; ++ DOUBLE mScaleFactor; + + EventRegistrationToken mSizeChangedEventToken; + }; +diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp +index 4e4fb6d..268dfbd 100644 +--- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp ++++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp +@@ -18,7 +18,7 @@ SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow() + unregisterForSizeChangeEvents(); + } + +-bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet) ++bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) + { + ComPtr props = propertySet; + ComPtr win = window; +diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h +index e88f554..5bbf274 100644 +--- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h ++++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h +@@ -18,7 +18,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e + public: + ~SwapChainPanelNativeWindow(); + +- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet); ++ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet); + bool registerForSizeChangeEvents(); + void unregisterForSizeChangeEvents(); + HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain); +diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h +index 378323a..b3ffcc8 100644 +--- a/src/3rdparty/angle/src/libEGL/Display.h ++++ b/src/3rdparty/angle/src/libEGL/Display.h +@@ -67,6 +67,7 @@ class Display + + const char *getExtensionString() const; + const char *getVendorString() const; ++ EGLNativeDisplayType getDisplayId() const { return mDisplayId; } + + private: + DISALLOW_COPY_AND_ASSIGN(Display); +diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp +index 3414656..b664a85 100644 +--- a/src/3rdparty/angle/src/libEGL/Surface.cpp ++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp +@@ -31,7 +31,7 @@ namespace egl + { + + Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported) +- : mDisplay(display), mConfig(config), mNativeWindow(window), mPostSubBufferSupported(postSubBufferSupported) ++ : mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported) + { + //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues) + mRenderer = static_cast(mDisplay->getRenderer()); +@@ -47,6 +47,8 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win + mSwapInterval = -1; + mWidth = width; + mHeight = height; ++ mFixedWidth = mWidth; ++ mFixedHeight = mHeight; + setSwapInterval(1); + mFixedSize = fixedSize; + +@@ -54,7 +56,7 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win + } + + Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType) +- : mDisplay(display), mNativeWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) ++ : mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) + { + //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues) + mRenderer = static_cast(mDisplay->getRenderer()); +@@ -71,6 +73,8 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL + setSwapInterval(1); + // This constructor is for offscreen surfaces, which are always fixed-size. + mFixedSize = EGL_TRUE; ++ mFixedWidth = mWidth; ++ mFixedHeight = mHeight; + } + + Surface::~Surface() +@@ -157,10 +161,13 @@ Error Surface::resetSwapChain() + + Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight) + { +- ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); + ASSERT(mSwapChain); + +- EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight)); ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) ++ backbufferWidth = std::max(1, backbufferWidth); ++ backbufferHeight = std::max(1, backbufferHeight); ++#endif ++ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight); + + if (status == EGL_CONTEXT_LOST) + { +@@ -209,14 +216,14 @@ Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + return Error(EGL_SUCCESS); + } + +- if (x + width > mWidth) ++ if (x + width > abs(mWidth)) + { +- width = mWidth - x; ++ width = abs(mWidth) - x; + } + +- if (y + height > mHeight) ++ if (y + height > abs(mHeight)) + { +- height = mHeight - y; ++ height = abs(mHeight) - y; + } + + if (width == 0 || height == 0) +@@ -224,6 +231,9 @@ Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + return Error(EGL_SUCCESS); + } + ++ ASSERT(width > 0); ++ ASSERT(height > 0); ++ + EGLint status = mSwapChain->swapRect(x, y, width, height); + + if (status == EGL_CONTEXT_LOST) +@@ -352,6 +362,13 @@ bool Surface::checkForOutOfDateSwapChain() + sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); + } + ++ if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight)) ++ { ++ clientWidth = mFixedWidth; ++ clientHeight = mFixedHeight; ++ sizeDirty = true; ++ } ++ + bool wasDirty = (mSwapIntervalDirty || sizeDirty); + + if (mSwapIntervalDirty) +@@ -378,7 +395,7 @@ bool Surface::checkForOutOfDateSwapChain() + + Error Surface::swap() + { +- return swapRect(0, 0, mWidth, mHeight); ++ return swapRect(0, 0, abs(mWidth), abs(mHeight)); + } + + Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +@@ -471,6 +488,16 @@ EGLint Surface::isFixedSize() const + return mFixedSize; + } + ++void Surface::setFixedWidth(EGLint width) ++{ ++ mFixedWidth = width; ++} ++ ++void Surface::setFixedHeight(EGLint height) ++{ ++ mFixedHeight = height; ++} ++ + EGLenum Surface::getFormat() const + { + return mConfig->mRenderTargetFormat; +diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h +index 662fe21..46382d0 100644 +--- a/src/3rdparty/angle/src/libEGL/Surface.h ++++ b/src/3rdparty/angle/src/libEGL/Surface.h +@@ -70,6 +70,8 @@ class Surface + virtual gl::Texture2D *getBoundTexture() const; + + EGLint isFixedSize() const; ++ void setFixedWidth(EGLint width); ++ void setFixedHeight(EGLint height); + + private: + DISALLOW_COPY_AND_ASSIGN(Surface); +@@ -91,6 +93,8 @@ class Surface + const egl::Config *mConfig; // EGL config surface was created with + EGLint mHeight; // Height of surface + EGLint mWidth; // Width of surface ++ EGLint mFixedHeight; // Pending height of the surface ++ EGLint mFixedWidth; // Pending width of the surface + // EGLint horizontalResolution; // Horizontal dot pitch + // EGLint verticalResolution; // Vertical dot pitch + // EGLBoolean largestPBuffer; // If true, create largest pbuffer possible +diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp +index 6110698..dc20d85 100644 +--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp ++++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp +@@ -706,6 +706,26 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint + return EGL_FALSE; + } + ++ switch (attribute) ++ { ++ case EGL_WIDTH: ++ if (!eglSurface->isFixedSize() || !value) { ++ recordError(egl::Error(EGL_BAD_PARAMETER)); ++ return EGL_FALSE; ++ } ++ eglSurface->setFixedWidth(value); ++ return EGL_TRUE; ++ case EGL_HEIGHT: ++ if (!eglSurface->isFixedSize() || !value) { ++ recordError(egl::Error(EGL_BAD_PARAMETER)); ++ return EGL_FALSE; ++ } ++ eglSurface->setFixedHeight(value); ++ return EGL_TRUE; ++ default: ++ break; ++ } ++ + UNIMPLEMENTED(); // FIXME + + recordError(egl::Error(EGL_SUCCESS)); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h -index d309f14..b86f5e5 100644 +index 1655f1d..c789cae 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h -@@ -57,7 +57,7 @@ class Renderer11 : public Renderer - - virtual void sync(bool block); - -- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); -+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); - - virtual gl::Error generateSwizzle(gl::Texture *texture); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); -@@ -222,7 +222,7 @@ class Renderer11 : public Renderer +@@ -231,7 +231,7 @@ class Renderer11 : public RendererD3D HMODULE mD3d11Module; HMODULE mDxgiModule; - HDC mDc; + EGLNativeDisplayType mDc; - EGLint mRequestedDisplay; + std::vector mAvailableFeatureLevels; + D3D_DRIVER_TYPE mDriverType; - HLSLCompiler mCompiler; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp -index 50dae4e..787c511 100644 +index 834b7bd..52c8a81 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp -@@ -6,6 +6,7 @@ - - // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. - -+#include "common/platform.h" - #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" - #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" - #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" -@@ -18,7 +19,7 @@ - namespace rx - { - --SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, -+SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) - { -@@ -38,6 +39,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, +@@ -42,6 +42,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE mPassThroughPS = NULL; mWidth = -1; mHeight = -1; -+ mViewportWidth = -1; -+ mViewportHeight = -1; ++ mRotateL = false; ++ mRotateR = false; mSwapInterval = 0; mAppCreatedShareHandle = mShareHandle != NULL; mPassThroughResourcesInit = false; -@@ -92,6 +95,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei - ASSERT(backbufferHeight >= 1); +@@ -92,10 +94,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei + ASSERT(device != NULL); + + // D3D11 does not allow zero size textures +- ASSERT(backbufferWidth >= 1); +- ASSERT(backbufferHeight >= 1); ++ ASSERT(backbufferWidth != 0); ++ ASSERT(backbufferHeight != 0); // Preserve the render target content -+#if !defined(ANGLE_PLATFORM_WINRT) ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { -@@ -99,6 +103,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei +@@ -103,6 +106,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } const int previousWidth = mWidth; const int previousHeight = mHeight; @@ -1128,112 +675,107 @@ index 50dae4e..787c511 100644 releaseOffscreenTexture(); -@@ -281,7 +286,12 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei +@@ -136,8 +140,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; + mOffscreenTexture->GetDesc(&offscreenTextureDesc); +- if (offscreenTextureDesc.Width != (UINT)backbufferWidth || +- offscreenTextureDesc.Height != (UINT)backbufferHeight || ++ if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) || ++ offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) || + offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || + offscreenTextureDesc.MipLevels != 1 || + offscreenTextureDesc.ArraySize != 1) +@@ -152,8 +156,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei + const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport(); + + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; +- offscreenTextureDesc.Width = backbufferWidth; +- offscreenTextureDesc.Height = backbufferHeight; ++ offscreenTextureDesc.Width = abs(backbufferWidth); ++ offscreenTextureDesc.Height = abs(backbufferHeight); + offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; + offscreenTextureDesc.MipLevels = 1; + offscreenTextureDesc.ArraySize = 1; +@@ -233,8 +237,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei + if (mDepthBufferFormat != GL_NONE) + { + D3D11_TEXTURE2D_DESC depthStencilTextureDesc; +- depthStencilTextureDesc.Width = backbufferWidth; +- depthStencilTextureDesc.Height = backbufferHeight; ++ depthStencilTextureDesc.Width = abs(backbufferWidth); ++ depthStencilTextureDesc.Height = abs(backbufferHeight); + depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; + depthStencilTextureDesc.MipLevels = 1; + depthStencilTextureDesc.ArraySize = 1; +@@ -286,6 +290,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei mWidth = backbufferWidth; mHeight = backbufferHeight; -+#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP -+ mViewportWidth = backbufferWidth; -+ mViewportHeight = backbufferHeight; -+#endif -+#if !defined(ANGLE_PLATFORM_WINRT) ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) if (previousOffscreenTexture != NULL) { D3D11_BOX sourceBox = {0}; -@@ -300,9 +310,10 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei - - if (mSwapChain) - { -- swapRect(0, 0, mWidth, mHeight); -+ swapRect(0, 0, mWidth, mHeight, SWAP_NORMAL); +@@ -307,6 +312,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei + swapRect(0, 0, mWidth, mHeight); } } +#endif return EGL_SUCCESS; } -@@ -329,8 +340,15 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) +@@ -320,8 +326,16 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) + return EGL_BAD_ACCESS; + } + ++ // Windows Phone works around the rotation limitation by using negative values for the swap chain size ++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) ++ mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape ++ mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape ++ backbufferWidth = abs(backbufferWidth); ++ backbufferHeight = abs(backbufferHeight); ++#endif ++ + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains +- if (backbufferWidth < 1 || backbufferHeight < 1) ++ if (backbufferWidth == 0 || backbufferHeight == 0) + { + return EGL_SUCCESS; + } +@@ -329,6 +343,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) + // Can only call resize if we have already created our swap buffer and resources + ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView); + ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone + SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); - // Resize swap chain -+ HRESULT result; -+#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP // Windows phone swap chain is never resized, only the texture is -+#if !defined(ANGLE_PLATFORM_WINRT) -+ const int bufferCount = 1; -+#else -+ const int bufferCount = 2; -+#endif - const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); -- HRESULT result = mSwapChain->ResizeBuffers(1, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); -+ result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); - - if (FAILED(result)) +@@ -366,6 +381,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) { -@@ -346,6 +364,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) - return EGL_BAD_ALLOC; - } + d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); } +#endif - result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); - ASSERT(SUCCEEDED(result)); -@@ -399,6 +418,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap - - IDXGIFactory *factory = mRenderer->getDxgiFactory(); - -+#if !defined(ANGLE_PLATFORM_WINRT) - DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; - swapChainDesc.BufferDesc.Width = backbufferWidth; - swapChainDesc.BufferDesc.Height = backbufferHeight; -@@ -417,7 +437,37 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap - swapChainDesc.Flags = 0; - - HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain); -+#else -+ IDXGIFactory2 *factory2; -+ HRESULT result = factory->QueryInterface(IID_PPV_ARGS(&factory2)); -+ ASSERT(SUCCEEDED(result)); -+ -+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; -+ swapChainDesc.Width = 0; -+ swapChainDesc.Height = 0; -+ swapChainDesc.Format = backbufferFormatInfo.texFormat; -+ swapChainDesc.SampleDesc.Count = 1; -+ swapChainDesc.SampleDesc.Quality = 0; -+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; -+ swapChainDesc.Stereo = FALSE; -+ swapChainDesc.Flags = 0; -+#if WINAPI_FAMILY==WINAPI_FAMILY_PC_APP -+ swapChainDesc.Scaling = DXGI_SCALING_NONE; -+ swapChainDesc.BufferCount = 2; -+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; -+#elif WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -+ swapChainDesc.BufferCount = 1; -+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; -+#endif - -+ IDXGISwapChain1 *swapChain; -+ result = factory2->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain); -+ mSwapChain = swapChain; -+ HRESULT hr = swapChain->GetDesc1(&swapChainDesc); -+ ASSERT(SUCCEEDED(hr)); -+ mViewportWidth = swapChainDesc.Width; -+ mViewportHeight = swapChainDesc.Height; -+#endif - if (FAILED(result)) - { - ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); -@@ -513,7 +563,7 @@ void SwapChain11::initPassThroughResources() + return resetOffscreenTexture(backbufferWidth, backbufferHeight); } +@@ -512,16 +528,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - // parameters should be validated/clamped by caller --EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) -+EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) - { - if (!mSwapChain) - { -@@ -544,10 +594,13 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +- // Set vertices +- D3D11_MAPPED_SUBRESOURCE mappedResource; +- HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); +- if (FAILED(result)) +- { +- return EGL_BAD_ACCESS; +- } +- +- d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); +- + // Create a quad in homogeneous coordinates + float x1 = (x / float(mWidth)) * 2.0f - 1.0f; + float y1 = (y / float(mHeight)) * 2.0f - 1.0f; +@@ -533,10 +539,23 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) float u2 = (x + width) / float(mWidth); float v2 = (y + height) / float(mHeight); @@ -1241,8 +783,18 @@ index 50dae4e..787c511 100644 - d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); -+ const int rotateL = flags & SWAP_ROTATE_90; -+ const int rotateR = flags & SWAP_ROTATE_270; ++ const bool rotateL = mRotateL; ++ const bool rotateR = mRotateR; ++ ++ // Set vertices ++ D3D11_MAPPED_SUBRESOURCE mappedResource; ++ HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); ++ if (FAILED(result)) ++ { ++ return EGL_BAD_ACCESS; ++ } ++ ++ d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); + + d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1); + d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2); @@ -1251,72 +803,35 @@ index 50dae4e..787c511 100644 deviceContext->Unmap(mQuadVB, 0); -@@ -577,8 +630,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +@@ -564,10 +583,11 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + + // Set the viewport D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; +- viewport.TopLeftX = 0; +- viewport.TopLeftY = 0; - viewport.Width = mWidth; - viewport.Height = mHeight; -+ viewport.Width = mViewportWidth; -+ viewport.Height = mViewportHeight; ++ viewport.TopLeftX = 0.0f; ++ viewport.TopLeftY = 0.0f; ++ const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR); ++ viewport.Width = FLOAT(invertViewport ? mHeight : mWidth); ++ viewport.Height = FLOAT(invertViewport ? mWidth : mHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h -index fb0afd7..b30b785 100644 +index 22401d8..77509ed 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h -@@ -19,13 +19,13 @@ class Renderer11; - class SwapChain11 : public SwapChain - { - public: -- SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, -+ SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat); - virtual ~SwapChain11(); - - EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); -- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); -+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags); - virtual void recreate(); - - virtual ID3D11Texture2D *getOffscreenTexture(); @@ -52,6 +52,8 @@ class SwapChain11 : public SwapChain Renderer11 *mRenderer; EGLint mHeight; EGLint mWidth; -+ EGLint mViewportWidth; -+ EGLint mViewportHeight; ++ bool mRotateL; ++ bool mRotateR; bool mAppCreatedShareHandle; unsigned int mSwapInterval; bool mPassThroughResourcesInit; -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp -index f702b79..0aeaabb 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp -@@ -238,7 +238,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI - } - - // parameters should be validated/clamped by caller --EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) -+EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint) - { - if (!mSwapChain) - { -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h -index 16a62bd..4d756f8 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h -@@ -25,7 +25,7 @@ class SwapChain9 : public SwapChain - - EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); -- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); -+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint); - virtual void recreate(); - - virtual IDirect3DSurface9 *getRenderTarget(); -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch b/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch index 297d5adc84..dd2768cf3e 100644 --- a/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch +++ b/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch @@ -1,6 +1,6 @@ -From 0e8aa60332e17f284804dc1b89a9db5795a92ecb Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Wed, 17 Sep 2014 21:17:39 +0300 +From 829bf86c57357d3c8ec598b92fcfdb1849e84075 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Tue, 11 Nov 2014 17:11:54 +0200 Subject: [PATCH 10/16] ANGLE: Enable D3D11 for feature level 9 cards Enable use of ANGLE on lower-end hardware, such as Surface RT and @@ -8,23 +8,32 @@ Windows Phone 8. Change-Id: Ice536802e4eedc1d264abd0dd65960638fce59e4 --- - src/3rdparty/angle/src/libGLESv2/angletypes.cpp | 4 +- - .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 73 +++---- + src/3rdparty/angle/src/libGLESv2/angletypes.cpp | 6 +- + .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 69 ++++--- .../src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp | 4 +- - .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 8 +- - .../renderer/d3d/d3d11/PixelTransfer11.cpp | 7 +- - .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 209 +++++++++++++-------- + .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 7 +- + .../renderer/d3d/d3d11/PixelTransfer11.cpp | 9 +- + .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 226 +++++++++++++-------- .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 1 + - .../renderer/d3d/d3d11/TextureStorage11.cpp | 2 +- + .../renderer/d3d/d3d11/TextureStorage11.cpp | 4 +- .../libGLESv2/renderer/d3d/d3d11/formatutils11.cpp | 4 +- .../renderer/d3d/d3d11/renderer11_utils.cpp | 2 +- - 10 files changed, 190 insertions(+), 124 deletions(-) + 10 files changed, 208 insertions(+), 124 deletions(-) diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp -index 06618d5..bb6425d 100644 +index 6fd02e0..5a0cfc5 100644 --- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp +++ b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp -@@ -22,8 +22,8 @@ SamplerState::SamplerState() +@@ -12,6 +12,8 @@ + #include "libGLESv2/State.h" + #include "libGLESv2/VertexArray.h" + ++#include ++ + namespace gl + { + +@@ -24,8 +26,8 @@ SamplerState::SamplerState() maxAnisotropy(1.0f), baseLevel(0), maxLevel(1000), @@ -36,28 +45,28 @@ index 06618d5..bb6425d 100644 compareFunc(GL_LEQUAL), swizzleRed(GL_RED), diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp -index 72820a4..d43e65e 100644 +index 91e7552..06aea9b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp -@@ -209,7 +209,7 @@ Blit11::Blit11(rx::Renderer11 *renderer) +@@ -209,7 +209,7 @@ Blit11::Blit11(Renderer11 *renderer) pointSamplerDesc.BorderColor[2] = 0.0f; pointSamplerDesc.BorderColor[3] = 0.0f; pointSamplerDesc.MinLOD = 0.0f; - pointSamplerDesc.MaxLOD = 0.0f; -+ pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f; ++ pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f; result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler); ASSERT(SUCCEEDED(result)); -@@ -228,7 +228,7 @@ Blit11::Blit11(rx::Renderer11 *renderer) +@@ -228,7 +228,7 @@ Blit11::Blit11(Renderer11 *renderer) linearSamplerDesc.BorderColor[2] = 0.0f; linearSamplerDesc.BorderColor[3] = 0.0f; linearSamplerDesc.MinLOD = 0.0f; - linearSamplerDesc.MaxLOD = 0.0f; -+ linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f; ++ linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f; result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler); ASSERT(SUCCEEDED(result)); -@@ -290,28 +290,31 @@ Blit11::Blit11(rx::Renderer11 *renderer) +@@ -290,28 +290,31 @@ Blit11::Blit11(Renderer11 *renderer) ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader"); @@ -76,14 +85,14 @@ index 72820a4..d43e65e 100644 - result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout"); +- +- result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS); +- ASSERT(SUCCEEDED(result)); +- d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader"); + result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader"); -- result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS); -- ASSERT(SUCCEEDED(result)); -- d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader"); -- - result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader"); @@ -109,7 +118,7 @@ index 72820a4..d43e65e 100644 buildShaderMap(); -@@ -972,40 +975,44 @@ void Blit11::buildShaderMap() +@@ -970,22 +973,27 @@ void Blit11::buildShaderMap() ID3D11Device *device = mRenderer->getDevice(); add2DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader" )); @@ -145,19 +154,7 @@ index 72820a4..d43e65e 100644 add3DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" )); add3DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader" )); add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" )); - add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" )); - add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" )); -+ add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" )); - add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" )); - add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" )); -- add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" )); -+ add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" )); - add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" )); - add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" )); -- add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" )); - add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" )); - add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" )); - add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" )); +@@ -1003,7 +1011,6 @@ void Blit11::buildShaderMap() add3DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" )); add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader")); @@ -166,22 +163,22 @@ index 72820a4..d43e65e 100644 addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader" )); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp -index 43ce5ba..ecd4d46 100644 +index 2d5fa3c..5aab379 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp -@@ -747,7 +747,9 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren +@@ -753,7 +753,9 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: bufferDesc->Usage = D3D11_USAGE_DEFAULT; - bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT; + bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER; -+ if (!static_cast(renderer)->isLevel9()) ++ if (!renderer->isLevel9()) + bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT; bufferDesc->CPUAccessFlags = 0; break; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp -index 5caa427..765d34f 100644 +index 4630762..7185a05 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp @@ -104,7 +104,7 @@ Clear11::Clear11(Renderer11 *renderer) @@ -189,11 +186,11 @@ index 5caa427..765d34f 100644 rsDesc.DepthBiasClamp = 0.0f; rsDesc.SlopeScaledDepthBias = 0.0f; - rsDesc.DepthClipEnable = FALSE; -+ rsDesc.DepthClipEnable = mRenderer->isLevel9(); ++ rsDesc.DepthClipEnable = renderer->isLevel9(); rsDesc.ScissorEnable = FALSE; rsDesc.MultisampleEnable = FALSE; rsDesc.AntialiasedLineEnable = FALSE; -@@ -114,6 +114,12 @@ Clear11::Clear11(Renderer11 *renderer) +@@ -114,6 +114,11 @@ Clear11::Clear11(Renderer11 *renderer) d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state"); mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat); @@ -202,53 +199,63 @@ index 5caa427..765d34f 100644 + memset(&mIntClearShader, 0, sizeof(ClearShader)); + return; + } -+ mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint ); mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint ); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp -index edaafec..a4e84f9 100644 +index a4072d8..6a3d347 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp -@@ -88,13 +88,16 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer) - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer"); +@@ -133,10 +133,13 @@ gl::Error PixelTransfer11::loadResources() + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader."); + } -+ StructZero(&mParamsData); -+ - // init shaders -+ if (mRenderer->isLevel9()) -+ return; -+ - mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS"); - mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); +- mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); +- if (!mBufferToTextureGS) ++ if (!mRenderer->isLevel9()) + { +- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader."); ++ mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); ++ if (!mBufferToTextureGS) ++ { ++ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader."); ++ } + } - buildShaderMap(); -- -- StructZero(&mParamsData); - } - - PixelTransfer11::~PixelTransfer11() + gl::Error error = buildShaderMap(); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -index 0bb7489..b4b26a8 100644 +index ffc6cc9..f6ba930 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -@@ -162,6 +162,11 @@ EGLint Renderer11::initialize() - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, -+#if !defined(ANGLE_ENABLE_D3D9) -+ D3D_FEATURE_LEVEL_9_3, -+ D3D_FEATURE_LEVEL_9_2, -+ D3D_FEATURE_LEVEL_9_1, -+#endif - }; +@@ -153,6 +153,24 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const eg + } + } - D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE; -@@ -1112,6 +1117,84 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons ++#if !defined(ANGLE_ENABLE_D3D9) ++ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9) ++ { ++ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3) ++ { ++ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3); ++ } ++ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2) ++ { ++ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2); ++ } ++ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) ++ { ++ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1); ++ } ++ } ++#endif ++ + mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP + : D3D_DRIVER_TYPE_HARDWARE; + } +@@ -1170,6 +1188,83 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons + return gl::Error(GL_NO_ERROR); } } - +template +static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data) +{ @@ -326,12 +333,11 @@ index 0bb7489..b4b26a8 100644 + default: UNREACHABLE(); + } +} -+ + gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) { - // Get the raw indices for an indexed draw -@@ -1123,10 +1206,13 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind - indices = static_cast(storage->getData()) + offset; +@@ -1189,10 +1284,13 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind + indices = bufferData + offset; } + // TODO: some level 9 hardware supports 32-bit indices; test and store support instead @@ -345,7 +351,7 @@ index 0bb7489..b4b26a8 100644 if (error.isError()) { SafeDelete(mLineLoopIB); -@@ -1137,7 +1223,8 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind +@@ -1203,7 +1301,8 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind // Checked by Renderer11::applyPrimitiveType ASSERT(count >= 0); @@ -355,7 +361,7 @@ index 0bb7489..b4b26a8 100644 { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); } -@@ -1157,42 +1244,12 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind +@@ -1223,42 +1322,12 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind return error; } @@ -402,8 +408,8 @@ index 0bb7489..b4b26a8 100644 error = mLineLoopIB->unmapBuffer(); if (error.isError()) { -@@ -1227,10 +1284,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * - indices = static_cast(storage->getData()) + offset; +@@ -1300,10 +1369,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * + indices = bufferData + offset; } + const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; @@ -416,7 +422,7 @@ index 0bb7489..b4b26a8 100644 if (error.isError()) { SafeDelete(mTriangleFanIB); -@@ -1243,13 +1302,14 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * +@@ -1316,13 +1387,14 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * const unsigned int numTris = count - 2; @@ -434,7 +440,7 @@ index 0bb7489..b4b26a8 100644 if (error.isError()) { return error; -@@ -1263,45 +1323,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * +@@ -1336,45 +1408,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * return error; } @@ -485,7 +491,7 @@ index 0bb7489..b4b26a8 100644 error = mTriangleFanIB->unmapBuffer(); if (error.isError()) -@@ -1549,7 +1576,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) +@@ -1634,7 +1673,7 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto } // needed for the point sprite geometry shader @@ -494,19 +500,7 @@ index 0bb7489..b4b26a8 100644 { mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; -@@ -1711,6 +1738,11 @@ bool Renderer11::testDeviceResettable() - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, -+#if !defined(ANGLE_ENABLE_D3D9) -+ D3D_FEATURE_LEVEL_9_3, -+ D3D_FEATURE_LEVEL_9_2, -+ D3D_FEATURE_LEVEL_9_1, -+#endif - }; - - ID3D11Device* dummyDevice; -@@ -1862,7 +1894,10 @@ int Renderer11::getMajorShaderModel() const +@@ -1938,7 +1977,10 @@ int Renderer11::getMajorShaderModel() const { case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4 @@ -518,7 +512,7 @@ index 0bb7489..b4b26a8 100644 default: UNREACHABLE(); return 0; } } -@@ -1873,7 +1908,10 @@ int Renderer11::getMinorShaderModel() const +@@ -1949,7 +1991,10 @@ int Renderer11::getMinorShaderModel() const { case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1 @@ -530,49 +524,81 @@ index 0bb7489..b4b26a8 100644 default: UNREACHABLE(); return 0; } } -@@ -2387,6 +2425,15 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch - case D3D_FEATURE_LEVEL_10_0: - profileVersion = "4_0"; +@@ -2455,6 +2500,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin + + unsigned int profileMajorVersion = 0; + unsigned int profileMinorVersion = 0; ++ const char *profileSuffix = NULL; + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: +@@ -2469,12 +2515,30 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin + profileMajorVersion = 4; + profileMinorVersion = 0; break; + case D3D_FEATURE_LEVEL_9_3: -+ profileVersion = "4_0_level_9_3"; ++ profileMajorVersion = 4; ++ profileMinorVersion = 0; ++ profileSuffix = "_level_9_3"; + break; + case D3D_FEATURE_LEVEL_9_2: -+ profileVersion = "4_0_level_9_2"; ++ profileMajorVersion = 4; ++ profileMinorVersion = 0; ++ profileSuffix = "_level_9_2"; + break; + case D3D_FEATURE_LEVEL_9_1: -+ profileVersion = "4_0_level_9_1"; ++ profileMajorVersion = 4; ++ profileMinorVersion = 0; ++ profileSuffix = "_level_9_1"; + break; ++ break; default: UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); + } + + std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); ++ if (profileSuffix) ++ profile += profileSuffix; + + UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2; + diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h -index b86f5e5..2a53fa1 100644 +index c789cae..d44bd2f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h -@@ -184,6 +184,7 @@ class Renderer11 : public Renderer +@@ -188,6 +188,7 @@ class Renderer11 : public RendererD3D ID3D11Device *getDevice() { return mDevice; } ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; - IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; + DXGIFactory *getDxgiFactory() { return mDxgiFactory; }; + bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; } Blit11 *getBlitter() { return mBlit; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp -index 3f0cd5b..91e7147 100644 +index 4287918..74af27e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp -@@ -472,7 +472,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform +@@ -744,7 +744,7 @@ gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource) D3D11_TEXTURE2D_DESC desc; - desc.Width = width; // Compressed texture size constraints? - desc.Height = height; -- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0); -+ desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0); + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; +- desc.MipLevels = mMipLevels; ++ desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels; desc.ArraySize = 1; desc.Format = mTextureFormat; desc.SampleDesc.Count = 1; +@@ -863,7 +863,7 @@ gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORM + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; +- srvDesc.Texture2D.MipLevels = mipLevels; ++ srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels; + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp -index 1ea916d..c078287 100644 +index 1ea916d..90a879e 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp @@ -557,7 +557,7 @@ D3D11LoadFunctionMap BuildD3D11LoadFunctionMap() @@ -589,15 +615,15 @@ index 1ea916d..c078287 100644 // From GL_EXT_texture_storage // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN ); -+ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); ++ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp -index b1867fb..06a22eb 100644 +index 9ffc32e..cbfe557 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp -@@ -283,7 +283,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) +@@ -284,7 +284,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_2: @@ -607,5 +633,5 @@ index b1867fb..06a22eb 100644 default: UNREACHABLE(); return false; } -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch b/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch index 35d525fb2d..afc9f256a1 100644 --- a/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch +++ b/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch @@ -1,6 +1,6 @@ -From 9e167b788cc9de1d963fd3fc2145848a6ccc0fa8 Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Mon, 22 Sep 2014 23:13:16 +0300 +From bbfd3cfcf6e1195d86368b61ce39504ce6acda50 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Wed, 12 Nov 2014 17:09:23 +0200 Subject: [PATCH 12/16] ANGLE: fix semantic index lookup The sorted semantic index table was returning a direct mapping to the @@ -14,10 +14,10 @@ Change-Id: I75d05ed707f56c45210e3dcbc277f894e3dc5a48 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp -index 1085346..3f6d9e0 100644 +index 0619023..6d64b38 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp -@@ -2788,7 +2788,7 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA +@@ -1216,7 +1216,7 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { int oldIndex = mAttributesByLayout[i]; @@ -27,10 +27,10 @@ index 1085346..3f6d9e0 100644 } } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp -index b006c04..d835e4f 100644 +index e41f238..ff90a6a 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp -@@ -112,10 +112,10 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl +@@ -113,10 +113,10 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl // Record the type of the associated vertex shader vector in our key // This will prevent mismatched vertex shaders from using the same input layout GLint attributeSize; @@ -44,5 +44,5 @@ index b006c04..d835e4f 100644 ilKey.elements[ilKey.elementCount].desc.InputSlot = i; ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch b/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch index 00e32186f0..b43dcc368b 100644 --- a/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch +++ b/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch @@ -1,6 +1,6 @@ -From 3499339ab768017458d3b5295af3742a0f6015db Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Mon, 22 Sep 2014 23:15:26 +0300 +From 5ef9348de2624c21be1c9fddd265fec5a0851d25 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Thu, 13 Nov 2014 15:34:26 +0200 Subject: [PATCH 13/16] ANGLE: Add support for querying platform device The EGL_EXT_device_base extension allows for querying the platform @@ -16,14 +16,14 @@ the IDXGIDevice3::Trim() calls required by the Windows Store. Change-Id: Ibdf228d81d6604e56db9dd8597d7cd2983ebc428 --- - src/3rdparty/angle/src/libEGL/libEGL.cpp | 47 +++++++++++++++++++++++++------- - 1 file changed, 37 insertions(+), 10 deletions(-) + src/3rdparty/angle/src/libEGL/libEGL.cpp | 50 +++++++++++++++++++++++++------- + 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp -index 7ea11c5..c2e0fd6 100644 +index dc20d85..68399d6 100644 --- a/src/3rdparty/angle/src/libEGL/libEGL.cpp +++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp -@@ -18,6 +18,9 @@ +@@ -17,6 +17,9 @@ #include "libGLESv2/Texture.h" #include "libGLESv2/main.h" #include "libGLESv2/renderer/SwapChain.h" @@ -33,7 +33,7 @@ index 7ea11c5..c2e0fd6 100644 #include "libEGL/main.h" #include "libEGL/Display.h" -@@ -484,24 +487,48 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf +@@ -582,25 +585,50 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf egl::Display *display = static_cast(dpy); egl::Surface *eglSurface = (egl::Surface*)surface; @@ -44,7 +44,8 @@ index 7ea11c5..c2e0fd6 100644 - - if (surface == EGL_NO_SURFACE) - { -- return egl::error(EGL_BAD_SURFACE, EGL_FALSE); +- recordError(egl::Error(EGL_BAD_SURFACE)); +- return EGL_FALSE; - } - switch (attribute) @@ -58,7 +59,8 @@ index 7ea11c5..c2e0fd6 100644 + + if (surface == EGL_NO_SURFACE) + { -+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE); ++ recordError(egl::Error(EGL_BAD_SURFACE)); ++ return EGL_FALSE; + } + rx::SwapChain *swapchain = eglSurface->getSwapChain(); @@ -82,7 +84,8 @@ index 7ea11c5..c2e0fd6 100644 + + if (renderer->getMajorShaderModel() < 4) + { -+ return egl::error(EGL_BAD_CONTEXT, EGL_FALSE); ++ recordError(egl::Error(EGL_BAD_CONTEXT)); ++ return EGL_FALSE; + } + + *value = static_cast(renderer)->getDevice(); @@ -90,8 +93,8 @@ index 7ea11c5..c2e0fd6 100644 + break; +#endif default: - return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); - } + recordError(egl::Error(EGL_BAD_ATTRIBUTE)); + return EGL_FALSE; -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch b/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch index b884f7b549..9ceb34d964 100644 --- a/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch +++ b/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch @@ -1,6 +1,6 @@ -From a3046fef7f754f06937161e779ce0a651e77317b Mon Sep 17 00:00:00 2001 +From 5b3bc73210ed1847d9bd7a94f06cc0d5de8e0b89 Mon Sep 17 00:00:00 2001 From: Michael Bruning -Date: Mon, 22 Sep 2014 23:23:40 +0300 +Date: Thu, 13 Nov 2014 15:40:10 +0200 Subject: [PATCH 14/16] Let ANGLE use multithreaded devices if necessary. This is needed to prevent lock-ups in application that use ANGLE from @@ -11,13 +11,13 @@ communicate this from the QtWebEngine module. Change-Id: Ibd5a5c75eb68af567d420d9a35efb3490c93b27c --- - src/3rdparty/angle/src/common/platform.h | 1 + - .../angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 13 +++++++++++++ - .../angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 ++++ - 3 files changed, 18 insertions(+) + src/3rdparty/angle/src/common/platform.h | 1 + + .../angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 10 ++++++++++ + .../angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 ++++ + 3 files changed, 15 insertions(+) diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h -index 387ba41..7d0d957 100644 +index 0065ec7..8b2190d 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h @@ -57,6 +57,7 @@ @@ -26,17 +26,16 @@ index 387ba41..7d0d957 100644 # include +# include # include + # include # include - # include diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -index b4b26a8..bd07ee1 100644 +index f6ba930..46b9984 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -@@ -301,6 +301,19 @@ EGLint Renderer11::initialize() +@@ -258,6 +258,16 @@ EGLint Renderer11::initialize() } - #endif -+#if !defined(ANGLE_PLATFORM_WINRT) + #if !defined(ANGLE_ENABLE_WINDOWS_STORE) + static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED"); + if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1")) + { @@ -47,16 +46,14 @@ index b4b26a8..bd07ee1 100644 + ASSERT(SUCCEEDED(result)); + multithread->Release(); + } -+#endif -+ - initializeDevice(); - - return EGL_SUCCESS; + #if !ANGLE_SKIP_DXGI_1_2_CHECK + // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. + // The easiest way to check is to query for a IDXGIDevice2. diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp -index e8564bd..1d52705 100644 +index 82963ec..4c552b2 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp -@@ -304,6 +304,10 @@ EGLint Renderer9::initialize() +@@ -299,6 +299,10 @@ EGLint Renderer9::initialize() D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES; @@ -68,5 +65,5 @@ index e8564bd..1d52705 100644 result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); } -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch b/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch index 7d914766a0..f78474f11a 100644 --- a/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch +++ b/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch @@ -1,23 +1,28 @@ -From 373b3f67352e9a6f599c6a9dd9aee3b4836e0a3f Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Mon, 22 Sep 2014 23:41:48 +0300 +From d9a9219ea2181dd4c1939d05747a21b67f16a906 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Thu, 13 Nov 2014 16:33:53 +0200 Subject: [PATCH 15/16] ANGLE: Fix -angle-d3d11 on MSVC2010 Allow the D3D11 renderer to build with the June 2010 DirectX SDK. Change-Id: I2343acedab16845d6a0d4a53cf3145f583efc4a7 --- - src/3rdparty/angle/src/common/platform.h | 6 ++ - .../renderer/d3d/d3d11/renderer11_utils.cpp | 89 ++++++++++++++++++++++ - 2 files changed, 95 insertions(+) + src/3rdparty/angle/src/common/platform.h | 8 +- + src/3rdparty/angle/src/libGLESv2/Context.cpp | 8 +- + src/3rdparty/angle/src/libGLESv2/Data.h | 2 +- + src/3rdparty/angle/src/libGLESv2/State.cpp | 6 +- + .../src/libGLESv2/renderer/d3d/RendererD3D.cpp | 4 +- + .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 4 +- + .../renderer/d3d/d3d11/renderer11_utils.cpp | 137 +++++++++++++++++++++ + 7 files changed, 156 insertions(+), 13 deletions(-) diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h -index 7d0d957..3c619f3 100644 +index 8b2190d..972eee2 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h -@@ -52,7 +52,9 @@ +@@ -52,17 +52,23 @@ - # if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF) + # if defined(ANGLE_ENABLE_D3D9) # include +# if !defined(COMPILER_IMPLEMENTATION) # include @@ -25,11 +30,13 @@ index 7d0d957..3c619f3 100644 # endif # if defined(ANGLE_ENABLE_D3D11) -@@ -60,8 +62,12 @@ + # include # include # include +-# include # include -+# if _MSC_VER >= 1700 ++# if defined(_MSC_VER) && (_MSC_VER >= 1700) ++# include # include +# endif +# if !defined(COMPILER_IMPLEMENTATION) @@ -37,12 +44,118 @@ index 7d0d957..3c619f3 100644 +# endif # endif - # undef near + # if defined(ANGLE_ENABLE_WINDOWS_STORE) +diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp +index fe9b1a2..b87689c 100644 +--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp +@@ -168,9 +168,9 @@ Context::~Context() + } + mIncompleteTextures.clear(); + +- for (auto &zeroTexture : mZeroTextures) ++ for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++) + { +- zeroTexture.second.set(NULL); ++ i->second.set(NULL); + } + mZeroTextures.clear(); + +@@ -354,7 +354,7 @@ void Context::deleteFenceSync(GLsync fenceSync) + + void Context::deleteVertexArray(GLuint vertexArray) + { +- auto vertexArrayObject = mVertexArrayMap.find(vertexArray); ++ VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray); + + if (vertexArrayObject != mVertexArrayMap.end()) + { +@@ -460,7 +460,7 @@ FenceSync *Context::getFenceSync(GLsync handle) const + + VertexArray *Context::getVertexArray(GLuint handle) const + { +- auto vertexArray = mVertexArrayMap.find(handle); ++ VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle); + + if (vertexArray == mVertexArrayMap.end()) + { +diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libGLESv2/Data.h +index cff872a..9234403 100644 +--- a/src/3rdparty/angle/src/libGLESv2/Data.h ++++ b/src/3rdparty/angle/src/libGLESv2/Data.h +@@ -14,7 +14,7 @@ + namespace gl + { + +-struct Data final ++struct Data + { + public: + Data(GLint clientVersion, const State &state, const Caps &caps, +diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp +index e7acda2..b5b62f5 100644 +--- a/src/3rdparty/angle/src/libGLESv2/State.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/State.cpp +@@ -665,13 +665,13 @@ void State::detachTexture(const TextureMap &zeroTextures, GLuint texture) + + void State::initializeZeroTextures(const TextureMap &zeroTextures) + { +- for (const auto &zeroTexture : zeroTextures) ++ for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++) + { +- auto &samplerTextureArray = mSamplerTextures[zeroTexture.first]; ++ TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first]; + + for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit) + { +- samplerTextureArray[textureUnit].set(zeroTexture.second.get()); ++ samplerTextureArray[textureUnit].set(i->second.get()); + } + } + } +diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp +index 6f58243..97da6da 100644 +--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp +@@ -27,9 +27,9 @@ RendererD3D::RendererD3D(egl::Display *display) + + RendererD3D::~RendererD3D() + { +- for (auto &incompleteTexture : mIncompleteTextures) ++ for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i) + { +- incompleteTexture.second.set(NULL); ++ i->second.set(NULL); + } + mIncompleteTextures.clear(); + } +diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +index 46b9984..a28fd78 100644 +--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +@@ -873,7 +873,7 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) + + void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource) + { +- auto ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); ++ std::vector ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex) + { +@@ -3398,7 +3398,7 @@ Workarounds Renderer11::generateWorkarounds() const + + void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv) + { +- auto ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); ++ std::vector ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + ASSERT(static_cast(resourceSlot) < currentSRVs.size()); + diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp -index 06a22eb..345fd24 100644 +index cbfe557..5831c57 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp -@@ -17,6 +17,37 @@ +@@ -18,6 +18,85 @@ #include @@ -76,300 +189,348 @@ index 06a22eb..345fd24 100644 +#ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION +# define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096 +#endif ++#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION ++# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384 ++#endif ++#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION ++# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048 ++#endif ++#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION ++# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048 ++#endif ++#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP ++# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 ++#endif ++#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP ++# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 ++#endif ++#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT ++# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32 ++#endif ++#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT ++# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32 ++#endif ++#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT ++# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 ++#endif ++#ifndef D3D11_SO_BUFFER_SLOT_COUNT ++# define D3D11_SO_BUFFER_SLOT_COUNT 4 ++#endif ++#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT ++# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 ++#endif ++#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT ++# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16 ++#endif ++#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE ++# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8 ++#endif ++#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE ++# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7 ++#endif ++#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT ++# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 ++#endif ++#ifndef D3D11_PS_INPUT_REGISTER_COUNT ++# define D3D11_PS_INPUT_REGISTER_COUNT 32 ++#endif ++#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT ++# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 ++#endif + namespace rx { -@@ -275,7 +306,9 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) +@@ -276,7 +355,9 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: return true; -@@ -293,7 +326,9 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) +@@ -294,7 +375,9 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY; case D3D_FEATURE_LEVEL_10_1: -@@ -313,7 +348,9 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) +@@ -314,7 +397,9 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: return true; -@@ -333,7 +370,9 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) +@@ -334,7 +419,9 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: -@@ -351,7 +390,9 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) +@@ -352,7 +439,9 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: -@@ -374,7 +415,9 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) +@@ -375,7 +464,9 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: -@@ -392,7 +435,9 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel +@@ -393,7 +484,9 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; case D3D_FEATURE_LEVEL_10_1: -@@ -410,7 +455,9 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) +@@ -411,7 +504,9 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; case D3D_FEATURE_LEVEL_10_1: -@@ -428,7 +475,9 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) +@@ -429,7 +524,9 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION; case D3D_FEATURE_LEVEL_10_1: -@@ -446,7 +495,9 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) +@@ -447,7 +544,9 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; case D3D_FEATURE_LEVEL_10_1: -@@ -464,7 +515,9 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) +@@ -465,7 +564,9 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; case D3D_FEATURE_LEVEL_10_1: -@@ -482,7 +535,9 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) +@@ -483,7 +584,9 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX; case D3D_FEATURE_LEVEL_10_1: -@@ -506,7 +561,9 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) +@@ -507,7 +610,9 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits::max(); -@@ -528,7 +585,9 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) +@@ -529,7 +634,9 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits::max(); -@@ -545,7 +604,9 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) +@@ -546,7 +653,9 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT; -@@ -565,7 +626,9 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) +@@ -566,7 +675,9 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; case D3D_FEATURE_LEVEL_10_1: -@@ -590,7 +653,9 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +@@ -591,7 +702,9 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); case D3D_FEATURE_LEVEL_10_1: -@@ -617,7 +682,9 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) +@@ -618,7 +731,9 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); -@@ -636,7 +703,9 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) +@@ -637,7 +752,9 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; case D3D_FEATURE_LEVEL_10_1: -@@ -658,7 +727,9 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) +@@ -659,7 +776,9 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; case D3D_FEATURE_LEVEL_10_1: -@@ -683,7 +754,9 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +@@ -684,7 +803,9 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); case D3D_FEATURE_LEVEL_10_1: -@@ -702,7 +775,9 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) +@@ -703,7 +824,9 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_1: -@@ -721,7 +796,9 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) +@@ -722,7 +845,9 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; case D3D_FEATURE_LEVEL_10_1: -@@ -740,7 +817,9 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +@@ -741,7 +866,9 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; case D3D_FEATURE_LEVEL_10_1: -@@ -759,7 +838,9 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +@@ -760,7 +887,9 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; -@@ -782,7 +863,9 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) +@@ -783,7 +912,9 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; case D3D_FEATURE_LEVEL_10_1: -@@ -801,7 +884,9 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) +@@ -802,7 +933,9 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT; case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT; -@@ -819,7 +904,9 @@ static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL fea +@@ -820,7 +953,9 @@ static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL feat { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif case D3D_FEATURE_LEVEL_11_0: case D3D_FEATURE_LEVEL_10_1: -@@ -837,7 +924,9 @@ static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featur +@@ -838,7 +973,9 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature { switch (featureLevel) { -+#if _MSC_VER >= 1700 ++#if !defined(_MSC_VER) || (_MSC_VER >= 1800) case D3D_FEATURE_LEVEL_11_1: +#endif - case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) / + case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) / GetMaximumStreamOutputBuffers(featureLevel); -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch b/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch index 2ea528018d..e3df95d8bf 100644 --- a/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch +++ b/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch @@ -1,35 +1,29 @@ -From 75c39e9020f062d155097f6b49aebbc12970b1e8 Mon Sep 17 00:00:00 2001 -From: Andrew Knight -Date: Tue, 23 Sep 2014 23:39:14 +0300 +From 43c8ceb17ccd6d5ae13a07c6d01b45eb40983917 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Tue, 11 Nov 2014 14:36:43 +0200 Subject: [PATCH 16/16] ANGLE: Fix compilation with MinGW + D3D11 -Provide workarounds for things GCC doesn't like, and define a number -of macros not found in the MinGW headers. +Provide workarounds for things GCC doesn't like, and define a few +missing definitions not found in the MinGW headers. Change-Id: I254c208209c0071fae5efb6727f2b3cfd5542da6 --- - src/3rdparty/angle/src/common/platform.h | 11 +++++ - src/3rdparty/angle/src/libEGL/Display.cpp | 1 + - src/3rdparty/angle/src/libGLESv2/Context.cpp | 5 +- - src/3rdparty/angle/src/libGLESv2/angletypes.h | 1 + - .../angle/src/libGLESv2/renderer/copyimage.inl | 2 +- - .../src/libGLESv2/renderer/d3d/TextureD3D.cpp | 4 +- + src/3rdparty/angle/src/common/platform.h | 73 ++++++++++++++++++++++ + .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 6 ++ .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 2 +- - .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 2 +- - .../renderer/d3d/d3d11/renderer11_utils.cpp | 53 +++++++++++++++++++++- + .../renderer/d3d/d3d11/renderer11_utils.cpp | 2 +- .../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 +- - src/3rdparty/angle/src/libGLESv2/validationES.cpp | 2 +- - 11 files changed, 76 insertions(+), 11 deletions(-) + 5 files changed, 83 insertions(+), 4 deletions(-) diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h -index 3c619f3..b53394f 100644 +index 972eee2..0001e71 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h -@@ -68,6 +68,17 @@ - # if !defined(COMPILER_IMPLEMENTATION) - # include - # endif -+# if defined(__MINGW32__) +@@ -81,6 +81,79 @@ + # endif + # endif + ++# if defined(__MINGW32__) // Missing defines on MinGW +typedef enum D3D11_MAP_FLAG +{ + D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L @@ -39,202 +33,121 @@ index 3c619f3..b53394f 100644 + UINT64 NumPrimitivesWritten; + UINT64 PrimitivesStorageNeeded; +} D3D11_QUERY_DATA_SO_STATISTICS; -+# endif - # endif - ++typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)( ++ IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *, ++ UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **); ++#define D3D11_MESSAGE_CATEGORY UINT ++#define D3D11_MESSAGE_SEVERITY UINT ++#define D3D11_MESSAGE_ID UINT ++struct D3D11_MESSAGE; ++typedef struct D3D11_INFO_QUEUE_FILTER_DESC ++{ ++ UINT NumCategories; ++ D3D11_MESSAGE_CATEGORY *pCategoryList; ++ UINT NumSeverities; ++ D3D11_MESSAGE_SEVERITY *pSeverityList; ++ UINT NumIDs; ++ D3D11_MESSAGE_ID *pIDList; ++} D3D11_INFO_QUEUE_FILTER_DESC; ++typedef struct D3D11_INFO_QUEUE_FILTER ++{ ++ D3D11_INFO_QUEUE_FILTER_DESC AllowList; ++ D3D11_INFO_QUEUE_FILTER_DESC DenyList; ++} D3D11_INFO_QUEUE_FILTER; ++static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 }; ++MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown ++{ ++public: ++ virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0; ++ virtual void __stdcall ClearStoredMessages() = 0; ++ virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0; ++ virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0; ++ virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0; ++ virtual UINT64 __stdcall GetNumStoredMessages() = 0; ++ virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0; ++ virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0; ++ virtual UINT64 __stdcall GetMessageCountLimit() = 0; ++ virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0; ++ virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0; ++ virtual void __stdcall ClearStorageFilter() = 0; ++ virtual HRESULT __stdcall PushEmptyStorageFilter() = 0; ++ virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0; ++ virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0; ++ virtual void __stdcall PopStorageFilter() = 0; ++ virtual UINT __stdcall GetStorageFilterStackSize() = 0; ++ virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0; ++ virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0; ++ virtual void __stdcall ClearRetrievalFilter() = 0; ++ virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0; ++ virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0; ++ virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0; ++ virtual void __stdcall PopRetrievalFilter() = 0; ++ virtual UINT __stdcall GetRetrievalFilterStackSize() = 0; ++ virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0; ++ virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0; ++ virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0; ++ virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0; ++ virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0; ++ virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0; ++ virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0; ++ virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0; ++ virtual void __stdcall SetMuteDebugOutput(BOOL) = 0; ++ virtual BOOL __stdcall GetMuteDebugOutput() = 0; ++}; ++#endif // __MINGW32__ ++ # undef near -diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp -index ba09631..5a50e4b 100644 ---- a/src/3rdparty/angle/src/libEGL/Display.cpp -+++ b/src/3rdparty/angle/src/libEGL/Display.cpp -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include + # undef far + #endif +diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +index 9d003b4..776d92b 100644 +--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +@@ -14,6 +14,12 @@ + #ifndef QT_D3DCOMPILER_DLL + #define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL + #endif ++#ifndef D3DCOMPILE_RESERVED16 ++#define D3DCOMPILE_RESERVED16 (1 << 16) ++#endif ++#ifndef D3DCOMPILE_RESERVED17 ++#define D3DCOMPILE_RESERVED17 (1 << 17) ++#endif - #include "common/debug.h" - #include "common/mathutil.h" -diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp -index 04c7616..5342de1 100644 ---- a/src/3rdparty/angle/src/libGLESv2/Context.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp -@@ -33,6 +33,7 @@ - #include "libEGL/Surface.h" - - #include -+#include - - namespace gl - { -@@ -354,7 +355,7 @@ void Context::deleteFenceSync(GLsync fenceSync) - // wait commands finish. However, since the name becomes invalid, we cannot query the fence, - // and since our API is currently designed for being called from a single thread, we can delete - // the fence immediately. -- mResourceManager->deleteFenceSync(reinterpret_cast(fenceSync)); -+ mResourceManager->deleteFenceSync(uintptr_t(fenceSync)); - } - - void Context::deleteVertexArray(GLuint vertexArray) -@@ -460,7 +461,7 @@ Renderbuffer *Context::getRenderbuffer(GLuint handle) - - FenceSync *Context::getFenceSync(GLsync handle) const - { -- return mResourceManager->getFenceSync(reinterpret_cast(handle)); -+ return mResourceManager->getFenceSync(uintptr_t(handle)); - } - - VertexArray *Context::getVertexArray(GLuint handle) const -diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h -index 922053e..642a6ec 100644 ---- a/src/3rdparty/angle/src/libGLESv2/angletypes.h -+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h -@@ -11,6 +11,7 @@ - - #include "libGLESv2/constants.h" - #include "common/RefCountObject.h" -+#include - - namespace gl - { -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl -index ea6970c..0498cf7 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl -@@ -24,7 +24,7 @@ inline void WriteColor(const uint8_t *source, uint8_t *dest) - template - inline void CopyPixel(const uint8_t *source, uint8_t *dest) - { -- colorType temp; -+ colorDataType temp; - ReadColor(source, &temp); - WriteColor(&temp, dest); - } -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp -index 2650913..96c8497 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp -@@ -129,7 +129,7 @@ bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei w - if (unpack.pixelBuffer.id() != 0) - { - gl::Buffer *pixelBuffer = unpack.pixelBuffer.get(); -- unsigned int offset = reinterpret_cast(pixels); -+ ptrdiff_t offset = reinterpret_cast(pixels); - // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data. - // This functionality should be moved into renderer and the getData method of BufferImpl removed. - const void *bufferData = pixelBuffer->getImplementation()->getData(); -@@ -186,7 +186,7 @@ bool TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void - // to create a render target. - ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat)); - -- unsigned int offset = reinterpret_cast(pixels); -+ ptrdiff_t offset = reinterpret_cast(pixels); - - return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea); - } + // Definitions local to the translation unit + namespace diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -index bd07ee1..b29b2ef 100644 +index a28fd78..e6d7f30 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp -@@ -281,7 +281,7 @@ EGLint Renderer11::initialize() - } - +@@ -333,7 +333,7 @@ EGLint Renderer11::initialize() // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log --#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) -+#if !defined(__MINGW32__) && defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) + #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) ID3D11InfoQueue *infoQueue; - result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); +- result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); ++ result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue); -diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp -index 787c511..4b29be0 100644 ---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp -@@ -537,7 +537,7 @@ void SwapChain11::initPassThroughResources() - samplerDesc.BorderColor[2] = 0.0f; - samplerDesc.BorderColor[3] = 0.0f; - samplerDesc.MinLOD = 0; -- samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; -+ samplerDesc.MaxLOD = FLT_MAX; - - result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); - ASSERT(SUCCEEDED(result)); + if (SUCCEEDED(result)) + { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp -index 345fd24..2af97e7 100644 +index 5831c57..121aa3b 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp -@@ -47,6 +47,57 @@ - #ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION - # define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096 - #endif -+#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION -+# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384 -+#endif -+#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION -+# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048 -+#endif -+#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION -+# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048 -+#endif -+#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP -+# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 -+#endif -+#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP -+# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 -+#endif -+#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT -+# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32 -+#endif -+#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT -+# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32 -+#endif -+#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT -+# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 -+#endif -+#ifndef D3D11_SO_BUFFER_SLOT_COUNT -+# define D3D11_SO_BUFFER_SLOT_COUNT 4 -+#endif -+#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -+# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 -+#endif -+#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT -+# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16 -+#endif -+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8 -+#endif -+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE -+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7 -+#endif -+#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT -+# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 -+#endif -+#ifndef D3D11_PS_INPUT_REGISTER_COUNT -+# define D3D11_PS_INPUT_REGISTER_COUNT 32 -+#endif -+#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT -+# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 -+#endif -+#ifndef D3D11_VS_OUTPUT_REGISTER_COUNT -+# define D3D11_VS_OUTPUT_REGISTER_COUNT 32 -+#endif - - namespace rx - { -@@ -1147,7 +1198,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo +@@ -1196,7 +1196,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) { -#if defined(_DEBUG) -+#if !defined(__MINGW32__) && defined(_DEBUG) ++#if defined(_DEBUG) && !defined(__MINGW32__) return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); #else return S_OK; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp -index 1d52705..d63f9b8 100644 +index 4c552b2..601cd24 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp -@@ -205,7 +205,7 @@ EGLint Renderer9::initialize() - if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) +@@ -200,7 +200,7 @@ EGLint Renderer9::initialize() + if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { ASSERT(mD3d9Ex); - mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast(&mD3d9)); @@ -242,7 +155,7 @@ index 1d52705..d63f9b8 100644 ASSERT(mD3d9); } else -@@ -329,7 +329,7 @@ EGLint Renderer9::initialize() +@@ -324,7 +324,7 @@ EGLint Renderer9::initialize() if (mD3d9Ex) { @@ -251,19 +164,6 @@ index 1d52705..d63f9b8 100644 ASSERT(SUCCEEDED(result)); } -diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.cpp b/src/3rdparty/angle/src/libGLESv2/validationES.cpp -index 1b6180d..f79bc97 100644 ---- a/src/3rdparty/angle/src/libGLESv2/validationES.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/validationES.cpp -@@ -1667,7 +1667,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t - // TODO: also disable index checking on back-ends that are robust to out-of-range accesses. - if (elementArrayBuffer) - { -- unsigned int offset = reinterpret_cast(indices); -+ GLint64 offset = reinterpret_cast(indices); - if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL)) - { - const void *dataPointer = elementArrayBuffer->getImplementation()->getData(); -- -1.9.0.msysgit.0 +1.9.4.msysgit.1 diff --git a/src/angle/src/libEGL/libEGL.pro b/src/angle/src/libEGL/libEGL.pro index 48ce7055fd..a16249309f 100644 --- a/src/angle/src/libEGL/libEGL.pro +++ b/src/angle/src/libEGL/libEGL.pro @@ -6,20 +6,40 @@ winrt: LIBS_PRIVATE += -ld3d11 LIBS_PRIVATE += -ldxguid -L$$QT_BUILD_TREE/lib -l$$qtLibraryTarget(libGLESv2) HEADERS += \ + $$ANGLE_DIR/src/common/NativeWindow.h \ + $$ANGLE_DIR/src/libEGL/AttributeMap.h \ $$ANGLE_DIR/src/libEGL/Config.h \ $$ANGLE_DIR/src/libEGL/Display.h \ + $$ANGLE_DIR/src/libEGL/Error.h \ $$ANGLE_DIR/src/libEGL/main.h \ $$ANGLE_DIR/src/libEGL/resource.h \ $$ANGLE_DIR/src/libEGL/ShaderCache.h \ $$ANGLE_DIR/src/libEGL/Surface.h SOURCES += \ + $$ANGLE_DIR/src/libEGL/AttributeMap.cpp \ $$ANGLE_DIR/src/libEGL/Config.cpp \ $$ANGLE_DIR/src/libEGL/Display.cpp \ + $$ANGLE_DIR/src/libEGL/Error.cpp \ $$ANGLE_DIR/src/libEGL/libEGL.cpp \ $$ANGLE_DIR/src/libEGL/main.cpp \ $$ANGLE_DIR/src/libEGL/Surface.cpp +!winrt { + SOURCES += \ + $$ANGLE_DIR/src/common/win32/NativeWindow.cpp +} else { + HEADERS += \ + $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.h \ + $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.h \ + $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.h + + SOURCES += \ + $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.cpp \ + $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.cpp \ + $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.cpp +} + !static { DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}.def mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}_mingw32.def diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro index c0f7982e6c..705768d17d 100644 --- a/src/angle/src/libGLESv2/libGLESv2.pro +++ b/src/angle/src/libGLESv2/libGLESv2.pro @@ -24,11 +24,13 @@ HEADERS += \ $$ANGLE_DIR/src/common/blocklayout.h \ $$ANGLE_DIR/src/common/shadervars.h \ $$ANGLE_DIR/src/common/utilities.h \ + $$ANGLE_DIR/src/common/NativeWindow.h \ $$ANGLE_DIR/src/libGLESv2/angletypes.h \ $$ANGLE_DIR/src/libGLESv2/BinaryStream.h \ $$ANGLE_DIR/src/libGLESv2/Buffer.h \ $$ANGLE_DIR/src/libGLESv2/Caps.h \ $$ANGLE_DIR/src/libGLESv2/Context.h \ + $$ANGLE_DIR/src/libGLESv2/Data.h \ $$ANGLE_DIR/src/libGLESv2/Error.h \ $$ANGLE_DIR/src/libGLESv2/Fence.h \ $$ANGLE_DIR/src/libGLESv2/formatutils.h \ @@ -53,6 +55,8 @@ HEADERS += \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexDataManager.h \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/MemoryBuffer.h \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ProgramD3D.h \ + $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RenderbufferD3D.h \ + $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RendererD3D.h \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ShaderD3D.h \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureD3D.h \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureStorage.h \ @@ -69,6 +73,7 @@ HEADERS += \ $$ANGLE_DIR/src/libGLESv2/renderer/loadimage.h \ $$ANGLE_DIR/src/libGLESv2/renderer/ProgramImpl.h \ $$ANGLE_DIR/src/libGLESv2/renderer/QueryImpl.h \ + $$ANGLE_DIR/src/libGLESv2/renderer/RenderbufferImpl.h \ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer.h \ $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget.h \ $$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable.h \ @@ -77,6 +82,7 @@ HEADERS += \ $$ANGLE_DIR/src/libGLESv2/renderer/TextureImpl.h \ $$ANGLE_DIR/src/libGLESv2/renderer/TextureFeedbackImpl.h \ $$ANGLE_DIR/src/libGLESv2/renderer/VertexDeclarationCache.h \ + $$ANGLE_DIR/src/libGLESv2/renderer/Workarounds.h \ $$ANGLE_DIR/src/libGLESv2/resource.h \ $$ANGLE_DIR/src/libGLESv2/ResourceManager.h \ $$ANGLE_DIR/src/libGLESv2/Sampler.h \ @@ -102,6 +108,7 @@ SOURCES += \ $$ANGLE_DIR/src/libGLESv2/Buffer.cpp \ $$ANGLE_DIR/src/libGLESv2/Caps.cpp \ $$ANGLE_DIR/src/libGLESv2/Context.cpp \ + $$ANGLE_DIR/src/libGLESv2/Data.cpp \ $$ANGLE_DIR/src/libGLESv2/Error.cpp \ $$ANGLE_DIR/src/libGLESv2/Fence.cpp \ $$ANGLE_DIR/src/libGLESv2/Float16ToFloat32.cpp \ @@ -131,10 +138,12 @@ SOURCES += \ $$ANGLE_DIR/src/libGLESv2/VertexAttribute.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/copyimage.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/loadimage.cpp \ - $$ANGLE_DIR/src/libGLESv2/renderer/loadimageSSE2.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/Image.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/IndexRangeCache.cpp \ + $$ANGLE_DIR/src/libGLESv2/renderer/ProgramImpl.cpp \ + $$ANGLE_DIR/src/libGLESv2/renderer/RenderbufferImpl.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer.cpp \ + $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/BufferD3D.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp \ @@ -143,6 +152,8 @@ SOURCES += \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexDataManager.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ProgramD3D.cpp \ + $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp \ + $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RendererD3D.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ShaderD3D.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureD3D.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureStorage.cpp \ @@ -192,6 +203,8 @@ angle_d3d11 { $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp } +SSE2_SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/loadimageSSE2.cpp + !winrt { HEADERS += \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Blit9.h \ @@ -211,6 +224,7 @@ angle_d3d11 { $$ANGLE_DIR/src/third_party/systeminfo/SystemInfo.h SOURCES += \ + $$ANGLE_DIR/src/common/win32/NativeWindow.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp \ @@ -227,6 +241,16 @@ angle_d3d11 { $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp \ $$ANGLE_DIR/src/third_party/systeminfo/SystemInfo.cpp +} else { + HEADERS += \ + $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.h \ + $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.h \ + $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.h + + SOURCES += \ + $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.cpp \ + $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.cpp \ + $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.cpp } !static { From 4decaa566c1c7bcb29ed83cc8fed853c351f30dc Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 14 Nov 2014 16:16:13 +0200 Subject: [PATCH 37/69] Android: Extract default style Task-number: QTBUG-40621 Change-Id: I4569c87c79769752373a9e6e12cb64c89dfc8f94 Reviewed-by: J-P Nurmi --- .../qtproject/qt5/android/ExtractStyle.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index c65797a1de..c7cd2a263b 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -1792,6 +1792,23 @@ public class ExtractStyle { } } + private JSONObject extractDefaultPalette() + { + TypedArray array = m_theme.obtainStyledAttributes(new int[]{ + android.R.attr.textAppearance + }); + int pos = 0; + JSONObject json = extractTextAppearance(array.getResourceId(pos++, -1)); + try { + json.put("defaultBackgroundColor", defaultBackgroundColor); + json.put("defaultTextColorPrimary", defaultTextColor); + } catch (Exception e) { + e.printStackTrace(); + } + array.recycle(); + return json; + } + public ExtractStyle(Context context, String extractPath) { // Log.i(MinistroService.TAG, "Extract " + extractPath); @@ -1803,9 +1820,13 @@ public class ExtractStyle { TypedArray array = m_theme.obtainStyledAttributes(new int[]{ android.R.attr.colorBackground, android.R.attr.textColorPrimary, + android.R.attr.textColor }); defaultBackgroundColor = array.getColor(0, 0); - defaultTextColor = array.getColor(1, 0xFFFFFF); + int textColor = array.getColor(1, 0xFFFFFF); + if (textColor == 0xFFFFFF) + textColor = array.getColor(2, 0xFFFFFF); + defaultTextColor = textColor; array.recycle(); try @@ -1813,6 +1834,7 @@ public class ExtractStyle { SimpleJsonWriter jsonWriter = new SimpleJsonWriter(m_extractPath+"style.json"); jsonWriter.beginObject(); try { + jsonWriter.name("defaultStyle").value(extractDefaultPalette()); extractWindow(jsonWriter, "windowStyle"); jsonWriter.name("buttonStyle").value(extractTextAppearanceInformations("buttonStyle", "QPushButton", null, -1)); jsonWriter.name("spinnerStyle").value(extractTextAppearanceInformations("spinnerStyle", "QComboBox", null, -1)); From acd06b6ef6c65d1e6a53f551895194512901f595 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 14 Nov 2014 17:49:32 +0200 Subject: [PATCH 38/69] Set Android palette and fonts in QPA plugin. Task-number: QTBUG-40621 Change-Id: Ibe069d4f93ac317e4f1b9ef5fc6bc3edcfac8685 Reviewed-by: J-P Nurmi --- .../android/qandroidplatformintegration.cpp | 22 +- .../android/qandroidplatformintegration.h | 6 +- .../android/qandroidplatformtheme.cpp | 297 +++++++++++++++++- .../platforms/android/qandroidplatformtheme.h | 16 +- src/widgets/styles/qandroidstyle.cpp | 260 +-------------- src/widgets/styles/qandroidstyle_p.h | 3 - 6 files changed, 335 insertions(+), 269 deletions(-) diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 8a3a958d3b..07bdf95bf4 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -78,10 +78,24 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA return QtAndroid::javaVM(); if (resource == "QtActivity") return QtAndroid::activity(); - if (resource == "AndroidStylePalettes") - return &m_palettes; - if (resource == "AndroidStyleFonts") - return &m_fonts; + if (resource == "AndroidStyleData") { + if (m_androidStyle) + return &m_androidStyle->m_styleData; + else + return Q_NULLPTR; + } + if (resource == "AndroidStandardPalette") { + if (m_androidStyle) + return &m_androidStyle->m_standardPalette; + else + return Q_NULLPTR; + } + if (resource == "AndroidQWidgetFonts") { + if (m_androidStyle) + return &m_androidStyle->m_QWidgetsFonts; + else + return Q_NULLPTR; + } if (resource == "AndroidDeviceName") { static QString deviceName = QtAndroid::deviceName(); return &deviceName; diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index 13c98442e9..7b4ab08847 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -44,6 +44,8 @@ #include "qandroidplatformscreen.h" +#include + QT_BEGIN_NAMESPACE class QDesktopWidget; @@ -51,12 +53,12 @@ class QAndroidPlatformServices; class QAndroidSystemLocale; class QPlatformAccessibility; +struct AndroidStyle; class QAndroidPlatformNativeInterface: public QPlatformNativeInterface { public: void *nativeResourceForIntegration(const QByteArray &resource); - QHash m_palettes; - QHash m_fonts; + std::shared_ptr m_androidStyle; }; class QAndroidPlatformIntegration : public QPlatformIntegration diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index 02974018aa..f9f2e4a944 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -37,17 +37,281 @@ #include "qandroidplatformmenu.h" #include "qandroidplatformmenuitem.h" #include "qandroidplatformdialoghelpers.h" -#include -#include + #include +#include +#include +#include +#include + #include #include QT_BEGIN_NAMESPACE +namespace { + const int textStyle_bold = 1; + const int textStyle_italic = 2; + + const int typeface_sans = 1; + const int typeface_serif = 2; + const int typeface_monospace = 3; +} + +static int fontType(const QString &androidControl) +{ + if (androidControl == QLatin1String("defaultStyle")) + return QPlatformTheme::SystemFont; + if (androidControl == QLatin1String("textViewStyle")) + return QPlatformTheme::LabelFont; + else if (androidControl == QLatin1String("buttonStyle")) + return QPlatformTheme::PushButtonFont; + else if (androidControl == QLatin1String("checkboxStyle")) + return QPlatformTheme::CheckBoxFont; + else if (androidControl == QLatin1String("radioButtonStyle")) + return QPlatformTheme::RadioButtonFont; + else if (androidControl == QLatin1String("simple_list_item_single_choice")) + return QPlatformTheme::ItemViewFont; + else if (androidControl == QLatin1String("simple_spinner_dropdown_item")) + return QPlatformTheme::ComboMenuItemFont; + else if (androidControl == QLatin1String("spinnerStyle")) + return QPlatformTheme::ComboLineEditFont; + else if (androidControl == QLatin1String("simple_list_item")) + return QPlatformTheme::ListViewFont; + return -1; +} + +static int paletteType(const QString &androidControl) +{ + if (androidControl == QLatin1String("defaultStyle")) + return QPlatformTheme::SystemPalette; + if (androidControl == QLatin1String("textViewStyle")) + return QPlatformTheme::LabelPalette; + else if (androidControl == QLatin1String("buttonStyle")) + return QPlatformTheme::ButtonPalette; + else if (androidControl == QLatin1String("checkboxStyle")) + return QPlatformTheme::CheckBoxPalette; + else if (androidControl == QLatin1String("radioButtonStyle")) + return QPlatformTheme::RadioButtonPalette; + else if (androidControl == QLatin1String("simple_list_item_single_choice")) + return QPlatformTheme::ItemViewPalette; + else if (androidControl == QLatin1String("editTextStyle")) + return QPlatformTheme::TextLineEditPalette; + else if (androidControl == QLatin1String("spinnerStyle")) + return QPlatformTheme::ComboBoxPalette; + return -1; +} + +static void setPaletteColor(const QVariantMap &object, + QPalette &palette, + QPalette::ColorRole role) +{ + // QPalette::Active -> ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET + palette.setColor(QPalette::Active, + role, + QRgb(object.value(QLatin1String("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt())); + + // QPalette::Inactive -> ENABLED_STATE_SET + palette.setColor(QPalette::Inactive, + role, + QRgb(object.value(QLatin1String("ENABLED_STATE_SET")).toInt())); + + // QPalette::Disabled -> EMPTY_STATE_SET + palette.setColor(QPalette::Disabled, + role, + QRgb(object.value(QLatin1String("EMPTY_STATE_SET")).toInt())); + + palette.setColor(QPalette::Current, role, palette.color(QPalette::Active, role)); + + if (role == QPalette::WindowText) { + // QPalette::BrightText -> PRESSED + // QPalette::Active -> PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET + palette.setColor(QPalette::Active, + QPalette::BrightText, + QRgb(object.value(QLatin1String("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt())); + + // QPalette::Inactive -> PRESSED_ENABLED_STATE_SET + palette.setColor(QPalette::Inactive, + QPalette::BrightText, + QRgb(object.value(QLatin1String("PRESSED_ENABLED_STATE_SET")).toInt())); + + // QPalette::Disabled -> PRESSED_STATE_SET + palette.setColor(QPalette::Disabled, + QPalette::BrightText, + QRgb(object.value(QLatin1String("PRESSED_STATE_SET")).toInt())); + + palette.setColor(QPalette::Current, QPalette::BrightText, palette.color(QPalette::Active, QPalette::BrightText)); + + // QPalette::HighlightedText -> SELECTED + // QPalette::Active -> ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET + palette.setColor(QPalette::Active, + QPalette::HighlightedText, + QRgb(object.value(QLatin1String("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET")).toInt())); + + // QPalette::Inactive -> ENABLED_SELECTED_STATE_SET + palette.setColor(QPalette::Inactive, + QPalette::HighlightedText, + QRgb(object.value(QLatin1String("ENABLED_SELECTED_STATE_SET")).toInt())); + + // QPalette::Disabled -> SELECTED_STATE_SET + palette.setColor(QPalette::Disabled, + QPalette::HighlightedText, + QRgb(object.value(QLatin1String("SELECTED_STATE_SET")).toInt())); + + palette.setColor(QPalette::Current, + QPalette::HighlightedText, + palette.color(QPalette::Active, QPalette::HighlightedText)); + + // Same colors for Text + palette.setColor(QPalette::Active, QPalette::Text, palette.color(QPalette::Active, role)); + palette.setColor(QPalette::Inactive, QPalette::Text, palette.color(QPalette::Inactive, role)); + palette.setColor(QPalette::Disabled, QPalette::Text, palette.color(QPalette::Disabled, role)); + palette.setColor(QPalette::Current, QPalette::Text, palette.color(QPalette::Current, role)); + + // And for ButtonText + palette.setColor(QPalette::Active, QPalette::ButtonText, palette.color(QPalette::Active, role)); + palette.setColor(QPalette::Inactive, QPalette::ButtonText, palette.color(QPalette::Inactive, role)); + palette.setColor(QPalette::Disabled, QPalette::ButtonText, palette.color(QPalette::Disabled, role)); + palette.setColor(QPalette::Current, QPalette::ButtonText, palette.color(QPalette::Current, role)); + } +} + +static std::shared_ptr loadAndroidStyle(QPalette *defaultPalette) +{ + QString stylePath(QLatin1String(qgetenv("MINISTRO_ANDROID_STYLE_PATH"))); + const QLatin1Char slashChar('/'); + if (!stylePath.isEmpty() && !stylePath.endsWith(slashChar)) + stylePath += slashChar; + + QString androidTheme = QLatin1String(qgetenv("QT_ANDROID_THEME")); + if (!androidTheme.isEmpty() && !androidTheme.endsWith(slashChar)) + androidTheme += slashChar; + + if (stylePath.isEmpty()) { + stylePath = QLatin1String("/data/data/org.kde.necessitas.ministro/files/dl/style/") + + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI")) + slashChar; + } + Q_ASSERT(!stylePath.isEmpty()); + + if (!androidTheme.isEmpty() && QFileInfo(stylePath + androidTheme + QLatin1String("style.json")).exists()) + stylePath += androidTheme; + + QFile f(stylePath + QLatin1String("style.json")); + if (!f.open(QIODevice::ReadOnly)) + return std::shared_ptr(); + + QJsonParseError error; + QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error); + if (document.isNull()) { + qCritical() << error.errorString(); + return std::shared_ptr(); + } + + if (!document.isObject()) { + qCritical() << "Style.json does not contain a valid style."; + return std::shared_ptr(); + } + std::shared_ptr style(new AndroidStyle); + style->m_styleData = document.object(); + for (QJsonObject::const_iterator objectIterator = style->m_styleData.constBegin(); + objectIterator != style->m_styleData.constEnd(); + ++objectIterator) { + QString key = objectIterator.key(); + QJsonValue value = objectIterator.value(); + if (!value.isObject()) { + qWarning("Style.json structure is unrecognized."); + continue; + } + QJsonObject item = value.toObject(); + QJsonObject::const_iterator attributeIterator = item.find(QLatin1String("qtClass")); + QByteArray qtClassName; + if (attributeIterator != item.constEnd()) { + // The item has palette and font information for a specific Qt Class (e.g. QWidget, QPushButton, etc.) + qtClassName = attributeIterator.value().toString().toLatin1(); + } + const int ft = fontType(key); + if (ft > -1 || !qtClassName.isEmpty()) { + // Extract font information + QFont font; + + // Font size (in pixels) + attributeIterator = item.find(QLatin1String("TextAppearance_textSize")); + if (attributeIterator != item.constEnd()) + font.setPixelSize(int(attributeIterator.value().toDouble())); + + // Font style + attributeIterator = item.find(QLatin1String("TextAppearance_textStyle")); + if (attributeIterator != item.constEnd()) { + const int style = int(attributeIterator.value().toDouble()); + font.setBold(style & textStyle_bold); + font.setItalic(style & textStyle_italic); + } + + // Font typeface + attributeIterator = item.find(QLatin1String("TextAppearance_typeface")); + if (attributeIterator != item.constEnd()) { + QFont::StyleHint styleHint = QFont::AnyStyle; + switch (int(attributeIterator.value().toDouble())) { + case typeface_sans: + styleHint = QFont::SansSerif; + break; + case typeface_serif: + styleHint = QFont::Serif; + break; + case typeface_monospace: + styleHint = QFont::Monospace; + break; + } + font.setStyleHint(styleHint, QFont::PreferMatch); + } + if (!qtClassName.isEmpty()) + style->m_QWidgetsFonts.insert(qtClassName, font); + + if (ft > -1) { + style->m_fonts.insert(ft, font); + if (ft == QPlatformTheme::SystemFont) + QGuiApplication::setFont(font); + } + // Extract font information + } + + const int pt = paletteType(key); + if (pt > -1 || !qtClassName.isEmpty()) { + // Extract palette information + QPalette palette; + attributeIterator = item.find(QLatin1String("defaultTextColorPrimary")); + if (attributeIterator != item.constEnd()) + palette.setColor(QPalette::WindowText, QRgb(int(attributeIterator.value().toDouble()))); + + attributeIterator = item.find(QLatin1String("defaultBackgroundColor")); + if (attributeIterator != item.constEnd()) + palette.setColor(QPalette::Background, QRgb(int(attributeIterator.value().toDouble()))); + + attributeIterator = item.find(QLatin1String("TextAppearance_textColor")); + if (attributeIterator != item.constEnd()) + setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::WindowText); + + attributeIterator = item.find(QLatin1String("TextAppearance_textColorLink")); + if (attributeIterator != item.constEnd()) + setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::Link); + + attributeIterator = item.find(QLatin1String("TextAppearance_textColorHighlight")); + if (attributeIterator != item.constEnd()) + palette.setColor(QPalette::Highlight, QRgb(int(attributeIterator.value().toDouble()))); + + if (pt == QPlatformTheme::SystemPalette) + *defaultPalette = style->m_standardPalette = palette; + + if (pt > -1) + style->m_palettes.insert(pt, palette); + // Extract palette information + } + } + return style; +} + QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *androidPlatformNativeInterface) { - m_androidPlatformNativeInterface = androidPlatformNativeInterface; QColor background(229, 229, 229); QColor light = background.lighter(150); QColor mid(background.darker(130)); @@ -80,6 +344,9 @@ QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *an m_defaultPalette.setBrush(QPalette::Active, QPalette::Highlight, highlight); m_defaultPalette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight); m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Highlight, highlight.lighter(150)); + m_androidStyleData = loadAndroidStyle(&m_defaultPalette); + QGuiApplication::setPalette(m_defaultPalette); + androidPlatformNativeInterface->m_androidStyle = m_androidStyleData; } QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const @@ -132,9 +399,11 @@ static inline int paletteType(QPlatformTheme::Palette type) const QPalette *QAndroidPlatformTheme::palette(Palette type) const { - QHash::const_iterator it = m_androidPlatformNativeInterface->m_palettes.find(paletteType(type)); - if (it != m_androidPlatformNativeInterface->m_palettes.end()) - return &(it.value()); + if (m_androidStyleData) { + auto it = m_androidStyleData->m_palettes.find(paletteType(type)); + if (it != m_androidStyleData->m_palettes.end()) + return &(it.value()); + } return &m_defaultPalette; } @@ -154,9 +423,11 @@ static inline int fontType(QPlatformTheme::Font type) const QFont *QAndroidPlatformTheme::font(Font type) const { - QHash::const_iterator it = m_androidPlatformNativeInterface->m_fonts.find(fontType(type)); - if (it != m_androidPlatformNativeInterface->m_fonts.end()) - return &(it.value()); + if (m_androidStyleData) { + auto it = m_androidStyleData->m_fonts.find(fontType(type)); + if (it != m_androidStyleData->m_fonts.end()) + return &(it.value()); + } // default in case the style has not set a font static QFont systemFont("Roboto", 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi @@ -165,18 +436,12 @@ const QFont *QAndroidPlatformTheme::font(Font type) const return 0; } -static const QLatin1String STYLES_PATH("/data/data/org.kde.necessitas.ministro/files/dl/style/"); -static const QLatin1String STYLE_FILE("/style.json"); - QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const { switch (hint) { case StyleNames: if (qgetenv("QT_USE_ANDROID_NATIVE_STYLE").toInt() - && (!qgetenv("MINISTRO_ANDROID_STYLE_PATH").isEmpty() - || QFileInfo(STYLES_PATH - + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI")) - + STYLE_FILE).exists())) { + && m_androidStyleData) { return QStringList("android"); } return QStringList("fusion"); diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h index 01611bf9d4..334e86ad7a 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.h +++ b/src/plugins/platforms/android/qandroidplatformtheme.h @@ -37,8 +37,22 @@ #include #include +#include + +#include + QT_BEGIN_NAMESPACE +struct AndroidStyle +{ + QJsonObject m_styleData; + QPalette m_standardPalette; + QHash m_palettes; + QHash m_fonts; + QHash m_QWidgetsFonts; + QHash m_QWidgetsPalettes; +}; + class QAndroidPlatformNativeInterface; class QAndroidPlatformTheme: public QPlatformTheme { @@ -57,7 +71,7 @@ public: private: - QAndroidPlatformNativeInterface * m_androidPlatformNativeInterface; + std::shared_ptr m_androidStyleData; QPalette m_defaultPalette; }; diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp index 38c7497ffa..0bc0b4f087 100644 --- a/src/widgets/styles/qandroidstyle.cpp +++ b/src/widgets/styles/qandroidstyle.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -55,105 +54,33 @@ QT_BEGIN_NAMESPACE namespace { - const int textStyle_bold = 1; - const int textStyle_italic = 2; - - const int typeface_sans = 1; - const int typeface_serif = 2; - const int typeface_monospace = 3; - const quint32 NO_COLOR = 1; const quint32 TRANSPARENT_COLOR = 0; } -static int fontType(const QString &androidControl) -{ - if (androidControl == QLatin1String("textViewStyle")) - return QPlatformTheme::SystemFont; - else if (androidControl == QLatin1String("buttonStyle")) - return QPlatformTheme::PushButtonFont; - else if (androidControl == QLatin1String("checkboxStyle")) - return QPlatformTheme::CheckBoxFont; - else if (androidControl == QLatin1String("radioButtonStyle")) - return QPlatformTheme::RadioButtonFont; - else if (androidControl == QLatin1String("simple_list_item_single_choice")) - return QPlatformTheme::ItemViewFont; - else if (androidControl == QLatin1String("simple_spinner_dropdown_item")) - return QPlatformTheme::ComboMenuItemFont; - else if (androidControl == QLatin1String("spinnerStyle")) - return QPlatformTheme::ComboLineEditFont; - else if (androidControl == QLatin1String("simple_list_item")) - return QPlatformTheme::ListViewFont; - return -1; -} - -static int paletteType(const QString &androidControl) -{ - if (androidControl == QLatin1String("textViewStyle")) - return QPlatformTheme::SystemPalette; - else if (androidControl == QLatin1String("buttonStyle")) - return QPlatformTheme::ButtonPalette; - else if (androidControl == QLatin1String("checkboxStyle")) - return QPlatformTheme::CheckBoxPalette; - else if (androidControl == QLatin1String("radioButtonStyle")) - return QPlatformTheme::RadioButtonPalette; - else if (androidControl == QLatin1String("simple_list_item_single_choice")) - return QPlatformTheme::ItemViewPalette; - else if (androidControl == QLatin1String("editTextStyle")) - return QPlatformTheme::TextLineEditPalette; - else if (androidControl == QLatin1String("spinnerStyle")) - return QPlatformTheme::ComboBoxPalette; - return -1; -} - QAndroidStyle::QAndroidStyle() : QFusionStyle() { QPixmapCache::clear(); checkBoxControl = NULL; - QString stylePath(QLatin1String(qgetenv("MINISTRO_ANDROID_STYLE_PATH"))); - const QLatin1Char slashChar('/'); - if (!stylePath.isEmpty() && !stylePath.endsWith(slashChar)) - stylePath += slashChar; - - QString androidTheme = QLatin1String(qgetenv("QT_ANDROID_THEME")); - if (!androidTheme.isEmpty() && !androidTheme.endsWith(slashChar)) - androidTheme += slashChar; - - if (stylePath.isEmpty()) { - stylePath = QLatin1String("/data/data/org.kde.necessitas.ministro/files/dl/style/") - + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI")) + slashChar; - } - Q_ASSERT(!stylePath.isEmpty()); - - if (!androidTheme.isEmpty() && QFileInfo(stylePath + androidTheme + QLatin1String("style.json")).exists()) - stylePath += androidTheme; - - QFile f(stylePath + QLatin1String("style.json")); - if (!f.open(QIODevice::ReadOnly)) - return; - - QJsonParseError error; - QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error); - if (document.isNull()) { - qCritical() << error.errorString(); - return; - } - - if (!document.isObject()) { - qCritical() << "Style.json does not contain a valid style."; - return; - } - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); + QPalette *standardPalette = reinterpret_cast(nativeInterface->nativeResourceForIntegration("AndroidStandardPalette")); + if (standardPalette) + m_standardPalette = *standardPalette; - QHash *palettes = reinterpret_cast *>(nativeInterface->nativeResourceForIntegration("AndroidStylePalettes")); - QHash *fonts = reinterpret_cast *>(nativeInterface->nativeResourceForIntegration("AndroidStyleFonts")); - palettes->clear(); - fonts->clear(); - QJsonObject object = document.object(); - for (QJsonObject::const_iterator objectIterator = object.constBegin(); - objectIterator != object.constEnd(); + QHash *qwidgetsFonts = reinterpret_cast *>(nativeInterface->nativeResourceForIntegration("AndroidQWidgetFonts")); + if (qwidgetsFonts) { + for (auto it = qwidgetsFonts->constBegin(); it != qwidgetsFonts->constEnd(); ++it) + QApplication::setFont(it.value(), it.key()); + qwidgetsFonts->clear(); // free the memory + } + + QJsonObject *object = reinterpret_cast(nativeInterface->nativeResourceForIntegration("AndroidStyleData")); + if (!object) + return; + + for (QJsonObject::const_iterator objectIterator = object->constBegin(); + objectIterator != object->constEnd(); ++objectIterator) { QString key = objectIterator.key(); QJsonValue value = objectIterator.value(); @@ -163,85 +90,6 @@ QAndroidStyle::QAndroidStyle() } QJsonObject item = value.toObject(); - QJsonObject::const_iterator attributeIterator = item.find(QLatin1String("qtClass")); - QString qtClassName; - if (attributeIterator != item.constEnd()) { - // The item has palette and font information for a specific Qt Class (e.g. QWidget, QPushButton, etc.) - qtClassName = attributeIterator.value().toString(); - } - const int ft = fontType(key); - if (ft > -1 || !qtClassName.isEmpty()) { - // Extract font information - QFont font; - - // Font size (in pixels) - attributeIterator = item.find(QLatin1String("TextAppearance_textSize")); - if (attributeIterator != item.constEnd()) - font.setPixelSize(int(attributeIterator.value().toDouble())); - - // Font style - attributeIterator = item.find(QLatin1String("TextAppearance_textStyle")); - if (attributeIterator != item.constEnd()) { - const int style = int(attributeIterator.value().toDouble()); - font.setBold(style & textStyle_bold); - font.setItalic(style & textStyle_italic); - } - - // Font typeface - attributeIterator = item.find(QLatin1String("TextAppearance_typeface")); - if (attributeIterator != item.constEnd()) { - QFont::StyleHint styleHint = QFont::AnyStyle; - switch (int(attributeIterator.value().toDouble())) { - case typeface_sans: - styleHint = QFont::SansSerif; - break; - case typeface_serif: - styleHint = QFont::Serif; - break; - case typeface_monospace: - styleHint = QFont::Monospace; - break; - } - font.setStyleHint(styleHint, QFont::PreferMatch); - } - if (!qtClassName.isEmpty()) - QApplication::setFont(font, qtClassName.toUtf8()); - if (ft > -1) - fonts->insert(ft, font); - // Extract font information - } - - const int pt = paletteType(key); - if (pt > -1 || !qtClassName.isEmpty()) { - // Extract palette information - QPalette palette; - attributeIterator = item.find(QLatin1String("defaultTextColorPrimary")); - if (attributeIterator != item.constEnd()) - palette.setColor(QPalette::WindowText, QRgb(int(attributeIterator.value().toDouble()))); - - attributeIterator = item.find(QLatin1String("defaultBackgroundColor")); - if (attributeIterator != item.constEnd()) - palette.setColor(QPalette::Background, QRgb(int(attributeIterator.value().toDouble()))); - - attributeIterator = item.find(QLatin1String("TextAppearance_textColor")); - if (attributeIterator != item.constEnd()) - setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::WindowText); - - attributeIterator = item.find(QLatin1String("TextAppearance_textColorLink")); - if (attributeIterator != item.constEnd()) - setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::Link); - - attributeIterator = item.find(QLatin1String("TextAppearance_textColorHighlight")); - if (attributeIterator != item.constEnd()) - palette.setColor(QPalette::Highlight, QRgb(int(attributeIterator.value().toDouble()))); - - if (QLatin1String("QWidget") == qtClassName) - m_standardPalette = palette; - - if (pt > -1) - palettes->insert(pt, palette); - // Extract palette information - } QAndroidStyle::ItemType itemType = qtControl(key); if (QC_UnknownType == itemType) continue; @@ -277,6 +125,7 @@ QAndroidStyle::QAndroidStyle() break; } } + *object = QJsonObject(); // free memory } QAndroidStyle::~QAndroidStyle() @@ -284,81 +133,6 @@ QAndroidStyle::~QAndroidStyle() qDeleteAll(m_androidControlsHash); } - -void QAndroidStyle::setPaletteColor(const QVariantMap &object, - QPalette &palette, - QPalette::ColorRole role) -{ - // QPalette::Active -> ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET - palette.setColor(QPalette::Active, - role, - QRgb(object.value(QLatin1String("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt())); - - // QPalette::Inactive -> ENABLED_STATE_SET - palette.setColor(QPalette::Inactive, - role, - QRgb(object.value(QLatin1String("ENABLED_STATE_SET")).toInt())); - - // QPalette::Disabled -> EMPTY_STATE_SET - palette.setColor(QPalette::Disabled, - role, - QRgb(object.value(QLatin1String("EMPTY_STATE_SET")).toInt())); - - palette.setColor(QPalette::Current, role, palette.color(QPalette::Active, role)); - - if (role == QPalette::WindowText) { - // QPalette::BrightText -> PRESSED - // QPalette::Active -> PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET - palette.setColor(QPalette::Active, - QPalette::BrightText, - QRgb(object.value(QLatin1String("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt())); - - // QPalette::Inactive -> PRESSED_ENABLED_STATE_SET - palette.setColor(QPalette::Inactive, - QPalette::BrightText, - QRgb(object.value(QLatin1String("PRESSED_ENABLED_STATE_SET")).toInt())); - - // QPalette::Disabled -> PRESSED_STATE_SET - palette.setColor(QPalette::Disabled, - QPalette::BrightText, - QRgb(object.value(QLatin1String("PRESSED_STATE_SET")).toInt())); - - palette.setColor(QPalette::Current, QPalette::BrightText, palette.color(QPalette::Active, QPalette::BrightText)); - - // QPalette::HighlightedText -> SELECTED - // QPalette::Active -> ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET - palette.setColor(QPalette::Active, - QPalette::HighlightedText, - QRgb(object.value(QLatin1String("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET")).toInt())); - - // QPalette::Inactive -> ENABLED_SELECTED_STATE_SET - palette.setColor(QPalette::Inactive, - QPalette::HighlightedText, - QRgb(object.value(QLatin1String("ENABLED_SELECTED_STATE_SET")).toInt())); - - // QPalette::Disabled -> SELECTED_STATE_SET - palette.setColor(QPalette::Disabled, - QPalette::HighlightedText, - QRgb(object.value(QLatin1String("SELECTED_STATE_SET")).toInt())); - - palette.setColor(QPalette::Current, - QPalette::HighlightedText, - palette.color(QPalette::Active, QPalette::HighlightedText)); - - // Same colors for Text - palette.setColor(QPalette::Active, QPalette::Text, palette.color(QPalette::Active, role)); - palette.setColor(QPalette::Inactive, QPalette::Text, palette.color(QPalette::Inactive, role)); - palette.setColor(QPalette::Disabled, QPalette::Text, palette.color(QPalette::Disabled, role)); - palette.setColor(QPalette::Current, QPalette::Text, palette.color(QPalette::Current, role)); - - // And for ButtonText - palette.setColor(QPalette::Active, QPalette::ButtonText, palette.color(QPalette::Active, role)); - palette.setColor(QPalette::Inactive, QPalette::ButtonText, palette.color(QPalette::Inactive, role)); - palette.setColor(QPalette::Disabled, QPalette::ButtonText, palette.color(QPalette::Disabled, role)); - palette.setColor(QPalette::Current, QPalette::ButtonText, palette.color(QPalette::Current, role)); - } -} - QAndroidStyle::ItemType QAndroidStyle::qtControl(const QString &android) { if (android == QLatin1String("buttonStyle")) diff --git a/src/widgets/styles/qandroidstyle_p.h b/src/widgets/styles/qandroidstyle_p.h index 65fa4cd096..504d43fe96 100644 --- a/src/widgets/styles/qandroidstyle_p.h +++ b/src/widgets/styles/qandroidstyle_p.h @@ -376,9 +376,6 @@ private: static ItemType qtControl(QStyle::SubElement subElement); static ItemType qtControl(const QString &android); - static void setPaletteColor(const QVariantMap &object, - QPalette &palette, - QPalette::ColorRole role); private: typedef QHash AndroidControlsHash; AndroidControlsHash m_androidControlsHash; From c8751b3d84a5ba25effb88946fc56d989c5fa10a Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 14 Nov 2014 14:55:51 +0100 Subject: [PATCH 39/69] Doc: Corrected brief statement for overview page Task-number: QTBUG-42682 Change-Id: I28afbb8b09d5568f3fae29fdfc5a3d15376b72de Reviewed-by: Martin Smith --- src/corelib/doc/src/animation.qdoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/doc/src/animation.qdoc b/src/corelib/doc/src/animation.qdoc index 6910b18937..5839d42a39 100644 --- a/src/corelib/doc/src/animation.qdoc +++ b/src/corelib/doc/src/animation.qdoc @@ -27,6 +27,7 @@ /*! \group animation + \brief Provides an easy way for creating animated GUIs. \title Animation Framework This page lists classes belonging to \l{Qt Core}'s @@ -46,7 +47,7 @@ \keyword Animation The animation framework aims to provide an easy way for creating animated - and smooth GUI's. By animating Qt properties, the framework provides great + and smooth GUIs. By animating Qt properties, the framework provides great freedom for animating widgets and other \l{QObject}s. The framework can also be used with the Graphics View framework. Many of the concepts available in the animation framework are also available in \l{Qt Quick}, From 365212fedeef639787a2c183b1ae975b2a9cb9c3 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 14 Nov 2014 11:50:32 +0200 Subject: [PATCH 40/69] winrt: Blacklist certain devices from creating a depth/stencil buffer This passes the EGLConfig created in the platform screen to the underlying context, and certain GPUs are blacklisted to be prevented from creating a configuration which does not render properly with Qt Quick. Task-number: QTBUG-42260 Change-Id: I7e1cdc33c2f5662538723c6930fad5f13b151d6f Reviewed-by: Oliver Wolff --- .../platforms/winrt/qwinrteglcontext.cpp | 4 +- .../platforms/winrt/qwinrteglcontext.h | 2 +- .../platforms/winrt/qwinrtintegration.cpp | 2 +- src/plugins/platforms/winrt/qwinrtscreen.cpp | 43 ++++++++++++++++++- src/plugins/platforms/winrt/qwinrtscreen.h | 1 + 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 5daeee69c0..64aedb1b33 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -35,8 +35,8 @@ QT_BEGIN_NAMESPACE -QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface) - : QEGLPlatformContext(format, share, display), m_eglSurface(surface) +QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config) + : QEGLPlatformContext(format, share, display, &config), m_eglSurface(surface) { } diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h index fb1199a79e..142e204fc8 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.h +++ b/src/plugins/platforms/winrt/qwinrteglcontext.h @@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE class QWinRTEGLContext : public QEGLPlatformContext { public: - explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface); + explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config); QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index b8ca9fdc66..4fa90b4b68 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -110,7 +110,7 @@ QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *wi QPlatformOpenGLContext *QWinRTIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { QWinRTScreen *screen = static_cast(context->screen()->handle()); - return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface()); + return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface(), screen->eglConfig()); } QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 3933902ae3..681307ddcf 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -33,6 +33,11 @@ #include "qwinrtscreen.h" +#define EGL_EGLEXT_PROTOTYPES +#include +#include +#include + #include "qwinrtbackingstore.h" #include "qwinrtinputcontext.h" #include "qwinrtcursor.h" @@ -452,6 +457,7 @@ public: EGLDisplay eglDisplay; EGLSurface eglSurface; + EGLConfig eglConfig; QHash applicationTokens; QHash windowTokens; @@ -575,7 +581,36 @@ QWinRTScreen::QWinRTScreen() if (!eglInitialize(d->eglDisplay, NULL, NULL)) qCritical("Failed to initialize EGL: 0x%x", eglGetError()); - d->eglSurface = eglCreateWindowSurface(d->eglDisplay, q_configFromGLFormat(d->eglDisplay, d->surfaceFormat), d->coreWindow.Get(), NULL); + // Check that the device properly supports depth/stencil rendering, and disable them if not + ComPtr d3dDevice; + const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf()); + if (ok && d3dDevice) { + ComPtr dxgiDevice; + hr = d3dDevice.As(&dxgiDevice); + if (SUCCEEDED(hr)) { + ComPtr dxgiAdapter; + hr = dxgiDevice->GetAdapter(&dxgiAdapter); + if (SUCCEEDED(hr)) { + ComPtr dxgiAdapter2; + hr = dxgiAdapter.As(&dxgiAdapter2); + if (SUCCEEDED(hr)) { + DXGI_ADAPTER_DESC2 desc; + hr = dxgiAdapter2->GetDesc2(&desc); + if (SUCCEEDED(hr)) { + // The following GPUs do not render properly with depth/stencil + if ((desc.VendorId == 0x4d4f4351 && desc.DeviceId == 0x32303032)) { // Qualcomm Adreno 225 + d->surfaceFormat.setDepthBufferSize(-1); + d->surfaceFormat.setStencilBufferSize(-1); + } + } + } + } + } + } + + d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat); + d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat); + d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), NULL); if (d->eglSurface == EGL_NO_SURFACE) qCritical("Failed to create EGL window surface: 0x%x", eglGetError()); } @@ -706,6 +741,12 @@ EGLSurface QWinRTScreen::eglSurface() const return d->eglSurface; } +EGLConfig QWinRTScreen::eglConfig() const +{ + Q_D(const QWinRTScreen); + return d->eglConfig; +} + QWindow *QWinRTScreen::topWindow() const { Q_D(const QWinRTScreen); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index e70a998216..c95a2073ed 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -109,6 +109,7 @@ public: ABI::Windows::UI::Core::ICoreWindow *coreWindow() const; EGLDisplay eglDisplay() const; // To opengl context EGLSurface eglSurface() const; // To window + EGLConfig eglConfig() const; private: void handleExpose(); From e7839239eb62da495f54f11a9f72be6bbc4a053e Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 13 Nov 2014 15:47:16 +0200 Subject: [PATCH 41/69] Android: Extract AnimatedStateListDrawable Task-number: QTBUG-42488 Change-Id: I6400c5ba54bdc9a0e1db71986432a6653da9e534 Reviewed-by: J-P Nurmi Reviewed-by: BogDan Vatra --- .../qtproject/qt5/android/ExtractStyle.java | 75 ++++++++++++++++++- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index c7cd2a263b..4dbc33057b 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -49,6 +49,7 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; import org.json.JSONArray; import org.json.JSONException; @@ -97,6 +98,8 @@ public class ExtractStyle { Class styleableClass = getClass("android.R$styleable"); Class rippleDrawableClass = getClass("android.graphics.drawable.RippleDrawable"); + Class animatedStateListDrawableClass = getClass("android.graphics.drawable.AnimatedStateListDrawable"); + final int[] EMPTY_STATE_SET = {}; final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled}; final int[] FOCUSED_STATE_SET = {android.R.attr.state_focused}; @@ -631,10 +634,9 @@ public class ExtractStyle { JSONObject stateJson = new JSONObject(); final Drawable d = (Drawable) StateListDrawable.class.getMethod("getStateDrawable", Integer.TYPE).invoke(stateList, i); final int [] states = (int[]) StateListDrawable.class.getMethod("getStateSet", Integer.TYPE).invoke(stateList, i); - if (states == null) - continue; - stateJson.put("states", getStatesList(states)); - stateJson.put("drawable", getDrawable(d, filename+"__"+getStatesName(states), null)); + if (states != null) + stateJson.put("states", getStatesList(states)); + stateJson.put("drawable", getDrawable(d, filename+"__" + (states != null ? getStatesName(states) : ("state_pos_" + i)), null)); array.put(stateJson); } json.put("type", "stateslist"); @@ -810,6 +812,67 @@ public class ExtractStyle { return json; } + private HashMap getStateTransitions(Object sa) throws Exception + { + HashMap transitions = new HashMap(); + final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa); + long[] keys = (long[]) getAccessibleField(sa.getClass(), "mKeys").get(sa); + long[] values = (long[]) getAccessibleField(sa.getClass(), "mValues").get(sa); + for (int i = 0; i < sz; i++) { + transitions.put(keys[i], values[i]); + } + return transitions; + } + + private HashMap getStateIds(Object sa) throws Exception + { + HashMap states = new HashMap(); + final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa); + int[] keys = (int[]) getAccessibleField(sa.getClass(), "mKeys").get(sa); + int[] values = (int[]) getAccessibleField(sa.getClass(), "mValues").get(sa); + for (int i = 0; i < sz; i++) { + states.put(keys[i], values[i]); + } + return states; + } + + private int findStateIndex(int id, HashMap stateIds) + { + for (Map.Entry s : stateIds.entrySet()) { + if (id == s.getValue()) + return s.getKey(); + } + return -1; + } + + private JSONObject getAnimatedStateListDrawable(Object drawable, String filename) + { + JSONObject json = getStateListDrawable(drawable, filename); + try { + Object state = getAccessibleField(animatedStateListDrawableClass, "mState").get(drawable); + + HashMap stateIds = getStateIds(getAccessibleField(state.getClass(), "mStateIds").get(state)); + HashMap transitions = getStateTransitions(getAccessibleField(state.getClass(), "mTransitions").get(state)); + + for (Map.Entry t : transitions.entrySet()) { + final int toState = findStateIndex(t.getKey().intValue(), stateIds); + final int fromState = findStateIndex((int) (t.getKey() >> 32), stateIds); + + JSONObject transition = new JSONObject(); + transition.put("from", fromState); + transition.put("to", toState); + transition.put("reverse", (t.getValue() >> 32) != 0); + + JSONArray stateslist = json.getJSONArray("stateslist"); + JSONObject stateobj = stateslist.getJSONObject(t.getValue().intValue()); + stateobj.put("transition", transition); + } + } catch (Exception e) { + e.printStackTrace(); + } + return json; + } + public JSONObject getDrawable(Object drawable, String filename, Rect padding) { if (drawable == null) @@ -855,6 +918,10 @@ public class ExtractStyle { if (rippleDrawableClass != null && rippleDrawableClass.isInstance(drawable)) return getRippleDrawable(drawable, filename, padding); + + if (animatedStateListDrawableClass != null && animatedStateListDrawableClass.isInstance(drawable)) + return getAnimatedStateListDrawable(drawable, filename); + if (drawable instanceof ScaleDrawable) { return getDrawable(((ScaleDrawable)drawable).getDrawable(), filename, null); From 68862c7231d257c2c1b17ddcb60cc742098d5ed5 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 13 Nov 2014 12:01:44 +0100 Subject: [PATCH 42/69] rcc: Change two-pass feature from opt-out to opt-in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the 'big-data' feature introduced and made mandatory with commit 5395180 opt-in trough CONFIG += resources_big. Since the feature has been introduced several setups have been found where the feature cannot be used, or not be used out-of-the-box. Using the traditional default behavior lowers the risk of further breakages. Change-Id: Ifd04204adadeec539e962d6a9a6955f63781bd36 Reviewed-by: Oswald Buddenhagen Reviewed-by: Fawzi Mohamed Reviewed-by: Tor Arne Vestbø Reviewed-by: Frederik Gladhorn --- mkspecs/features/resources.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf index 27db7d7d7a..8564731a22 100644 --- a/mkspecs/features/resources.prf +++ b/mkspecs/features/resources.prf @@ -11,7 +11,7 @@ rcc.name = RCC ${QMAKE_FILE_IN} rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} rcc.CONFIG += add_inputs_as_makefile_deps -resources_small|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") { +!resources_big|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") { rcc.output = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)} rcc.commands = $$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} From 2f1d22c8b4033b7160dde08ba232d22a620f8cd7 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 7 Nov 2014 10:52:34 +0100 Subject: [PATCH 43/69] qdoc: Removed text formatting from requisites table Removed the teletype (code) formatting used in the requisite table: include, qmake (qtvariable) and import statement (for QML types). This makes the table look more uniform as it doesn't mix font styles anymore. Also, remove the closing tag that caused incorrect html to be generated. Change-Id: I180a90c22d4b0066aade8ce38d13343076285ff0 Reviewed-by: Martin Smith --- src/tools/qdoc/htmlgenerator.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index bd8d45ab53..0f5bf26e71 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -1898,12 +1898,9 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) //add the includes to the map if (!inner->includes().isEmpty()) { text.clear(); - text << formattingRightMap()[ATOM_FORMATTING_BOLD] - << formattingLeftMap()[ATOM_FORMATTING_TELETYPE] - << highlightedCode(indent(codeIndent, + text << highlightedCode(indent(codeIndent, marker->markedUpIncludes(inner->includes())), - inner) - << formattingRightMap()[ATOM_FORMATTING_TELETYPE]; + inner); requisites.insert(headerText, text); } @@ -1938,9 +1935,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) ModuleNode* moduleNode = qdb_->findModule(inner->moduleName()); if (moduleNode && !moduleNode->qtVariable().isEmpty()) { text.clear(); - text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_TELETYPE) - << "QT += " + moduleNode->qtVariable() - << Atom(Atom::FormattingRight, ATOM_FORMATTING_TELETYPE); + text << "QT += " + moduleNode->qtVariable(); requisites.insert(qtVariableText, text); } } @@ -2053,10 +2048,7 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker) else qmlModuleVersion = qcn->qmlModuleVersion(); text.clear(); - text << formattingRightMap()[ATOM_FORMATTING_BOLD] - << formattingLeftMap()[ATOM_FORMATTING_TELETYPE] - << "import " + qcn->qmlModuleName() + " " + qmlModuleVersion - << formattingRightMap()[ATOM_FORMATTING_TELETYPE]; + text << "import " + qcn->qmlModuleName() + " " + qmlModuleVersion; requisites.insert(importText, text); //add the since and project into the map From 1ffe39dfd155c1318e249591c71e808437cc9696 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 28 Oct 2014 10:00:56 +0100 Subject: [PATCH 44/69] Make it possible to disable font embedding When font embedding is explicitly disabled, fall back to painter paths as we would if the font prohibits embedding. Note that this flag was never respected on any platform in any version of Qt, as far as I've been able to tell, because the handling of it in the X11 print engine was removed shortly after it was introduced in 2005. [ChangeLog][Printing] Disabling font embedding is now possible using the QPrinter::setFontEmbedding() function. Task-number: QTBUG-41943 Change-Id: Ice5e893f9893c5243310ae7892bec7497dd55c4a Reviewed-by: Konstantin Ritt Reviewed-by: Lars Knoll --- src/gui/painting/qpdf.cpp | 3 ++- .../platforms/cocoa/qprintengine_mac.mm | 16 +++++++++------ .../platforms/cocoa/qprintengine_mac_p.h | 3 ++- src/printsupport/kernel/qprintengine_win.cpp | 16 +++++++++------ src/printsupport/kernel/qprintengine_win_p.h | 4 +++- src/printsupport/kernel/qprinter.cpp | 4 ---- .../kernel/qprinter/tst_qprinter.cpp | 20 +++++-------------- 7 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 9082f98205..46d016de6b 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -2501,7 +2501,8 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti) QFontEngine::FaceId face_id = fe->faceId(); bool noEmbed = false; - if (face_id.filename.isEmpty() + if (!embedFonts + || face_id.filename.isEmpty() || fe->fsType & 0x200 /* bitmap embedding only */ || fe->fsType == 2 /* no embedding allowed */) { *currentPage << "Q\n"; diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index f684fef233..a58514614b 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -412,7 +412,10 @@ void QMacPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); - d->paintEngine->drawTextItem(p, ti); + if (!d->embedFonts) + QPaintEngine::drawTextItem(p, ti); + else + d->paintEngine->drawTextItem(p, ti); } void QMacPrintEngine::drawTiledPixmap(const QRectF &dr, const QPixmap &pixmap, const QPointF &sr) @@ -457,8 +460,6 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va break; case PPK_CustomBase: break; - case PPK_FontEmbedding: - break; case PPK_PageOrder: // TODO Check if can be supported via Cups Options break; @@ -471,6 +472,9 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va break; // The following keys are properties and settings that are supported by the Mac PrintEngine + case PPK_FontEmbedding: + d->embedFonts = value.toBool(); + break; case PPK_Resolution: { // TODO It appears the old code didn't actually set the resolution??? Can we delete all this??? int bestResolution = 0; @@ -622,9 +626,6 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const case PPK_CustomBase: // Special case, leave null break; - case PPK_FontEmbedding: - ret = false; - break; case PPK_PageOrder: // TODO Check if can be supported via Cups Options ret = QPrinter::FirstPageFirst; @@ -648,6 +649,9 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const break; // The following keys are properties and settings that are supported by the Mac PrintEngine + case PPK_FontEmbedding: + ret = d->embedFonts; + break; case PPK_CollateCopies: { Boolean status; PMGetCollate(d->settings(), &status); diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index c7307688ae..c99069b7f7 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -124,10 +124,11 @@ public: QString m_creator; QPaintEngine *paintEngine; QHash valueCache; + uint embedFonts; QMacPrintEnginePrivate() : mode(QPrinter::ScreenResolution), state(QPrinter::Idle), m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))), - printInfo(0), paintEngine(0) {} + printInfo(0), paintEngine(0), embedFonts(true) {} ~QMacPrintEnginePrivate(); void initialize(); diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index 7f5e83c61e..4e0a3e0795 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -269,7 +269,8 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem bool fallBack = state->pen().brush().style() != Qt::SolidPattern || qAlpha(brushColor) != 0xff || d->txop >= QTransform::TxProject - || ti.fontEngine->type() != QFontEngine::Win; + || ti.fontEngine->type() != QFontEngine::Win + || !d->embed_fonts; if (!fallBack) { const QVariantMap userData = ti.fontEngine->userData().toMap(); @@ -1001,8 +1002,6 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & // The following keys are settings that are unsupported by the Windows PrintEngine case PPK_CustomBase: break; - case PPK_FontEmbedding: - break; case PPK_PageOrder: break; case PPK_PrinterProgram: @@ -1011,6 +1010,10 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & break; // The following keys are properties and settings that are supported by the Windows PrintEngine + case PPK_FontEmbedding: + d->embed_fonts = value.toBool(); + break; + case PPK_CollateCopies: { if (!d->devMode) @@ -1282,9 +1285,6 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const // The following keys are settings that are unsupported by the Windows PrintEngine // Return sensible default values to ensure consistent behavior across platforms - case PPK_FontEmbedding: - value = false; - break; case PPK_PageOrder: value = QPrinter::FirstPageFirst; break; @@ -1296,6 +1296,10 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const break; // The following keys are properties and settings that are supported by the Windows PrintEngine + case PPK_FontEmbedding: + value = d->embed_fonts; + break; + case PPK_CollateCopies: value = d->devMode->dmCollate == DMCOLLATE_TRUE; break; diff --git a/src/printsupport/kernel/qprintengine_win_p.h b/src/printsupport/kernel/qprintengine_win_p.h index b84bde8a92..0a87795bb8 100644 --- a/src/printsupport/kernel/qprintengine_win_p.h +++ b/src/printsupport/kernel/qprintengine_win_p.h @@ -125,7 +125,8 @@ public: m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))), num_copies(1), printToFile(false), - reinit(false) + reinit(false), + embed_fonts(true) { } @@ -216,6 +217,7 @@ public: uint has_pen : 1; uint has_brush : 1; uint has_custom_paper_size : 1; + uint embed_fonts : 1; uint txop; diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index c13b1574d0..437a68e609 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -1632,8 +1632,6 @@ QPrinter::PaperSource QPrinter::paperSource() const Enabled or disables font embedding depending on \a enable. - Currently this option is only supported on X11. - \sa fontEmbeddingEnabled() */ void QPrinter::setFontEmbeddingEnabled(bool enable) @@ -1647,8 +1645,6 @@ void QPrinter::setFontEmbeddingEnabled(bool enable) Returns \c true if font embedding is enabled. - Currently this option is only supported on X11. - \sa setFontEmbeddingEnabled() */ bool QPrinter::fontEmbeddingEnabled() const diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp index 1be570e4b8..e3a72f4ab4 100644 --- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp +++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp @@ -1103,9 +1103,7 @@ void tst_QPrinter::fontEmbedding() { // fontEmbeddingEnabled() / setFontEmbeddingEnabled() / PPK_FontEmbedding // PdfFormat: Supported, default true - // NativeFormat, Cups: Supported, default true - // NativeFormat, Win: Unsupported, always false - // NativeFormat, Mac: Unsupported, always false + // NativeFormat: Supported, default true QPrinter pdf; pdf.setOutputFormat(QPrinter::PdfFormat); @@ -1116,25 +1114,17 @@ void tst_QPrinter::fontEmbedding() QPrinter native; if (native.outputFormat() == QPrinter::NativeFormat) { // Test default -#if defined Q_OS_MAC || defined Q_OS_WIN - QCOMPARE(native.fontEmbeddingEnabled(), false); -#else QCOMPARE(native.fontEmbeddingEnabled(), true); -#endif // Q_OS_MAC || Q_OS_WIN // Test set/get - bool expected = true; - native.setFontEmbeddingEnabled(expected); -#if defined Q_OS_MAC || defined Q_OS_WIN - expected = false; -#endif // Q_OS_MAC || Q_OS_WIN - QCOMPARE(native.fontEmbeddingEnabled(), expected); + native.setFontEmbeddingEnabled(true); + QCOMPARE(native.fontEmbeddingEnabled(), true); // Test value preservation native.setOutputFormat(QPrinter::PdfFormat); - QCOMPARE(native.fontEmbeddingEnabled(), expected); + QCOMPARE(native.fontEmbeddingEnabled(), true); native.setOutputFormat(QPrinter::NativeFormat); - QCOMPARE(native.fontEmbeddingEnabled(), expected); + QCOMPARE(native.fontEmbeddingEnabled(), true); } else { QSKIP("No printers installed, cannot test NativeFormat, please install printers to test"); } From 946cf4ca00dbcdc15d24dc2b52bf01c69dcda848 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 11 Nov 2014 08:27:10 +0200 Subject: [PATCH 45/69] Android: copy build.gradle to install folder. Task-number: QTCREATORBUG-13311 Change-Id: I4c91164ae1fc593397bb46f98fbc49ef1569da39 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/templates/templates.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/android/templates/templates.pro b/src/android/templates/templates.pro index 684a556c5b..55387f3af7 100644 --- a/src/android/templates/templates.pro +++ b/src/android/templates/templates.pro @@ -2,6 +2,7 @@ CONFIG -= qt android_install templates.files = \ $$PWD/AndroidManifest.xml \ + $$PWD/build.gradle \ $$PWD/res templates.path = $$[QT_INSTALL_PREFIX]/src/android/templates @@ -17,5 +18,6 @@ INSTALLS += templates QMAKE_POST_LINK += \ $${QMAKE_COPY} $$shell_path($$PWD/AndroidManifest.xml) $$OUT_PATH $$RETURN \ + $${QMAKE_COPY} $$shell_path($$PWD/build.gradle) $$OUT_PATH $$RETURN \ $${QMAKE_COPY_DIR} $$shell_path($$PWD/res) $$OUT_PATH } From dfbd09378c203ce029adf4a31f3a755cf22fb2e8 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 14 Nov 2014 13:01:13 +0200 Subject: [PATCH 46/69] Fix crash on Android L and list view items. This crash is visible on Android L. This patch removes the static_cast which caused the crash and it also fixed the list view item problem. I could not create separated patches because they depend too much on each other. Task-number: QTBUG-42673 Task-number: QTBUG-41814 Change-Id: I5d3e9c2b73df8f0e87e815b785b1c64d65a3ffaf Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/styles/qandroidstyle.cpp | 112 ++++++++++----------------- src/widgets/styles/qandroidstyle_p.h | 8 +- 2 files changed, 42 insertions(+), 78 deletions(-) diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp index 0bc0b4f087..337da24aee 100644 --- a/src/widgets/styles/qandroidstyle.cpp +++ b/src/widgets/styles/qandroidstyle.cpp @@ -244,6 +244,10 @@ QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::PrimitiveElement primit case QStyle::PE_FrameLineEdit: return QC_EditText; + case QStyle::PE_IndicatorViewItemCheck: + case QStyle::PE_IndicatorCheckBox: + return QC_Checkbox; + case QStyle::PE_FrameWindow: case QStyle::PE_Widget: case QStyle::PE_Frame: @@ -357,37 +361,8 @@ void QAndroidStyle::drawControl(QStyle::ControlElement element, } break; default: - break; - } - } else if (element == CE_ItemViewItem) { - const QStyleOptionViewItem *vopt = qstyleoption_cast(opt); - if (vopt && vopt->features & QStyleOptionViewItem::HasCheckIndicator) { - p->save(); - p->setClipRect(opt->rect); - - QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, w); - - // draw the background - proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, w); - - // draw the check mark - QStyleOptionViewItem option(*vopt); - option.rect = checkRect; - option.state = option.state & ~QStyle::State_HasFocus; - - switch (vopt->checkState) { - case Qt::Unchecked: - option.state |= QStyle::State_Off; - break; - default: - option.state |= QStyle::State_On; - break; - } - QPixmap pixmap = checkBoxControl->imgCheckBox(&option); - p->drawPixmap(checkRect, pixmap); - p->restore(); - } else { QFusionStyle::drawControl(element, opt, p, w); + break; } } else { QFusionStyle::drawControl(element, opt, p, w); @@ -532,7 +507,7 @@ QRect QAndroidStyle::subControlRect(ComplexControl cc, case CC_GroupBox: { if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast(opt)) { QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2); - QSize checkBoxSize = checkBoxControl->sizeCheckBox(opt); + QSize checkBoxSize = checkBoxControl->size(opt); int indicatorWidth = checkBoxSize.width(); int indicatorHeight = checkBoxSize.height(); QRect checkBoxRect; @@ -589,9 +564,9 @@ int QAndroidStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, case PM_ScrollBarExtent: return 0; case PM_IndicatorWidth: - return checkBoxControl->sizeCheckBox(option).width(); + return checkBoxControl->size(option).width(); case PM_IndicatorHeight: - return checkBoxControl->sizeCheckBox(option).height(); + return checkBoxControl->size(option).height(); default: return QFusionStyle::pixelMetric(metric, option, widget); } @@ -608,7 +583,7 @@ QSize QAndroidStyle::sizeFromContents(ContentsType ct, if (const QStyleOptionHeader *hdr = qstyleoption_cast(opt)) { bool nullIcon = hdr->icon.isNull(); int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w); - int iconSize = nullIcon ? 0 : checkBoxControl->sizeCheckBox(opt).width(); + int iconSize = nullIcon ? 0 : checkBoxControl->size(opt).width(); QSize txt; /* * These next 4 lines are a bad hack to fix a bug in case a QStyleSheet is applied at QApplication level. @@ -642,7 +617,7 @@ QSize QAndroidStyle::sizeFromContents(ContentsType ct, if (ct == CT_GroupBox) { if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast(opt)) { QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2); - QSize checkBoxSize = checkBoxControl->sizeCheckBox(opt); + QSize checkBoxSize = checkBoxControl->size(opt); int indicatorWidth = checkBoxSize.width(); int indicatorHeight = checkBoxSize.height(); QRect checkBoxRect; @@ -738,13 +713,6 @@ QSize QAndroidStyle::AndroidDrawable::size() const return QSize(); } -QPixmap QAndroidStyle::AndroidDrawable::img() const -{ - if (type() == Image || type() == NinePatch) - return static_cast(this)->img(); - - return QPixmap(); -} QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidDrawable::fromMap(const QVariantMap &drawable, ItemType itemType) @@ -810,19 +778,7 @@ void QAndroidStyle::AndroidImageDrawable::draw(QPainter *painter, const QStyleOp QPixmapCache::insert(m_hashKey, pm); } - painter->drawPixmap(opt->rect.x(), (opt->rect.height() - pm.height()) / 2, pm); -} -QPixmap QAndroidStyle::AndroidImageDrawable::img() const -{ - if (m_hashKey.isEmpty()) - m_hashKey = QFileInfo(m_filePath).fileName(); - - QPixmap pm; - if (!QPixmapCache::find(m_hashKey, &pm)) { - pm.load(m_filePath); - QPixmapCache::insert(m_hashKey, pm); - } - return pm; + painter->drawPixmap(opt->rect.x(), opt->rect.y() + (opt->rect.height() - pm.height()) / 2, pm); } QSize QAndroidStyle::AndroidImageDrawable::size() const @@ -1220,14 +1176,6 @@ QSize QAndroidStyle::AndroidStateDrawable::sizeImage(const QStyleOption *opt) co s = drawable->size(); return s; } -QPixmap QAndroidStyle::AndroidStateDrawable::img(const QStyleOption *opt) const -{ - QPixmap pm; - const AndroidDrawable *drawable = bestAndroidStateMatch(opt); - if (drawable) - pm = drawable->img(); - return pm; -} const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::bestAndroidStateMatch(const QStyleOption *opt) const { @@ -1507,7 +1455,6 @@ QRect QAndroidStyle::AndroidControl::subElementRect(QStyle::SubElement /* subEle return visualRect(option->direction, option->rect, r); } return option->rect; - } QRect QAndroidStyle::AndroidControl::subControlRect(const QStyleOptionComplex *option, @@ -1552,6 +1499,16 @@ QMargins QAndroidStyle::AndroidControl::padding() return QMargins(); } +QSize QAndroidStyle::AndroidControl::size(const QStyleOption *option) +{ + if (const AndroidDrawable *drawable = backgroundDrawable()) { + if (drawable->type() == State) + drawable = static_cast(backgroundDrawable())->bestAndroidStateMatch(option); + return drawable->size(); + } + return QSize(); +} + const QAndroidStyle::AndroidDrawable *QAndroidStyle::AndroidControl::backgroundDrawable() const { return m_background; @@ -1562,11 +1519,12 @@ QAndroidStyle::AndroidCompoundButtonControl::AndroidCompoundButtonControl(const : AndroidControl(control, itemType) { QVariantMap::const_iterator it = control.find(QLatin1String("CompoundButton_button")); - if (it != control.end()) + if (it != control.end()) { m_button = AndroidDrawable::fromMap(it.value().toMap(), itemType); - else + const_cast(m_button)->setPaddingLeftToSizeWidth(); + } else { m_button = 0; - const_cast(m_button)->setPaddingLeftToSizeWidth(); + } } QAndroidStyle::AndroidCompoundButtonControl::~AndroidCompoundButtonControl() @@ -1582,16 +1540,24 @@ void QAndroidStyle::AndroidCompoundButtonControl::drawControl(const QStyleOption if (m_button) m_button->draw(p, opt); } -QSize QAndroidStyle::AndroidCompoundButtonControl::sizeCheckBox(const QStyleOption *opt) const + +QMargins QAndroidStyle::AndroidCompoundButtonControl::padding() { - const AndroidDrawable *drawable = m_button; - return static_cast(drawable)->sizeImage(opt); + if (m_button) + return m_button->padding(); + return AndroidControl::padding(); } -QPixmap QAndroidStyle::AndroidCompoundButtonControl::imgCheckBox(const QStyleOption *opt) const + +QSize QAndroidStyle::AndroidCompoundButtonControl::size(const QStyleOption *option) { - const AndroidDrawable *drawable = m_button; - return static_cast(drawable)->img(opt); + if (m_button) { + if (m_button->type() == State) + return static_cast(m_button)->bestAndroidStateMatch(option)->size(); + return m_button->size(); + } + return AndroidControl::size(option); } + const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidCompoundButtonControl::backgroundDrawable() const { return m_background ? m_background : m_button; diff --git a/src/widgets/styles/qandroidstyle_p.h b/src/widgets/styles/qandroidstyle_p.h index 504d43fe96..d8e7768380 100644 --- a/src/widgets/styles/qandroidstyle_p.h +++ b/src/widgets/styles/qandroidstyle_p.h @@ -124,7 +124,6 @@ public: static AndroidDrawable *fromMap(const QVariantMap &drawable, ItemType itemType); static QMargins extractMargins(const QVariantMap &value); virtual void setPaddingLeftToSizeWidth(); - QPixmap img() const; protected: ItemType m_itemType; QMargins m_padding; @@ -149,7 +148,6 @@ public: virtual void draw(QPainter *painter,const QStyleOption *opt) const; virtual QSize size() const; - QPixmap img() const; protected: QString m_filePath; mutable QString m_hashKey; @@ -223,7 +221,6 @@ public: static int extractState(const QVariantMap &value); virtual void setPaddingLeftToSizeWidth(); QSize sizeImage(const QStyleOption *opt) const; - QPixmap img(const QStyleOption *opt) const; private: typedef QPair StateType; QList m_states; @@ -263,6 +260,7 @@ public: const QSize &contentsSize, const QWidget *w) const; virtual QMargins padding(); + virtual QSize size(const QStyleOption *option); protected: virtual const AndroidDrawable * backgroundDrawable() const; const AndroidDrawable *m_background; @@ -276,8 +274,8 @@ public: AndroidCompoundButtonControl(const QVariantMap &control, ItemType itemType); virtual ~AndroidCompoundButtonControl(); virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w); - QSize sizeCheckBox(const QStyleOption *opt) const; - QPixmap imgCheckBox(const QStyleOption *opt) const; + virtual QMargins padding(); + virtual QSize size(const QStyleOption *option); protected: virtual const AndroidDrawable * backgroundDrawable() const; const AndroidDrawable *m_button; From 08afe17731001a87569a17ad0fa9974e9dc88f19 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 14 Nov 2014 13:02:59 +0200 Subject: [PATCH 47/69] Android: Fix QSlider appearance Task-number: QTBUG-42672 Change-Id: I882c1f625ea659967a8db09246dc28d7aef93fdf Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/styles/qandroidstyle.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp index 337da24aee..5b4b346da9 100644 --- a/src/widgets/styles/qandroidstyle.cpp +++ b/src/widgets/styles/qandroidstyle.cpp @@ -1648,7 +1648,6 @@ QRect QAndroidStyle::AndroidProgressBarControl::subElementRect(QStyle::SubElemen p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top()); padding = m_progressDrawable->padding(); p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top()); - QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom()); if (horizontal) { @@ -1731,15 +1730,15 @@ void QAndroidStyle::AndroidSeekBarControl::drawControl(const QStyleOption *optio if (drawable->type() == State) drawable = static_cast(m_seekBarThumb)->bestAndroidStateMatch(option); QStyleOption copy(*option); - copy.rect.setY((copy.rect.height() - m_minSize.height()) / 2); - copy.rect.setHeight(m_minSize.height()); + copy.rect.setHeight(m_progressDrawable->size().height()); copy.rect.setWidth(copy.rect.width() - drawable->size().width()); - copy.rect.translate(drawable->size().width() / 2, 0); + const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2; + copy.rect.translate(drawable->size().width() / 2, yTranslate); m_progressDrawable->draw(p, ©); if (styleOption->orientation == Qt::Vertical) qCritical() << "Vertical slider are not supported"; - int pos = copy.rect.width()*factor - drawable->size().width() / 2; - copy.rect.translate(pos, 0); + int pos = copy.rect.width() * factor - drawable->size().width() / 2; + copy.rect.translate(pos, -yTranslate); copy.rect.setSize(drawable->size()); m_seekBarThumb->draw(p, ©); } From 47c2d76dbab76fc33ca6c73ac701d6814d861f89 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 14 Nov 2014 11:51:49 +0200 Subject: [PATCH 48/69] winrt: Resize window on Windows Phone using EGL To avoid duplicating code in ANGLE, we can resize the framebuffer in QPA. This potentially allows us to synchronize rendering to avoid displaying a frame which is rendered for the new geometry but is displayed with the old geometry. Change-Id: I5f3a0634628d9ea4ca73349a02e646eb043bd757 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 46 ++++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 681307ddcf..fadcd01b06 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -473,6 +473,7 @@ QWinRTScreen::QWinRTScreen() Q_D(QWinRTScreen); d->orientation = Qt::PrimaryOrientation; d->touchDevice = Q_NULLPTR; + d->eglDisplay = EGL_NO_DISPLAY; // Obtain the WinRT Application, view, and window HRESULT hr; @@ -531,8 +532,10 @@ QWinRTScreen::QWinRTScreen() Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->add_PointerWheelChanged(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); Q_ASSERT_SUCCEEDED(hr); +#ifndef Q_OS_WINPHONE hr = d->coreWindow->add_SizeChanged(Callback(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); Q_ASSERT_SUCCEEDED(hr); +#endif hr = d->coreWindow->add_Activated(Callback(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->add_Closed(Callback(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); @@ -610,7 +613,14 @@ QWinRTScreen::QWinRTScreen() d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat); d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat); - d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), NULL); + const QRect bounds = geometry(); + EGLint windowAttributes[] = { + EGL_FIXED_SIZE_ANGLE, EGL_TRUE, + EGL_WIDTH, bounds.width(), + EGL_HEIGHT, bounds.height(), + EGL_NONE + }; + d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), windowAttributes); if (d->eglSurface == EGL_NO_SURFACE) qCritical("Failed to create EGL window surface: 0x%x", eglGetError()); } @@ -1051,26 +1061,33 @@ HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationPr return S_OK; } -HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args) +HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *) { Q_D(QWinRTScreen); - Size size; - HRESULT hr = args->get_Size(&size); - RETURN_OK_IF_FAILED("Failed to get window size."); - + Rect size; + HRESULT hr; + hr = d->coreWindow->get_Bounds(&size); + RETURN_OK_IF_FAILED("Failed to get window bounds"); QSizeF logicalSize = QSizeF(size.Width, size.Height); +#ifndef Q_OS_WINPHONE // This handler is called from orientation changed, in which case we should always update the size if (d->logicalSize == logicalSize) return S_OK; +#endif - // Regardless of state, all top-level windows are viewport-sized - this might change if - // a more advanced compositor is written. d->logicalSize = logicalSize; - const QRect newGeometry = geometry(); - QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry); - QPlatformScreen::resizeMaximizedWindows(); - handleExpose(); - + if (d->eglDisplay) { + const QRect newGeometry = geometry(); +#ifdef Q_OS_WINPHONE // Resize the EGL window + const int width = newGeometry.width() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::LandscapeOrientation ? -1 : 1); + const int height = newGeometry.height() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::InvertedLandscapeOrientation ? -1 : 1); + eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_WIDTH, width); + eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_HEIGHT, height); +#endif + QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry); + QPlatformScreen::resizeMaximizedWindows(); + handleExpose(); + } return S_OK; } @@ -1140,6 +1157,9 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable * QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation); } +#ifdef Q_OS_WINPHONE // The size changed handler is ignored in favor of this callback + onSizeChanged(Q_NULLPTR, Q_NULLPTR); +#endif return S_OK; } From f44eb5c57f28825e29425be339a00df5d99b68eb Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 17 Oct 2014 13:46:37 +0200 Subject: [PATCH 49/69] Doc: Solved link and autolink errs qnamespace.qdoc Task-number: QTBUG-40362 Change-Id: I81166dc3a54427e2d2d81f640162f6c338947849 Reviewed-by: Martin Smith --- src/corelib/global/qnamespace.qdoc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 4e074bcdb5..8d6f7834b0 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -134,7 +134,7 @@ \value AA_MacDontSwapCtrlAndMeta On Mac OS X by default, Qt swaps the Control and Meta (Command) keys (i.e., whenever Control is pressed, Qt sends Meta, and whenever Meta is pressed Control is sent). When this - attribute is true, Qt will not do the flip. QKeySequence::StandardShortcuts + attribute is true, Qt will not do the flip. \l QKeySequence::StandardKey will also flip accordingly (i.e., QKeySequence::Copy will be Command+C on the keyboard regardless of the value set, though what is output for QKeySequence::toString(QKeySequence::PortableText) will be different). @@ -144,7 +144,7 @@ to be consistent in pixels-per-point across devices rather than defining 1 point as 1/72 inch. - \value AA_X11InitThreads Calls XInitThreads() as part of the QApplication + \value AA_X11InitThreads Calls \c XInitThreads() as part of the QApplication construction in order to make Xlib calls thread-safe. This attribute must be set before QApplication is constructed. @@ -159,10 +159,11 @@ \value AA_UseHighDpiPixmaps Make QIcon::pixmap() generate high-dpi pixmaps that can be larger than the requested size. Such pixmaps will have - devicePixelRatio set to a value higher than 1. After setting this - attribute application code that uses pixmap sizes in layout geometry - calculations should typically divide by QPixmap::devicePixelRatio() - to get device-independent layout geometry. + \l {QPixmap::devicePixelRatio}{devicePixelRatio()} set to a value higher than 1. + + After setting this attribute, application code that uses pixmap + sizes in layout geometry calculations should typically divide by + \l {QPixmap::devicePixelRatio}{devicePixelRatio()} to get device-independent layout geometry. \value AA_ForceRasterWidgets Make top-level widgets use pure raster surfaces, and do not support non-native GL-based child widgets. @@ -182,7 +183,7 @@ \l{http://www.mesa3d.org/llvmpipe.html}{Mesa llvmpipe}, providing OpenGL 2.1. The value may have no effect if no such OpenGL implementation is available. The default name of this library is - opengl32sw.dll and can be overridden by setting the environment + \c opengl32sw.dll and can be overridden by setting the environment variable \e QT_OPENGL_DLL. See the platform-specific pages, for instance \l{Qt for Windows}, for more information. This value has been added in Qt 5.4. @@ -221,7 +222,7 @@ \value AllButtons This value corresponds to a mask of all possible mouse buttons. Use to set the 'acceptedButtons' - property of a mouseArea to accept ALL mouse buttons. + property of a MouseArea to accept ALL mouse buttons. \value LeftButton The left button is pressed, or an event refers to the left button. (The left button may be the right button on @@ -2443,7 +2444,7 @@ \value ImhExclusiveInputMask This mask yields nonzero if any of the exclusive flags are used. - \note If several exclusive flags are ORed together, the resulting character set will + \note If several exclusive flags are OR-ed together, the resulting character set will consist of the union of the specified sets. For instance specifying \c ImhNumbersOnly and \c ImhUppercaseOnly would yield a set consisting of numbers and uppercase letters. @@ -2969,8 +2970,8 @@ This enum provides additional information concerning a QMouseEvent. \value MouseEventCreatedDoubleClick Indicates that Qt has created a - MouseButtonDblClick event from this event. The flag is set in the causing - MouseButtonPress, and not in the resulting MouseButtonDblCLick. + \l {QEvent::MouseButtonDblClick}{MouseButtonDblClick} event from this event. The flag is set in the causing + \l {QEvent::MouseButtonPress}{MouseButtonPress}, and not in the resulting \l {QEvent::MouseButtonDblClick}{MouseButtonDblClick}. \omitvalue MouseEventFlagMask */ From 0600f7d6299a21014f1b72d54fc6b23c02693204 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 14 Nov 2014 14:15:04 +0400 Subject: [PATCH 50/69] Fix hb_face leaking in QFontEngineFT Since HarfBuzz-old's HB_Face doesn't support ref-counting, it is impossible to keep the same behavior as for NG's ref-counted hb_face when we're going to reparent the data of unknown type in QFontEngineFT. We should either not release the object returned by harfbuzzFace(), or introduce ref-counting for HB-old's HB_Face. Stop referencing HB-NG's objects on access for now and thus avoid a need to release them manually. Task-number: QTBUG-42674 Change-Id: Ia21e7ba9c17185796b0dd98c2c27d02566f2a701 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine.cpp | 2 -- src/gui/text/qharfbuzzng.cpp | 6 ++---- src/gui/text/qtextengine.cpp | 2 -- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 52e10bd717..0b517fbf29 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -373,8 +373,6 @@ bool QFontEngine::supportsScript(QChar::Script script) const if (!ret && script_tag_2 != HB_OT_TAG_DEFAULT_SCRIPT) ret = hb_ot_layout_table_find_script(face, HB_OT_TAG_GSUB, HB_OT_TAG_DEFAULT_SCRIPT, &script_index); } - - hb_face_destroy(face); } return ret; } diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index eb7bca1974..16c45e642b 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -632,7 +632,7 @@ hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe) fe->face_destroy_func = _hb_qt_face_release; } - return hb_face_reference((hb_face_t *)fe->face_); + return (hb_face_t *)fe->face_; } @@ -645,8 +645,6 @@ _hb_qt_font_create(QFontEngine *fe) hb_font_t *font = hb_font_create(face); - hb_face_destroy(face); // ref-ed in hb_qt_face_get_for_engine() - if (Q_UNLIKELY(hb_font_is_immutable(font))) { hb_font_destroy(font); return NULL; @@ -684,7 +682,7 @@ hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe) fe->font_destroy_func = _hb_qt_font_release; } - return hb_font_reference((hb_font_t *)fe->font_); + return (hb_font_t *)fe->font_; } QT_END_NAMESPACE diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 9fe1fd26e9..d156124b98 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1168,8 +1168,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st }; const int num_features = 1; shapedOk = hb_shape_full(hb_font, buffer, features, num_features, 0); - - hb_font_destroy(hb_font); } if (!shapedOk) { hb_buffer_destroy(buffer); From 2b9ae07ca3fef1178b63d5052c33edf6b5551f5c Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 13 Nov 2014 15:43:08 +0200 Subject: [PATCH 51/69] Android: Extract VectorDrawable Task-numer: QTBUG-42488 Change-Id: Iacc9e6afc75f1f480ba8119c9cbd481beb1d1089 Reviewed-by: J-P Nurmi Reviewed-by: BogDan Vatra --- .../qtproject/qt5/android/ExtractStyle.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index 4dbc33057b..a8583cde17 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -99,6 +99,7 @@ public class ExtractStyle { Class styleableClass = getClass("android.R$styleable"); Class rippleDrawableClass = getClass("android.graphics.drawable.RippleDrawable"); Class animatedStateListDrawableClass = getClass("android.graphics.drawable.AnimatedStateListDrawable"); + Class vectorDrawableClass = getClass("android.graphics.drawable.VectorDrawable"); final int[] EMPTY_STATE_SET = {}; final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled}; @@ -410,6 +411,24 @@ public class ExtractStyle { return null; } + Field tryGetAccessibleField(Class clazz, String fieldName) { + if (clazz == null) + return null; + + try { + Field f = clazz.getDeclaredField(fieldName); + f.setAccessible(true); + return f; + } catch (Exception e) { + for (Class c : clazz.getInterfaces()) { + Field f = tryGetAccessibleField(c, fieldName); + if (f != null) + return f; + } + } + return tryGetAccessibleField(clazz.getSuperclass(), fieldName); + } + int getField(Class clazz, String fieldName) { try { @@ -873,6 +892,95 @@ public class ExtractStyle { return json; } + private JSONObject getVPath(Object path) throws Exception + { + JSONObject json = new JSONObject(); + final Class pathClass = path.getClass(); + json.put("type", "path"); + json.put("name", tryGetAccessibleField(pathClass, "mPathName").get(path)); + Object[] mNodes = (Object[]) tryGetAccessibleField(pathClass, "mNodes").get(path); + JSONArray nodes = new JSONArray(); + for (Object n: mNodes) { + JSONObject node = new JSONObject(); + node.put("type", String.valueOf(getAccessibleField(n.getClass(), "mType").getChar(n))); + node.put("params", getJsonArray((float[])getAccessibleField(n.getClass(), "mParams").get(n))); + nodes.put(node); + } + json.put("nodes", nodes); + json.put("isClip", (Boolean) pathClass.getMethod("isClipPath").invoke(path)); + + if (tryGetAccessibleField(pathClass, "mStrokeColor") == null) + return json; // not VFullPath + + json.put("strokeColor", getAccessibleField(pathClass, "mStrokeColor").getInt(path)); + json.put("strokeWidth", getAccessibleField(pathClass, "mStrokeWidth").getFloat(path)); + json.put("fillColor", getAccessibleField(pathClass, "mFillColor").getInt(path)); + json.put("strokeAlpha", getAccessibleField(pathClass, "mStrokeAlpha").getFloat(path)); + json.put("fillRule", getAccessibleField(pathClass, "mFillRule").getInt(path)); + json.put("fillAlpha", getAccessibleField(pathClass, "mFillAlpha").getFloat(path)); + json.put("trimPathStart", getAccessibleField(pathClass, "mTrimPathStart").getFloat(path)); + json.put("trimPathEnd", getAccessibleField(pathClass, "mTrimPathEnd").getFloat(path)); + json.put("trimPathOffset", getAccessibleField(pathClass, "mTrimPathOffset").getFloat(path)); + json.put("strokeLineCap", (Paint.Cap) getAccessibleField(pathClass, "mStrokeLineCap").get(path)); + json.put("strokeLineJoin", (Paint.Join) getAccessibleField(pathClass, "mStrokeLineJoin").get(path)); + json.put("strokeMiterlimit", getAccessibleField(pathClass, "mStrokeMiterlimit").getFloat(path)); + return json; + } + + @SuppressWarnings("unchecked") + private JSONObject getVGroup(Object group) throws Exception + { + JSONObject json = new JSONObject(); + json.put("type", "group"); + final Class groupClass = group.getClass(); + json.put("name", getAccessibleField(groupClass, "mGroupName").get(group)); + json.put("rotate", getAccessibleField(groupClass, "mRotate").getFloat(group)); + json.put("pivotX", getAccessibleField(groupClass, "mPivotX").getFloat(group)); + json.put("pivotY", getAccessibleField(groupClass, "mPivotY").getFloat(group)); + json.put("scaleX", getAccessibleField(groupClass, "mScaleX").getFloat(group)); + json.put("scaleY", getAccessibleField(groupClass, "mScaleY").getFloat(group)); + json.put("translateX", getAccessibleField(groupClass, "mTranslateX").getFloat(group)); + json.put("translateY", getAccessibleField(groupClass, "mTranslateY").getFloat(group)); + + ArrayList mChildren = (ArrayList) getAccessibleField(groupClass, "mChildren").get(group); + JSONArray children = new JSONArray(); + for (Object c: mChildren) { + if (groupClass.isInstance(c)) + children.put(getVGroup(c)); + else + children.put(getVPath(c)); + } + json.put("children", children); + return json; + } + + private JSONObject getVectorDrawable(Object drawable, String filename, Rect padding) + { + JSONObject json = new JSONObject(); + try { + json.put("type", "vector"); + final Object state = getAccessibleField(vectorDrawableClass, "mVectorState").get(drawable); + final Class stateClass = state.getClass(); + final ColorStateList mTint = (ColorStateList) getAccessibleField(stateClass, "mTint").get(state); + if (mTint != null) { + json.put("tintList", getColorStateList(mTint)); + json.put("tintMode", (PorterDuff.Mode) getAccessibleField(stateClass, "mTintMode").get(state)); + } + final Object mVPathRenderer = getAccessibleField(stateClass, "mVPathRenderer").get(state); + final Class VPathRendererClass = mVPathRenderer.getClass(); + json.put("baseWidth", getAccessibleField(VPathRendererClass, "mBaseWidth").getFloat(mVPathRenderer)); + json.put("baseHeight", getAccessibleField(VPathRendererClass, "mBaseHeight").getFloat(mVPathRenderer)); + json.put("viewportWidth", getAccessibleField(VPathRendererClass, "mViewportWidth").getFloat(mVPathRenderer)); + json.put("viewportHeight", getAccessibleField(VPathRendererClass, "mViewportHeight").getFloat(mVPathRenderer)); + json.put("rootAlpha", getAccessibleField(VPathRendererClass, "mRootAlpha").getInt(mVPathRenderer)); + json.put("rootName", getAccessibleField(VPathRendererClass, "mRootName").get(mVPathRenderer)); + json.put("rootGroup", getVGroup(getAccessibleField(mVPathRenderer.getClass(), "mRootGroup").get(mVPathRenderer))); + } catch(Exception e) { + e.printStackTrace(); + } + return json; + } + public JSONObject getDrawable(Object drawable, String filename, Rect padding) { if (drawable == null) @@ -922,6 +1030,9 @@ public class ExtractStyle { if (animatedStateListDrawableClass != null && animatedStateListDrawableClass.isInstance(drawable)) return getAnimatedStateListDrawable(drawable, filename); + if (vectorDrawableClass != null && vectorDrawableClass.isInstance(drawable)) + return getVectorDrawable(drawable, filename, padding); + if (drawable instanceof ScaleDrawable) { return getDrawable(((ScaleDrawable)drawable).getDrawable(), filename, null); From db31a5009af21719c040b7f203c32fd821ae011e Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 11 Nov 2014 14:17:27 +0100 Subject: [PATCH 52/69] WinRT: Fill data in QUdpSocket::readDatagram There was still a TODO left in there and the data was never filled. In addition to filling the data, some pointer checks for addr and port were added. Task-number: QTBUG-42244 Change-Id: I8e358b5544edcdb4077a52f433e4bc17d92014ce Reviewed-by: Andrew Knight --- .../socket/qnativesocketengine_winrt.cpp | 88 ++++++++++--------- .../socket/qnativesocketengine_winrt_p.h | 9 +- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index c3be3eb408..cacfe11fea 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -529,41 +529,27 @@ qint64 QNativeSocketEngine::write(const char *data, qint64 len) qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr, quint16 *port) { Q_D(QNativeSocketEngine); - if (d->socketType != QAbstractSocket::UdpSocket) + if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty()) return -1; - QHostAddress returnAddress; - quint16 returnPort; + WinRtDatagram datagram = d->pendingDatagrams.takeFirst(); + if (addr) + *addr = datagram.address; - for (int i = 0; i < d->pendingDatagrams.size(); ++i) { - IDatagramSocketMessageReceivedEventArgs *arg = d->pendingDatagrams.at(i); - ComPtr remoteHost; - HString remoteHostString; - HString remotePort; - arg->get_RemoteAddress(&remoteHost); - arg->get_RemotePort(remotePort.GetAddressOf()); - remoteHost->get_CanonicalName(remoteHostString.GetAddressOf()); - returnAddress.setAddress(qt_QStringFromHString(remoteHostString)); - returnPort = qt_QStringFromHString(remotePort).toInt(); - ComPtr reader; - arg->GetDataReader(&reader); - if (!reader) - continue; + if (port) + *port = datagram.port; - BYTE buffer[1024]; - reader->ReadBytes(maxlen, buffer); - *addr = returnAddress; - *port = returnPort; - arg = d->pendingDatagrams.takeFirst(); - arg->Release(); - - // TODO: fill data - Q_UNUSED(data); - --i; - return maxlen; + QByteArray readOrigin; + // Do not read the whole datagram. Put the rest of it back into the "queue" + if (maxlen < datagram.data.length()) { + QByteArray readOrigin = datagram.data.left(maxlen); + datagram.data = datagram.data.remove(0, maxlen); + d->pendingDatagrams.prepend(datagram); + } else { + readOrigin = datagram.data; } - - return -1; + strcpy(data, readOrigin); + return readOrigin.length(); } qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QHostAddress &addr, quint16 port) @@ -609,17 +595,10 @@ bool QNativeSocketEngine::hasPendingDatagrams() const qint64 QNativeSocketEngine::pendingDatagramSize() const { Q_D(const QNativeSocketEngine); - qint64 ret = 0; - foreach (IDatagramSocketMessageReceivedEventArgs *arg, d->pendingDatagrams) { - ComPtr reader; - UINT32 unconsumedBufferLength; - arg->GetDataReader(&reader); - if (!reader) - return -1; - reader->get_UnconsumedBufferLength(&unconsumedBufferLength); - ret += unconsumedBufferLength; - } - return ret; + if (d->pendingDatagrams.isEmpty()) + return -1; + + return d->pendingDatagrams.at(0).data.length(); } qint64 QNativeSocketEngine::bytesToWrite() const @@ -1236,7 +1215,32 @@ HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, I { Q_Q(QNativeSocketEngine); Q_UNUSED(socket); - pendingDatagrams.append(args); + + WinRtDatagram datagram; + QHostAddress returnAddress; + ComPtr remoteHost; + HRESULT hr = args->get_RemoteAddress(&remoteHost); + RETURN_OK_IF_FAILED("Could not obtain remote host"); + HString remoteHostString; + remoteHost->get_CanonicalName(remoteHostString.GetAddressOf()); + RETURN_OK_IF_FAILED("Could not obtain remote host's canonical name"); + returnAddress.setAddress(qt_QStringFromHString(remoteHostString)); + datagram.address = returnAddress; + HString remotePort; + hr = args->get_RemotePort(remotePort.GetAddressOf()); + RETURN_OK_IF_FAILED("Could not obtain remote port"); + datagram.port = qt_QStringFromHString(remotePort).toInt(); + + ComPtr reader; + hr = args->GetDataReader(&reader); + RETURN_OK_IF_FAILED("Could not obtain data reader"); + quint32 length; + hr = reader->get_UnconsumedBufferLength(&length); + RETURN_OK_IF_FAILED("Could not obtain unconsumed buffer length"); + datagram.data.resize(length); + hr = reader->ReadBytes(length, reinterpret_cast(datagram.data.data())); + RETURN_OK_IF_FAILED("Could not read datagram"); + pendingDatagrams.append(datagram); emit q->readReady(); return S_OK; diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 7652a09b17..716403097d 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -55,6 +55,12 @@ QT_BEGIN_NAMESPACE class QNativeSocketEnginePrivate; +struct WinRtDatagram { + QByteArray data; + int port; + QHostAddress address; +}; + class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine { Q_OBJECT @@ -197,7 +203,8 @@ private: Microsoft::WRL::ComPtr connectOp; QBuffer readBytes; QMutex readMutex; - QList pendingDatagrams; + + QList pendingDatagrams; QList pendingConnections; QList currentConnections; QEventLoop eventLoop; From 32bc5f01c416a4a54fd0ff3835bd5d500707bce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 14 Nov 2014 17:03:57 +0100 Subject: [PATCH 53/69] Revert "Build Qt for OS X and iOS with relative rpath" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The change was made too late in the 5.4.0 release cycle, and broke the Qt build and deployment in several areas: - macdeployqt - OS X 10.7 builds - shadow builds This reverts commit c0a54efc4091b365ffac09fc2827cf92f849d698. Change-Id: I1c1ad4901228f5516352ccdfa963e8ea2b5013b6 Reviewed-by: Morten Johan Sørvig Reviewed-by: Gabriel de Dietrich --- configure | 6 +++++- mkspecs/features/qt_build_config.prf | 6 ++++++ mkspecs/features/qt_module.prf | 3 --- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 979e32e050..1a002b4081 100755 --- a/configure +++ b/configure @@ -5784,7 +5784,11 @@ fi [ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES" [ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS" -if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then +if [ "$XPLATFORM_MAC" = "yes" ] && [ "$QT_CROSS_COMPILE" = "no" ]; then + if [ "$CFG_RPATH" = "yes" ]; then + QMAKE_CONFIG="$QMAKE_CONFIG absolute_library_soname" + fi +elif [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then if [ -n "$RPATH_FLAGS" ]; then echo echo "ERROR: -R cannot be used on this platform as \$QMAKE_LFLAGS_RPATH is" diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index 7197f84c9a..42046c238a 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -52,6 +52,12 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR unset(modpath) } +mac { + !isEmpty(QMAKE_RPATHDIR){ + CONFIG += absolute_library_soname + } +} + cross_compile: \ CONFIG += force_bootstrap diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 7d47caef46..8599a47ecd 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -111,9 +111,6 @@ mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) { } } -mac:contains(QT_CONFIG, rpath): \ - QMAKE_SONAME_PREFIX = @rpath - mac { CONFIG += explicitlib macx-g++ { From e4d9102805e2e733d00a3de926ef97337e6d58cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 13 Nov 2014 14:20:32 +0100 Subject: [PATCH 54/69] Set CFBundleIdentifier prefix for Qt frameworks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This sets the prefix for frameworks to "org.qt-project". Applications keep using the default Xcode preferences prefix. Task-number: QTBUG-32896 Change-Id: I67384f643888f2de3dd8e36b9bce0f04ca4e16dd Reviewed-by: Tor Arne Vestbø --- mkspecs/features/qt_module.prf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 8599a47ecd..d213f9e260 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -94,6 +94,8 @@ else: \ # OS X and iOS frameworks mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) { + # Set the CFBundleIdentifier prefix for Qt frameworks + QMAKE_TARGET_BUNDLE_PREFIX = org.qt-project #QMAKE_FRAMEWORK_VERSION = 4.0 CONFIG += lib_bundle sliced_bundle qt_framework CONFIG -= qt_install_headers #no need to install these as well From 40a4e446f37ee49783227d80fa1d805c8cab2463 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 17 Nov 2014 15:10:10 +0100 Subject: [PATCH 55/69] ANGLE: Fix compilation with D3D9 Fixes a regression introduced in c6df5fe3ed0f2a722 that broke compilation with d3d9 (namely, -target xp). Task-number: QTBUG-42714 Change-Id: I1a5e9682d5463bfa082a5d0c062399a131a7cf52 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/src/common/NativeWindow.h | 7 ++- src/3rdparty/angle/src/common/platform.h | 1 + .../angle/src/common/win32/NativeWindow.cpp | 2 +- ...0017-ANGLE-Fix-compilation-with-D3D9.patch | 62 +++++++++++++++++++ 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h index 9e93aeacde..c4a0e42bcc 100644 --- a/src/3rdparty/angle/src/common/NativeWindow.h +++ b/src/3rdparty/angle/src/common/NativeWindow.h @@ -54,7 +54,12 @@ public: bool getClientRect(LPRECT rect); bool isIconic(); - HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, +# if defined(ANGLE_ENABLE_D3D11) + typedef ID3D11Device Device; +#else + typedef IDirect3DDevice9 Device; +#endif + HRESULT createSwapChain(Device* device, DXGIFactory* factory, DXGI_FORMAT format, UINT width, UINT height, DXGISwapChain** swapChain); diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h index 0001e7142e..5bf97f9184 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h @@ -52,6 +52,7 @@ # if defined(ANGLE_ENABLE_D3D9) # include +# include # if !defined(COMPILER_IMPLEMENTATION) # include # endif diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp index 2440747260..46082a2e28 100644 --- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp +++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp @@ -35,7 +35,7 @@ bool NativeWindow::isIconic() return IsIconic(mWindow) == TRUE; } -HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, +HRESULT NativeWindow::createSwapChain(NativeWindow::Device* device, DXGIFactory* factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain** swapChain) { diff --git a/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch b/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch new file mode 100644 index 0000000000..4ada6d41d2 --- /dev/null +++ b/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch @@ -0,0 +1,62 @@ +From d7839cc052de126cc3b457fe41963fd9c7e91846 Mon Sep 17 00:00:00 2001 +From: Kai Koehne +Date: Mon, 17 Nov 2014 15:10:10 +0100 +Subject: [PATCH] ANGLE: Fix compilation with D3D9 + +Fixes a regression introduced in c6df5fe3ed0f2a722 that +broke compilation with d3d9 (namely, -target xp). + +Task-number: QTBUG-42714 +Change-Id: I1a5e9682d5463bfa082a5d0c062399a131a7cf52 +--- + src/3rdparty/angle/src/common/NativeWindow.h | 7 ++++++- + src/3rdparty/angle/src/common/platform.h | 1 + + src/3rdparty/angle/src/common/win32/NativeWindow.cpp | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h +index 9e93aea..c4a0e42 100644 +--- a/src/3rdparty/angle/src/common/NativeWindow.h ++++ b/src/3rdparty/angle/src/common/NativeWindow.h +@@ -54,7 +54,12 @@ public: + bool getClientRect(LPRECT rect); + bool isIconic(); + +- HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, ++# if defined(ANGLE_ENABLE_D3D11) ++ typedef ID3D11Device Device; ++#else ++ typedef IDirect3DDevice9 Device; ++#endif ++ HRESULT createSwapChain(Device* device, DXGIFactory* factory, + DXGI_FORMAT format, UINT width, UINT height, + DXGISwapChain** swapChain); + +diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h +index 0001e71..5bf97f9 100644 +--- a/src/3rdparty/angle/src/common/platform.h ++++ b/src/3rdparty/angle/src/common/platform.h +@@ -52,6 +52,7 @@ + + # if defined(ANGLE_ENABLE_D3D9) + # include ++# include + # if !defined(COMPILER_IMPLEMENTATION) + # include + # endif +diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp +index 2440747..46082a2 100644 +--- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp ++++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp +@@ -35,7 +35,7 @@ bool NativeWindow::isIconic() + return IsIconic(mWindow) == TRUE; + } + +-HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, ++HRESULT NativeWindow::createSwapChain(NativeWindow::Device* device, DXGIFactory* factory, + DXGI_FORMAT format, unsigned int width, unsigned int height, + DXGISwapChain** swapChain) + { +-- +1.9.4.msysgit.0 + From 8aa2ae3e0e1f07c7dbb43790e35d9c87ec148bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 17 Nov 2014 15:00:45 +0100 Subject: [PATCH 56/69] iOS: Tell Xcode to not build universal app binaries for debug builds You're likely to only target/develop on one device at a time, so we only need to build for one architecture at a time. Switching device in Xcode will switch the active architecture as well, so the only case where you'll need a universal debug build is if you are creating a debug package for testers. Change-Id: I4f37f5c982082c42836749d1e9fbe5ef91138912 Reviewed-by: Oswald Buddenhagen Reviewed-by: Richard Moe Gustavsen --- mkspecs/macx-ios-clang/features/default_post.prf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 0245c948d9..643a17e23e 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -202,6 +202,11 @@ macx-xcode { QMAKE_MAC_XCODE_SETTINGS += arch_iphoneos arch_iphonesimulator QMAKE_XCODE_ARCHS = $$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS + + only_active_arch.name = ONLY_ACTIVE_ARCH + only_active_arch.value = YES + only_active_arch.build = debug + QMAKE_MAC_XCODE_SETTINGS += only_active_arch } else { # Be more specific about which architecture we're targeting contains(QT_ARCH, arm.*): \ From 41f8d1f393f049f31648bd9fa7eb7ad357fe2d7b Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 17 Nov 2014 13:43:24 +0100 Subject: [PATCH 57/69] Fix wrong qversionnumber header name in tools.pri Change-Id: Ie571ca0dc1720bcd04e492697e93f866b1877a5b Reviewed-by: Keith Gardner Reviewed-by: Oswald Buddenhagen --- src/corelib/tools/tools.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index af0ed228bd..cef802fa76 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -71,7 +71,7 @@ HEADERS += \ tools/qunicodetools_p.h \ tools/qvarlengtharray.h \ tools/qvector.h \ - tools/qversionnumber.h + tools/qversionnumber_p.h SOURCES += \ From e37a69252eb7c564fd888361b3672cfc31eca949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Mon, 17 Nov 2014 18:41:05 +0100 Subject: [PATCH 58/69] Fix memcpy with incorrect destination Variable dsa is assigned in this block with q_DSA_new instead of rsa. So this should be the destination of memcpy. Change-Id: Id5a41d99f1606bf525ad5f819bbc06bb1235bf5b Reviewed-by: Richard J. Moore --- src/network/ssl/qsslkey_openssl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index 6b0fa954eb..e4d30ff229 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -95,7 +95,7 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey) type = QSsl::PrivateKey; dsa = q_DSA_new(); - memcpy(rsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA)); + memcpy(dsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA)); return true; } From e86f1ceaedba24187747ab6b1d4b4712fbcca137 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 13 Nov 2014 15:23:27 +0100 Subject: [PATCH 59/69] qdoc: Missing break in qdoc switch statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a missing break statement in the function that generates the .index file, which caused qdoc to output extra attributes in the element. Change-Id: I110c15c67a228249bfe0c7da138f2ca0b4921371 Task-number: QTBUG-42625 Reviewed-by: Topi Reiniö --- src/tools/qdoc/qdocindexfiles.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp index 7445292a56..00041b2b65 100644 --- a/src/tools/qdoc/qdocindexfiles.cpp +++ b/src/tools/qdoc/qdocindexfiles.cpp @@ -980,6 +980,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, if (!brief.isEmpty()) writer.writeAttribute("brief", brief); } + break; case Node::QmlModule: { const QmlModuleNode* qmn = static_cast(node); From 6dac557fd3b9c913f1bc8b863bb676fc46df4b05 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 19 Nov 2014 12:05:27 +0100 Subject: [PATCH 60/69] Correct the signature and access rights for the protected constructor Change-Id: Ic43398a82777f3b1a95a36f60ebc4338d60c29ec Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglpaintdevice.cpp | 4 ++-- src/gui/opengl/qopenglpaintdevice.h | 2 +- src/widgets/kernel/qopenglwidget.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index e908fd8e91..a08d26f708 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -138,8 +138,8 @@ QOpenGLPaintDevice::QOpenGLPaintDevice(int width, int height) /*! \internal */ -QOpenGLPaintDevice::QOpenGLPaintDevice(QOpenGLPaintDevicePrivate *dd) - : d_ptr(dd) +QOpenGLPaintDevice::QOpenGLPaintDevice(QOpenGLPaintDevicePrivate &dd) + : d_ptr(&dd) { } diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h index dda3bfe43f..10cee842ab 100644 --- a/src/gui/opengl/qopenglpaintdevice.h +++ b/src/gui/opengl/qopenglpaintdevice.h @@ -53,7 +53,6 @@ public: QOpenGLPaintDevice(); explicit QOpenGLPaintDevice(const QSize &size); QOpenGLPaintDevice(int width, int height); - QOpenGLPaintDevice(QOpenGLPaintDevicePrivate *dd); virtual ~QOpenGLPaintDevice(); int devType() const { return QInternal::OpenGL; } @@ -76,6 +75,7 @@ public: virtual void ensureActiveTarget(); protected: + QOpenGLPaintDevice(QOpenGLPaintDevicePrivate &dd); int metric(QPaintDevice::PaintDeviceMetric metric) const; Q_DISABLE_COPY(QOpenGLPaintDevice) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 8a4e0c8ffd..23bb1f7050 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -471,7 +471,7 @@ class QOpenGLWidgetPaintDevice : public QOpenGLPaintDevice { public: QOpenGLWidgetPaintDevice(QOpenGLWidget *widget) - : QOpenGLPaintDevice(new QOpenGLWidgetPaintDevicePrivate(widget)) { } + : QOpenGLPaintDevice(*new QOpenGLWidgetPaintDevicePrivate(widget)) { } void ensureActiveTarget() Q_DECL_OVERRIDE; }; From 242f1c2d63dd5f3381f13d46bdb08ccaba18ac1f Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Tue, 18 Nov 2014 15:18:05 +0100 Subject: [PATCH 61/69] Fix QtCreator debugging on Android 5.0 devices Add a socket based handshake method for gdb. The previous file based method remains for now and can be activated from Qt creator. It will be used by older creator builds but has the limitation of not working on 5.0 devices. The new mechanism works on pre 5.0 devices too. Task-number: QTCREATORBUG-13418 Change-Id: Ia3ecd1b144b544f52d90940ca885653bcbc477ac Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../qt5/android/QtActivityDelegate.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index cab5da9dbc..12b606b89f 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -72,10 +72,16 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import java.io.BufferedReader; +import java.io.DataOutputStream; import java.io.File; import java.io.FileWriter; +import java.io.InputStreamReader; import java.io.IOException; import java.lang.reflect.Method; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -488,6 +494,53 @@ public class QtActivityDelegate Log.i(QtNative.QtTAG, "DEBUGGER: " + msg); } + private class DebugWaitRunnable implements Runnable { + + public DebugWaitRunnable(int socketPort) throws IOException { + socket = new ServerSocket(socketPort); + } + + public boolean wasFailure; + private ServerSocket socket; + + public void run() { + final int napTime = 200; // milliseconds between file accesses + final int timeOut = 30000; // ms until we give up on ping and pong + final int maxAttempts = timeOut / napTime; + + try { + socket.setSoTimeout(timeOut); + debugLog("Waiting for debug socket on port: " + socket.getLocalPort()); + Socket connectionFromClient = socket.accept(); + debugLog("Debug socket accepted"); + BufferedReader inFromClient = + new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream())); + DataOutputStream outToClient = new DataOutputStream(connectionFromClient.getOutputStream()); + outToClient.writeBytes("" + android.os.Process.myPid()); + + for (int i = 0; i < maxAttempts; i++) { + String clientData = inFromClient.readLine(); + debugLog("Incoming socket " + clientData); + if (!clientData.isEmpty()) + break; + + if (socket.isClosed()) { + wasFailure = true; + break; + } + Thread.sleep(napTime); + } + } catch (IOException ioEx) { + ioEx.printStackTrace(); + wasFailure = true; + Log.e(QtNative.QtTAG,"Can't start debugger" + ioEx.getMessage()); + } catch (InterruptedException interruptEx) { + wasFailure = true; + Log.e(QtNative.QtTAG,"Can't start debugger" + interruptEx.getMessage()); + } + } + }; + public boolean startApplication() { // start application @@ -544,9 +597,17 @@ public class QtActivityDelegate String pongFile = extras.getString("pong_file"); String gdbserverSocket = extras.getString("gdbserver_socket"); String gdbserverCommand = extras.getString("gdbserver_command"); + String pingViaSocket = extras.getString("ping_socketport"); boolean usePing = pingFile != null; boolean usePong = pongFile != null; boolean useSocket = gdbserverSocket != null; + int pingSocket = 0; + if (pingViaSocket != null) { + try { + pingSocket = Integer.parseInt(pingViaSocket); + } catch (NumberFormatException ignored) { } + } + boolean usePingViaSocket = (pingViaSocket != null && pingSocket > 0); int napTime = 200; // milliseconds between file accesses int timeOut = 30000; // ms until we give up on ping and pong int maxAttempts = timeOut / napTime; @@ -602,6 +663,20 @@ public class QtActivityDelegate debugLog("socket not used"); } + if (usePingViaSocket) { + DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket); + Thread waitThread = new Thread(runnable); + waitThread.start(); + waitThread.join(); + + if (runnable.wasFailure) { + debugLog("Could not connect to debug client"); + return false; + } else { + debugLog("Got pid acknowledgment"); + } + } + if (usePing) { // Tell we are ready. debugLog("writing ping at " + pingFile); From 52ea96db06d5ecb070dfd1e4fcf30c0c186ec906 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 18 Nov 2014 15:53:18 +0100 Subject: [PATCH 62/69] Doc: Added brief statement to group definition Groups: richtext and sharing. Task-number: QTBUG-42682 Change-Id: I46bd7e5bba0f665519ee4f3c033b971f0836e314 Reviewed-by: Martin Smith --- src/corelib/doc/src/implicit-sharing.qdoc | 1 + src/corelib/doc/src/statemachine.qdoc | 1 + src/gui/doc/src/richtext.qdoc | 1 + 3 files changed, 3 insertions(+) diff --git a/src/corelib/doc/src/implicit-sharing.qdoc b/src/corelib/doc/src/implicit-sharing.qdoc index 1185fe8348..ec8edb4b6b 100644 --- a/src/corelib/doc/src/implicit-sharing.qdoc +++ b/src/corelib/doc/src/implicit-sharing.qdoc @@ -30,6 +30,7 @@ /*! \group shared + \brief How to maximize resource usage by implicit data sharing. \title Implicitly Shared Classes These \l{Qt Core} classes provides a safe and efficient way of sharing and diff --git a/src/corelib/doc/src/statemachine.qdoc b/src/corelib/doc/src/statemachine.qdoc index b281eb177b..846eb7d1f0 100644 --- a/src/corelib/doc/src/statemachine.qdoc +++ b/src/corelib/doc/src/statemachine.qdoc @@ -27,6 +27,7 @@ /*! \group statemachine + \brief How to create and execute state graphs. \title State Machine Classes These \l{Qt Core} classes are part of the \l{The State Machine Framework}{ diff --git a/src/gui/doc/src/richtext.qdoc b/src/gui/doc/src/richtext.qdoc index 90248298d6..460018a52e 100644 --- a/src/gui/doc/src/richtext.qdoc +++ b/src/gui/doc/src/richtext.qdoc @@ -27,6 +27,7 @@ /*! \group richtext-processing + \brief How to use Rich Text Processing APIs. \title Rich Text Processing APIs */ From efeb15f3065ab01a3eed483385fa0421f617eb10 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 17 Nov 2014 15:01:35 +0100 Subject: [PATCH 63/69] add buildsystem changelog for 5.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I22ac7dc475fccb3c71e3f514fb58045062a1a95b Reviewed-by: Tor Arne Vestbø Reviewed-by: Thiago Macieira --- dist/changes-5.4.0 | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/dist/changes-5.4.0 b/dist/changes-5.4.0 index 927ca0f9f1..614f57afe2 100644 --- a/dist/changes-5.4.0 +++ b/dist/changes-5.4.0 @@ -43,3 +43,46 @@ OS X - OS X 10.10 is now supported. - QMacStyle has been updated with better OS 10.10 support. - The Qt binary packages are now configured with C++11 enabled. + +Windows +------- + + - [QTBUG-38259] Changed configure defaults so that Qt5Core does not + link against ICU libraries anymore. Pass '-icu' to enable it. + +**************************************************************************** +* Tools * +**************************************************************************** + +configure & build system +------------------------ + + - The -process/-fully-process/-dont-process configure options have been + removed due to being unnecessary and counterproductive. + - [QTBUG-36955] The -vcproj configure option was removed. Use "qmake -r -tp vc" + _after_ building Qt in case you want to use Visual Studio to work on Qt. + - [QTBUG-37961] Qt plugins contain version info again. + - [QTBUG-39216] Fixed more cases where the Qt build would pick up headers + from a pre-existing Qt installation. + - [QTBUG-41267] Fixed parallelized (jom) -debug-and-release builds. + +qmake +----- + + - [QTBUG-21910][Unix] Added 'make dist' target for SUBDIRS projects. + - [QTBUG-32895][iOS] Fixed structure of bundles. They can be signed now. + - [QTBUG-26782][VS] Fixed handling of TARGET_EXT. + - [QTBUG-30712][VS] Fixed handling of QMAKE_LIBFLAGS. + - [QTBUG-30373][VS] Using different RESOURCES in different build variants + no longer produces invalid vcxproj files. + - [QTBUG-37520][VS] Made it possible to suppress qmake warnings about + unknown compiler options. CONFIG+=suppress_vcproj_warnings. + - [QTBUG-37363][MSVC2012+] embed_manifest_exe is now properly supported. + - [QTBUG-41504][MSVC2012+] Building DLLs targeting Windows XP is now + supported. As a side effect, Windows CE makespecs must not add /ENTRY: to + QMAKE_LFLAGS_CONSOLE any more. The flag is hard-coded in console.prf now. + - [QTBUG-35318][Xcode] Fixed QMAKE_BUNDLE_DATA's path resolution. + - [QTBUG-39527] Fixed qtCompile() when used with jom -jN. + - QMAKE_EXTRA_COMPILERS' commands and depend_command are no longer mangled. + Use $$shell_path() and $$shell_quote() to prepare the commands correctly. + - Added link-time optimization support for Clang, GCC and ICC. CONFIG+=ltgc. From 19a920c4604b7edfb1632ac30281a1e498a838b0 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 13 Nov 2014 10:32:03 +0100 Subject: [PATCH 64/69] Doc: correct autolink issues corelib/mimetype Task-number: QTBUG-40362 Change-Id: I852151fdbbe0cbc7ba88066984fc7bf83547b215 Reviewed-by: Martin Smith --- src/corelib/mimetypes/qmimedatabase.cpp | 4 ++-- src/corelib/mimetypes/qmimetype.cpp | 4 ++-- src/corelib/tools/qbytearray.cpp | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index 9d14e5f90b..c5103ebe59 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -248,7 +248,7 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent) \endcode On a typical Unix system, this will be /usr/share/mime/packages/, but it is also possible to extend the list of directories by setting the environment variable - XDG_DATA_DIRS. For instance adding /opt/myapp/share to XDG_DATA_DIRS will result + \c XDG_DATA_DIRS. For instance adding /opt/myapp/share to \c XDG_DATA_DIRS will result in /opt/myapp/share/mime/packages/ being searched for MIME definitions. Here is an example of MIME XML: @@ -575,7 +575,7 @@ QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, con This can be useful for showing all MIME types to the user, for instance in a MIME type editor. Do not use unless really necessary in other cases - though, prefer using the mimeTypeFor* methods for performance reasons. + though, prefer using the \l {mimeTypeForData()}{mimeTypeForXxx()} methods for performance reasons. */ QList QMimeDatabase::allMimeTypes() const { diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index d1bf27eae0..1ad2a449c1 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -89,8 +89,8 @@ void QMimeTypePrivate::addGlobPattern(const QString &pattern) Determining the MIME type of a file can be useful to make sure your application supports it. It is also useful in file-manager-like applications - or widgets, in order to display an appropriate icon() for the file, or even - the descriptive comment() in detailed views. + or widgets, in order to display an appropriate \l {QMimeType::iconName}{icon} for the file, or even + the descriptive \l {QMimeType::comment()}{comment} in detailed views. To check if a file has the expected MIME type, you should use inherits() rather than a simple string comparison based on the name(). This is because diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index dd235ef7a5..a622221bd3 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -725,7 +725,7 @@ static inline char qToLower(char c) occurrences of a particular value with another, use one of the two-parameter replace() overloads. - QByteArrays can be compared using overloaded operators such as + {QByteArray}s can be compared using overloaded operators such as operator<(), operator<=(), operator==(), operator>=(), and so on. The comparison is based exclusively on the numeric values of the characters and is very fast, but is not what a human would @@ -770,7 +770,7 @@ static inline char qToLower(char c) lastIndexOf(), operator<(), operator<=(), operator>(), operator>=(), toLower() and toUpper(). - This issue does not apply to QStrings since they represent + This issue does not apply to {QString}s since they represent characters using Unicode. \sa QString, QBitArray @@ -3105,6 +3105,7 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba) replaced with a single space. Whitespace means any character for which the standard C++ + \c isspace() function returns \c true in the C locale. This includes the ASCII isspace() function returns \c true in the C locale. This includes the ASCII characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '. @@ -3143,13 +3144,13 @@ QByteArray QByteArray::simplified() const and the end. Whitespace means any character for which the standard C++ - isspace() function returns \c true in the C locale. This includes the ASCII + \c isspace() function returns \c true in the C locale. This includes the ASCII characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '. Example: \snippet code/src_corelib_tools_qbytearray.cpp 33 - Unlike simplified(), trimmed() leaves internal whitespace alone. + Unlike simplified(), \l {QByteArray::trimmed()}{trimmed()} leaves internal whitespace alone. \sa simplified() */ From 8ed994f7acd0988a7399e89c2c8f58309754c1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 3 Sep 2014 16:52:23 +0200 Subject: [PATCH 65/69] iOS: Make sure QStandardPaths::displayName() is defined The file qstandardpaths_ios.mm doesn't have an implementation for this function, only (the wrongly named) qstandardpaths_mac.cpp does. There's no Foundation API to get the directory name, so we fall back to the hard-coded strings like all other platforms. Change-Id: I6dcfeb6a0e5860dd0d4e9a0cd334b2c2181a0004 Reviewed-by: Richard Moe Gustavsen --- src/corelib/io/qstandardpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index 2583e46ad8..c206e432f6 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -526,7 +526,7 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr an empty QString if no relevant location can be found. */ -#if !defined(Q_OS_MAC) && !defined(QT_BOOTSTRAPPED) +#if !defined(Q_OS_OSX) && !defined(QT_BOOTSTRAPPED) QString QStandardPaths::displayName(StandardLocation type) { switch (type) { From fbfc2b8e0b0edf9baa69193a96a57a6a6aa6cfaf Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 11 Nov 2014 13:23:55 +0100 Subject: [PATCH 66/69] Doc: corrected autolink issues itemmodels Task-number: QTBUG-40362 Change-Id: I8423643e47d27358dbbce58009cc9039aecb74cf Reviewed-by: Martin Smith --- src/corelib/itemmodels/qabstractitemmodel.cpp | 8 ++++---- src/corelib/itemmodels/qitemselectionmodel.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 6b89c8377a..b15d255e66 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -2711,7 +2711,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star persistent indexes in the model, which you would otherwise be required to do yourself. Using beginMoveRows and endMoveRows is an alternative to emitting layoutAboutToBeChanged and - layoutChanged directly along with changePersistentIndexes. + layoutChanged directly along with changePersistentIndex. The \a sourceParent index corresponds to the parent from which the rows are moved; \a sourceFirst and \a sourceLast are the first and last @@ -2978,7 +2978,7 @@ void QAbstractItemModel::endRemoveColumns() persistent indexes in the model, which you would otherwise be required to do yourself. Using beginMoveRows and endMoveRows is an alternative to emitting layoutAboutToBeChanged and - layoutChanged directly along with changePersistentIndexes. + layoutChanged directly along with changePersistentIndex. The \a sourceParent index corresponds to the parent from which the columns are moved; \a sourceFirst and \a sourceLast are the first and last @@ -3165,11 +3165,11 @@ void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QM /*! \since 4.1 - Changes the QPersistentModelIndexes that is equal to the indexes in the + Changes the {QPersistentModelIndex}es that are equal to the indexes in the given \a from model index list to the given \a to model index list. If no persistent model indexes equal to the indexes in the given \a from - model index list was found, nothing is changed. + model index list are found, nothing is changed. \sa persistentIndexList(), changePersistentIndex() */ diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp index db78af8cf8..5395fd5d09 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.cpp +++ b/src/corelib/itemmodels/qitemselectionmodel.cpp @@ -1076,7 +1076,7 @@ void QItemSelectionModelPrivate::_q_layoutChanged(const QList Date: Wed, 19 Nov 2014 15:25:27 +0100 Subject: [PATCH 67/69] Doc: Corrected autolink errors corelib Task-number: QTBUG-40362 Change-Id: I551c2af94bb61fcc2494792761dab92d537e5068 Reviewed-by: Martin Smith --- src/corelib/doc/src/animation.qdoc | 6 ++--- src/corelib/doc/src/containers.qdoc | 22 +++++++++---------- src/corelib/doc/src/datastreamformat.qdoc | 2 +- src/corelib/doc/src/filestorage.qdoc | 4 ++-- .../doc/src/objectmodel/signalsandslots.qdoc | 10 ++++----- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/corelib/doc/src/animation.qdoc b/src/corelib/doc/src/animation.qdoc index 5839d42a39..9385c08995 100644 --- a/src/corelib/doc/src/animation.qdoc +++ b/src/corelib/doc/src/animation.qdoc @@ -48,7 +48,7 @@ The animation framework aims to provide an easy way for creating animated and smooth GUIs. By animating Qt properties, the framework provides great - freedom for animating widgets and other \l{QObject}s. The framework can + freedom for animating widgets and other {QObject}s. The framework can also be used with the Graphics View framework. Many of the concepts available in the animation framework are also available in \l{Qt Quick}, where it offers a declarative way of defining animations. Much of the @@ -57,7 +57,7 @@ In this overview, we explain the basics of its architecture. We also show examples of the most common techniques that the - framework allows for animating QObjects and graphics items. + framework allows for animating {QObject}s and graphics items. \tableofcontents @@ -85,7 +85,7 @@ over the property using an easing curve. So when you want to animate a value, you can declare it as a property and make your class a QObject. Note that this gives us great freedom in - animating already existing widgets and other \l{QObject}s. + animating already existing widgets and other {QObject}s. Complex animations can be constructed by building a tree structure of \l{QAbstractAnimation}s. The tree is built by using diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc index 6017269272..a517ca32d3 100644 --- a/src/corelib/doc/src/containers.qdoc +++ b/src/corelib/doc/src/containers.qdoc @@ -386,7 +386,7 @@ \l{QMapIterator::hasPrevious()}{hasPrevious()}, \l{QMapIterator::previous()}{previous()}, and \l{QMapIterator::peekPrevious()}{peekPrevious()}. The key and - value components are extracted by calling key() and value() on + value components are extracted by calling \l{QMapIterator::key()}{key()} and \l{QMapIterator::value()}{value()} on the object returned by next(), peekNext(), previous(), or peekPrevious(). @@ -395,7 +395,7 @@ \snippet code/doc_src_containers.cpp 7 - QMapIterator also provides a key() and a value() function that + QMapIterator also provides a \l{QMapIterator::key()}{key()} and a \l{QMapIterator::value()}{value()} function that operate directly on the iterator and that return the key and value of the last item that the iterator jumped above. For example, the following code copies the contents of a QMap into a @@ -459,13 +459,13 @@ \snippet code/doc_src_containers.cpp 10 Unlike \l{Java-style iterators}, STL-style iterators point - directly at items. The begin() function of a container returns an + directly at items. The \l{QList::begin()}{begin()} function of a container returns an iterator that points to the first item in the container. The - end() function of a container returns an iterator to the + \l{QList::end()}{end()} function of a container returns an iterator to the imaginary item one position past the last item in the container. - end() marks an invalid position; it must never be dereferenced. + \l {QList::end()}{end()} marks an invalid position; it must never be dereferenced. It is typically used in a loop's break condition. If the list is - empty, begin() equals end(), so we never execute the loop. + empty, \l{QList::begin}{begin()} equals \l{QList:end()}{end()}, so we never execute the loop. The diagram below shows the valid iterator positions as red arrows for a vector containing four items: @@ -484,8 +484,8 @@ compilers also allow us to write \c{i->toLower()}, but some don't. - For read-only access, you can use const_iterator, constBegin(), - and constEnd(). For example: + For read-only access, you can use const_iterator, \l{QList::constBegin}{constBegin()}, + and \l{QList::constEnd()}{constEnd()}. For example: \snippet code/doc_src_containers.cpp 12 @@ -759,7 +759,7 @@ QString. QVector also uses that algorithm for data types that can be - moved around in memory using memcpy() (including the basic C++ + moved around in memory using \c memcpy() (including the basic C++ types, the pointer types, and Qt's \l{shared classes}) but uses a different algorithm for data types that can only be moved by calling the copy constructor and a destructor. Since the cost of @@ -790,7 +790,7 @@ \endlist If you know approximately how many items you will store in a - container, you can start by calling reserve(), and when you are - done populating the container, you can call squeeze() to release + container, you can start by calling \l{QString::reserve()}{reserve()}, and when you are + done populating the container, you can call \l{QString::squeeze()}{squeeze()} to release the extra preallocated memory. */ diff --git a/src/corelib/doc/src/datastreamformat.qdoc b/src/corelib/doc/src/datastreamformat.qdoc index b6efe6aa33..56a6d0aafa 100644 --- a/src/corelib/doc/src/datastreamformat.qdoc +++ b/src/corelib/doc/src/datastreamformat.qdoc @@ -173,7 +173,7 @@ \li If the image is null a "null image" marker is saved; otherwise the image is saved in PNG or BMP format (depending on the stream version). If you want control of the format, - stream the image into a QBuffer (using QImageIO) and stream + stream the image into a QBuffer (using QImageIOHandler/QImageIOPlugin) and stream that. \endlist \row \li QKeySequence diff --git a/src/corelib/doc/src/filestorage.qdoc b/src/corelib/doc/src/filestorage.qdoc index 394d920923..a60c5846ff 100644 --- a/src/corelib/doc/src/filestorage.qdoc +++ b/src/corelib/doc/src/filestorage.qdoc @@ -86,8 +86,8 @@ read console input and write console output. There are three general ways to use QTextStream when reading text files: \list - \li Chunk by chunk, by calling readLine() or readAll(). - \li Word by word. QTextStream supports streaming into QStrings, QByteArrays + \li Chunk by chunk, by calling \l{QBuffer::readLine()}{readLine()} or \l{QBuffer::readAll()}{readAll()}. + \li Word by word. QTextStream supports streaming into {QString}s, {QByteArray}s and char* buffers. Words are delimited by space, and leading white space is automatically skipped. \li Character by character, by streaming into QChar or char types. This diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc index f79e8a7dca..b9b1874d0f 100644 --- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc +++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc @@ -242,7 +242,7 @@ By default, for every connection you make, a signal is emitted; two signals are emitted for duplicate connections. You can break - all of these connections with a single disconnect() call. + all of these connections with a single \l{QObject::disconnect()}{disconnect()} call. If you pass the Qt::UniqueConnection \a type, the connection will only be made if it is not a duplicate. If there is already a duplicate (exact same signal to the exact same slot on the same objects), @@ -251,9 +251,7 @@ This example illustrates that objects can work together without needing to know any information about each other. To enable this, the objects only need to be connected together, and this can be achieved with some simple - QObject::connect() function calls, or with \c{uic}'s - \l{Using a Designer UI File in Your Application#Automatic Connections} - {automatic connections} feature. + QObject::connect() function calls, or with \c{uic}'s {automatic connections} feature. \section1 A Real Example @@ -354,7 +352,7 @@ connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed); \endcode - There are several advantages to using connect() with function pointers. + There are several advantages to using QObject::connect() with function pointers. First, it allows the compiler to check that the signal's arguments are compatible with the slot's arguments. Arguments can also be implicitly converted by the compiler, if needed. @@ -407,7 +405,7 @@ will open: "Tax File", "Accounts File", or "Report File". In order to open the correct file, you use QSignalMapper::setMapping() to - map all the clicked() signals to a QSignalMapper object. Then you connect + map all the QPushButton::clicked() signals to a QSignalMapper object. Then you connect the file's QPushButton::clicked() signal to the QSignalMapper::map() slot. \snippet signalmapper/filereader.cpp 0 From 52f5bf9cd5dd5586dc18b2d7efd833232c2f508a Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 19 Nov 2014 18:43:18 +0200 Subject: [PATCH 68/69] Android: Use LocalServerSocket instead of ServerSocket Using LocalServerSocket is way much safer than ServerSocket because is not using ports which might be in use by other applications. Change-Id: I0e2be0b4561362939950861024f1f95ab819f2c2 Reviewed-by: BogDan Vatra Reviewed-by: Alex Blasche Reviewed-by: hjk Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../qt5/android/QtActivityDelegate.java | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 12b606b89f..f44465b4c5 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -50,6 +50,8 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.graphics.drawable.ColorDrawable; +import android.net.LocalServerSocket; +import android.net.LocalSocket; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -79,9 +81,6 @@ import java.io.FileWriter; import java.io.InputStreamReader; import java.io.IOException; import java.lang.reflect.Method; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -496,12 +495,12 @@ public class QtActivityDelegate private class DebugWaitRunnable implements Runnable { - public DebugWaitRunnable(int socketPort) throws IOException { - socket = new ServerSocket(socketPort); + public DebugWaitRunnable(String pingPongSocket) throws IOException { + socket = new LocalServerSocket(pingPongSocket); } public boolean wasFailure; - private ServerSocket socket; + private LocalServerSocket socket; public void run() { final int napTime = 200; // milliseconds between file accesses @@ -509,9 +508,7 @@ public class QtActivityDelegate final int maxAttempts = timeOut / napTime; try { - socket.setSoTimeout(timeOut); - debugLog("Waiting for debug socket on port: " + socket.getLocalPort()); - Socket connectionFromClient = socket.accept(); + LocalSocket connectionFromClient = socket.accept(); debugLog("Debug socket accepted"); BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream())); @@ -524,7 +521,7 @@ public class QtActivityDelegate if (!clientData.isEmpty()) break; - if (socket.isClosed()) { + if (connectionFromClient.isClosed()) { wasFailure = true; break; } @@ -539,6 +536,14 @@ public class QtActivityDelegate Log.e(QtNative.QtTAG,"Can't start debugger" + interruptEx.getMessage()); } } + + public void shutdown() throws IOException + { + wasFailure = true; + try { + socket.close(); + } catch (IOException ignored) { } + } }; public boolean startApplication() @@ -597,17 +602,11 @@ public class QtActivityDelegate String pongFile = extras.getString("pong_file"); String gdbserverSocket = extras.getString("gdbserver_socket"); String gdbserverCommand = extras.getString("gdbserver_command"); - String pingViaSocket = extras.getString("ping_socketport"); + String pingSocket = extras.getString("ping_socket"); boolean usePing = pingFile != null; boolean usePong = pongFile != null; boolean useSocket = gdbserverSocket != null; - int pingSocket = 0; - if (pingViaSocket != null) { - try { - pingSocket = Integer.parseInt(pingViaSocket); - } catch (NumberFormatException ignored) { } - } - boolean usePingViaSocket = (pingViaSocket != null && pingSocket > 0); + boolean usePingSocket = pingSocket != null; int napTime = 200; // milliseconds between file accesses int timeOut = 30000; // ms until we give up on ping and pong int maxAttempts = timeOut / napTime; @@ -654,7 +653,7 @@ public class QtActivityDelegate } if (i == maxAttempts) { - debugLog("time out when waiting for socket"); + debugLog("time out when waiting for debug socket"); return false; } @@ -663,11 +662,23 @@ public class QtActivityDelegate debugLog("socket not used"); } - if (usePingViaSocket) { + if (usePingSocket) { DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket); Thread waitThread = new Thread(runnable); waitThread.start(); - waitThread.join(); + + int i; + for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) { + debugLog("Waiting for debug socket connect"); + debugLog("go to sleep"); + Thread.sleep(napTime); + } + + if (i == maxAttempts) { + debugLog("time out when waiting for ping socket"); + runnable.shutdown(); + return false; + } if (runnable.wasFailure) { debugLog("Could not connect to debug client"); From 087aa1f3cb5975ef55e42db54487f737c93a4f0f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 20 Nov 2014 11:08:13 +0100 Subject: [PATCH 69/69] Windows: Prevent registration of timers in shutdown phase Do not register new timers after closingDown() has been called. They might call back into QEventDispatcherWin32 after the object has been destructed, leading to crashes on exit. registerSocketNotifier has a similar protection using QCoreApplication::closingDown(). This however does not work in all cases, because QEventDispatcher::closingDown() is called in ~QGuiApplication(), while QCoreApplication::is_app_closing is set in ~QCoreApplication(). In between qt_call_post_routines() is called, which might trigger new timers to be registered. Task-number: QTBUG-42772 Change-Id: I91325fb10e38c117c1cbedfee272d0ab6a5ca8fa Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qeventdispatcher_win.cpp | 12 ++++++++++-- src/corelib/kernel/qeventdispatcher_win_p.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 62e6e9f051..1a8bb381aa 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -307,8 +307,9 @@ static void resolveTimerAPI() } QEventDispatcherWin32Private::QEventDispatcherWin32Private() - : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0), - serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), wakeUps(0) + : threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0), + getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), + wakeUps(0) { resolveTimerAPI(); } @@ -931,6 +932,11 @@ void QEventDispatcherWin32::registerTimer(int timerId, int interval, Qt::TimerTy Q_D(QEventDispatcherWin32); + // exiting ... do not register new timers + // (QCoreApplication::closingDown() is set too late to be used here) + if (d->closingDown) + return; + WinTimerInfo *t = new WinTimerInfo; t->dispatcher = this; t->timerId = timerId; @@ -1155,6 +1161,8 @@ void QEventDispatcherWin32::closingDown() d->timerVec.clear(); d->timerDict.clear(); + d->closingDown = true; + uninstallMessageHook(); } diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index a68f6cfa28..8022299a76 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -147,6 +147,7 @@ public: DWORD threadId; bool interrupt; + bool closingDown; // internal window handle used for socketnotifiers/timers/etc HWND internalHwnd;