summaryrefslogtreecommitdiffstats
path: root/src/angle/patches
diff options
context:
space:
mode:
Diffstat (limited to 'src/angle/patches')
-rw-r--r--src/angle/patches/0012-ANGLE-Support-WinRT.patch1131
-rw-r--r--src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch990
-rw-r--r--src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch51
-rw-r--r--src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch85
-rw-r--r--src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch28
5 files changed, 2285 insertions, 0 deletions
diff --git a/src/angle/patches/0012-ANGLE-Support-WinRT.patch b/src/angle/patches/0012-ANGLE-Support-WinRT.patch
new file mode 100644
index 0000000000..8a5b96c7c0
--- /dev/null
+++ b/src/angle/patches/0012-ANGLE-Support-WinRT.patch
@@ -0,0 +1,1131 @@
+From 67c318c7b9c6d95d3170d11956dbec56494511ca Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Tue, 1 Oct 2013 09:43:29 +0300
+Subject: [PATCH] ANGLE: Support WinRT
+
+This enables EGL for WinRT's native types, and adjusts some codepaths
+to accommodate differences in between desktop Windows and WinRT.
+
+- 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 <Friedemann.Kleint@digia.com>
+---
+ src/3rdparty/angle/include/EGL/eglplatform.h | 10 ++-
+ src/3rdparty/angle/src/compiler/osinclude.h | 35 ++++------
+ src/3rdparty/angle/src/compiler/ossource_posix.cpp | 8 +++
+ src/3rdparty/angle/src/compiler/ossource_win.cpp | 8 +++
+ src/3rdparty/angle/src/compiler/ossource_winrt.cpp | 75 ++++++++++++++++++++++
+ src/3rdparty/angle/src/libEGL/Display.cpp | 8 ++-
+ src/3rdparty/angle/src/libEGL/Display.h | 4 +-
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 35 +++++++++-
+ src/3rdparty/angle/src/libEGL/Surface.h | 7 +-
+ src/3rdparty/angle/src/libEGL/libEGL.cpp | 4 +-
+ src/3rdparty/angle/src/libEGL/main.cpp | 40 ++++++++++--
+ src/3rdparty/angle/src/libGLESv2/main.cpp | 39 +++++++++--
+ src/3rdparty/angle/src/libGLESv2/precompiled.h | 15 +++++
+ .../angle/src/libGLESv2/renderer/Renderer.cpp | 23 ++++---
+ .../angle/src/libGLESv2/renderer/Renderer.h | 27 +++++++-
+ .../angle/src/libGLESv2/renderer/Renderer11.cpp | 10 ++-
+ .../angle/src/libGLESv2/renderer/Renderer11.h | 2 +-
+ .../angle/src/libGLESv2/renderer/SwapChain.h | 4 +-
+ .../angle/src/libGLESv2/renderer/SwapChain11.cpp | 29 +++++++--
+ .../angle/src/libGLESv2/renderer/SwapChain11.h | 2 +-
+ src/3rdparty/angle/src/libGLESv2/utilities.cpp | 53 +++++++++++++++
+ src/angle/src/common/common.pri | 2 +-
+ src/angle/src/compiler/translator_common.pro | 7 +-
+ src/angle/src/config.pri | 5 +-
+ 24 files changed, 386 insertions(+), 66 deletions(-)
+ create mode 100644 src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+
+diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
+index 34283f2..eb15ae5 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_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
++
++struct IUnknown;
++
++typedef int 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
+ #endif
+diff --git a/src/3rdparty/angle/src/compiler/osinclude.h b/src/3rdparty/angle/src/compiler/osinclude.h
+index d8bb1a7..60177d5 100644
+--- a/src/3rdparty/angle/src/compiler/osinclude.h
++++ b/src/3rdparty/angle/src/compiler/osinclude.h
+@@ -13,27 +13,26 @@
+ //
+
+ #if defined(_WIN32) || defined(_WIN64)
++#define STRICT
++#define VC_EXTRALEAN 1
++#include <windows.h>
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
++#define ANGLE_OS_WINRT
++#else
+ #define ANGLE_OS_WIN
++#endif
+ #elif defined(__APPLE__) || defined(__linux__) || \
+ defined(__FreeBSD__) || defined(__OpenBSD__) || \
+ defined(__sun) || defined(ANDROID) || \
+ defined(__GLIBC__) || defined(__GNU__) || \
+ defined(__QNX__)
+ #define ANGLE_OS_POSIX
+-#else
+-#error Unsupported platform.
+-#endif
+-
+-#if defined(ANGLE_OS_WIN)
+-#define STRICT
+-#define VC_EXTRALEAN 1
+-#include <windows.h>
+-#elif defined(ANGLE_OS_POSIX)
+ #include <pthread.h>
+ #include <semaphore.h>
+ #include <errno.h>
+-#endif // ANGLE_OS_WIN
+-
++#else
++#error Unsupported platform.
++#endif
+
+ #include "compiler/debug.h"
+
+@@ -43,23 +42,17 @@
+ #if defined(ANGLE_OS_WIN)
+ typedef DWORD OS_TLSIndex;
+ #define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
++#elif defined(ANGLE_OS_WINRT)
++typedef size_t OS_TLSIndex;
++#define OS_INVALID_TLS_INDEX ((DWORD)0xFFFFFF)
+ #elif defined(ANGLE_OS_POSIX)
+ typedef pthread_key_t OS_TLSIndex;
+ #define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1))
+ #endif // ANGLE_OS_WIN
+
+ OS_TLSIndex OS_AllocTLSIndex();
++void *OS_GetTLSValue(OS_TLSIndex nIndex);
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
+ bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
+
+-inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
+-{
+- ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+-#if defined(ANGLE_OS_WIN)
+- return TlsGetValue(nIndex);
+-#elif defined(ANGLE_OS_POSIX)
+- return pthread_getspecific(nIndex);
+-#endif // ANGLE_OS_WIN
+-}
+-
+ #endif // __OSINCLUDE_H
+diff --git a/src/3rdparty/angle/src/compiler/ossource_posix.cpp b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+index 1e1e699..35510c1 100644
+--- a/src/3rdparty/angle/src/compiler/ossource_posix.cpp
++++ b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+@@ -33,6 +33,14 @@ OS_TLSIndex OS_AllocTLSIndex()
+ }
+
+
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++
++ return pthread_getspecific(nIndex);
++}
++
++
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+ {
+ if (nIndex == OS_INVALID_TLS_INDEX) {
+diff --git a/src/3rdparty/angle/src/compiler/ossource_win.cpp b/src/3rdparty/angle/src/compiler/ossource_win.cpp
+index 89922fe..708a1ad 100644
+--- a/src/3rdparty/angle/src/compiler/ossource_win.cpp
++++ b/src/3rdparty/angle/src/compiler/ossource_win.cpp
+@@ -29,6 +29,14 @@ OS_TLSIndex OS_AllocTLSIndex()
+ }
+
+
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++
++ return TlsGetValue(nIndex);
++}
++
++
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+ {
+ if (nIndex == OS_INVALID_TLS_INDEX) {
+diff --git a/src/3rdparty/angle/src/compiler/ossource_winrt.cpp b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+new file mode 100644
+index 0000000..84443ab
+--- /dev/null
++++ b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+@@ -0,0 +1,75 @@
++//
++// Copyright (c) 2002-2010 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 "compiler/osinclude.h"
++//
++// This file contains contains Windows Runtime specific functions
++//
++
++#if !defined(ANGLE_OS_WINRT)
++#error Trying to build a WinRT specific file in a non-WinRT build.
++#endif
++
++#include <vector>
++
++
++//
++// Thread Local Storage Operations
++//
++__declspec(thread) std::vector<void *> *tls = nullptr;
++__declspec(thread) std::vector<OS_TLSIndex> *freeIndices = nullptr;
++
++OS_TLSIndex OS_AllocTLSIndex()
++{
++ if (!tls)
++ tls = new std::vector<void*>;
++
++ if (freeIndices && !freeIndices->empty()) {
++ OS_TLSIndex index = freeIndices->back();
++ freeIndices->pop_back();
++ return index;
++ } else {
++ tls->push_back(nullptr);
++ return tls->size() - 1;
++ }
++}
++
++
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++ ASSERT(tls);
++
++ return tls->at(nIndex);
++}
++
++
++bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
++{
++ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
++ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
++ return false;
++ }
++
++ tls->at(nIndex) = lpvValue;
++ return true;
++}
++
++
++bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
++{
++ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
++ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
++ return false;
++ }
++
++ if (!freeIndices)
++ freeIndices = new std::vector<OS_TLSIndex>;
++
++ freeIndices->push_back(nIndex);
++
++ return true;
++}
+diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
+index a382c3b..14973af 100644
+--- a/src/3rdparty/angle/src/libEGL/Display.cpp
++++ b/src/3rdparty/angle/src/libEGL/Display.cpp
+@@ -186,7 +186,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;
+@@ -456,7 +456,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++)
+ {
+@@ -471,7 +471,6 @@ bool Display::hasExistingWindowSurface(HWND window)
+
+ void Display::initExtensionString()
+ {
+- HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ bool shareHandleSupported = mRenderer->getShareHandleSupport();
+
+ mExtensionString = "";
+@@ -487,10 +486,13 @@ void Display::initExtensionString()
+
+ mExtensionString += "EGL_ANGLE_query_surface_pointer ";
+
++#if !defined(ANGLE_OS_WINRT)
++ HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ if (swiftShader)
+ {
+ mExtensionString += "EGL_ANGLE_software_display ";
+ }
++#endif
+
+ if (shareHandleSupported)
+ {
+diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
+index 58c3940..5d55410 100644
+--- a/src/3rdparty/angle/src/libEGL/Display.h
++++ b/src/3rdparty/angle/src/libEGL/Display.h
+@@ -40,7 +40,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, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+
+@@ -51,7 +51,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; };
+
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
+index b47a7bc..abc6d7d 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
+@@ -20,10 +20,15 @@
+ #include "libEGL/main.h"
+ #include "libEGL/Display.h"
+
++#if defined(ANGLE_OS_WINRT)
++#include <windows.foundation.h>
++#include <windows.ui.core.h>
++#endif
++
+ namespace egl
+ {
+
+-Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
++Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported)
+ : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
+ {
+ mRenderer = mDisplay->getRenderer();
+@@ -96,6 +101,7 @@ bool Surface::resetSwapChain()
+
+ if (mWindow)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+@@ -107,6 +113,14 @@ bool Surface::resetSwapChain()
+
+ width = windowRect.right - windowRect.left;
+ height = windowRect.bottom - windowRect.top;
++#else
++ ABI::Windows::Foundation::Rect windowRect;
++ ABI::Windows::UI::Core::ICoreWindow *window;
++ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ window->get_Bounds(&windowRect);
++ width = windowRect.Width;
++ height = windowRect.Height;
++#endif
+ }
+ else
+ {
+@@ -226,7 +240,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ return true;
+ }
+
+-HWND Surface::getWindowHandle()
++EGLNativeWindowType Surface::getWindowHandle()
+ {
+ return mWindow;
+ }
+@@ -235,6 +249,7 @@ HWND Surface::getWindowHandle()
+ #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
+ #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+
++#if !defined(ANGLE_OS_WINRT)
+ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
+ {
+ if (message == WM_SIZE)
+@@ -248,9 +263,13 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
+ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+ }
++#endif
+
+ void Surface::subclassWindow()
+ {
++#if defined(ANGLE_OS_WINRT)
++ mWindowSubclassed = false;
++#else
+ if (!mWindow)
+ {
+ return;
+@@ -274,10 +293,12 @@ void Surface::subclassWindow()
+ SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ mWindowSubclassed = true;
++#endif
+ }
+
+ void Surface::unsubclassWindow()
+ {
++#if !defined(ANGLE_OS_WINRT)
+ if(!mWindowSubclassed)
+ {
+ return;
+@@ -300,10 +321,12 @@ void Surface::unsubclassWindow()
+ RemoveProp(mWindow, kSurfaceProperty);
+ RemoveProp(mWindow, kParentWndProc);
+ mWindowSubclassed = false;
++#endif
+ }
+
+ bool Surface::checkForOutOfDateSwapChain()
+ {
++#if !defined(ANGLE_OS_WINRT)
+ RECT client;
+ if (!GetClientRect(getWindowHandle(), &client))
+ {
+@@ -314,6 +337,14 @@ bool Surface::checkForOutOfDateSwapChain()
+ // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
+ int clientWidth = client.right - client.left;
+ int clientHeight = client.bottom - client.top;
++#else
++ ABI::Windows::Foundation::Rect windowRect;
++ ABI::Windows::UI::Core::ICoreWindow *window;
++ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ window->get_Bounds(&windowRect);
++ int clientWidth = windowRect.Width;
++ int clientHeight = windowRect.Height;
++#endif
+ bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
+
+ if (mSwapIntervalDirty)
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
+index 938b800..ae9a380 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.h
++++ b/src/3rdparty/angle/src/libEGL/Surface.h
+@@ -15,6 +15,7 @@
+ #include <EGL/egl.h>
+
+ #include "common/angleutils.h"
++#include "windows.h"
+
+ namespace gl
+ {
+@@ -34,7 +35,7 @@ class Config;
+ class Surface
+ {
+ public:
+- Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported);
++ Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported);
+ Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
+
+ ~Surface();
+@@ -43,7 +44,7 @@ class Surface
+ void release();
+ bool resetSwapChain();
+
+- HWND getWindowHandle();
++ EGLNativeWindowType getWindowHandle();
+ bool swap();
+ bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
+
+@@ -79,7 +80,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
+diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
+index 6e10c39..5bcb5d5 100644
+--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
++++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
+@@ -308,14 +308,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
+ return EGL_NO_SURFACE;
+ }
+
++#if !defined(ANGLE_OS_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);
+ }
+ catch(std::bad_alloc&)
+ {
+diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
+index 7dea5fc..964b4b2 100644
+--- a/src/3rdparty/angle/src/libEGL/main.cpp
++++ b/src/3rdparty/angle/src/libEGL/main.cpp
+@@ -1,3 +1,4 @@
++#include "../libGLESv2/precompiled.h"
+ //
+ // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+@@ -12,7 +13,13 @@
+
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
++#if !defined(ANGLE_OS_WINRT)
+ static DWORD currentTLS = TLS_OUT_OF_INDEXES;
++#else
++static __declspec(thread) void *currentTLS = 0;
++#endif
++
++namespace egl { Current *getCurrent(); }
+
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+@@ -35,22 +42,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ }
+ #endif
+
++#if !defined(ANGLE_OS_WINRT)
+ currentTLS = TlsAlloc();
+
+ if (currentTLS == TLS_OUT_OF_INDEXES)
+ {
+ return FALSE;
+ }
++#endif
+ }
+ // Fall throught to initialize index
+ case DLL_THREAD_ATTACH:
+ {
+- egl::Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ TlsSetValue(currentTLS, current);
+-
++#endif
+ current->error = EGL_SUCCESS;
+ current->API = EGL_OPENGL_ES_API;
+ current->display = EGL_NO_DISPLAY;
+@@ -61,24 +71,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ break;
+ case DLL_THREAD_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++#endif
+ }
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
+ }
+
+ TlsFree(currentTLS);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++ }
++#endif
+ }
+ break;
+ default:
+@@ -95,7 +116,16 @@ namespace egl
+ Current *getCurrent()
+ {
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+- return (Current*)TlsGetValue(currentTLS);
++#if !defined(ANGLE_OS_WINRT)
++ Current *current = (Current*)TlsGetValue(currentTLS);
++ if (!current)
++ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
++ return current;
++#else
++ if (!currentTLS)
++ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
++ return (Current*)currentTLS;
++#endif
+ #else
+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
+ static Current curr = { EGL_SUCCESS, EGL_OPENGL_ES_API, EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE };
+diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
+index 730a6ac..defdf35 100644
+--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
+@@ -13,7 +13,13 @@
+
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
++#if !defined(ANGLE_OS_WINRT)
+ static DWORD currentTLS = TLS_OUT_OF_INDEXES;
++#else
++static __declspec(thread) void *currentTLS = 0;
++#endif
++
++namespace gl { Current *getCurrent(); }
+
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+@@ -21,22 +27,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ {
+ case DLL_PROCESS_ATTACH:
+ {
++#if !defined(ANGLE_OS_WINRT)
+ currentTLS = TlsAlloc();
+
+ if (currentTLS == TLS_OUT_OF_INDEXES)
+ {
+ return FALSE;
+ }
++#endif
+ }
+ // Fall throught to initialize index
+ case DLL_THREAD_ATTACH:
+ {
+- gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ TlsSetValue(currentTLS, current);
+-
++#endif
+ current->context = NULL;
+ current->display = NULL;
+ }
+@@ -44,24 +53,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ break;
+ case DLL_THREAD_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++#endif
+ }
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
+ }
+
+ TlsFree(currentTLS);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++ }
++#endif
+ }
+ break;
+ default:
+@@ -78,7 +98,16 @@ namespace gl
+ Current *getCurrent()
+ {
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+- return (Current*)TlsGetValue(currentTLS);
++#if !defined(ANGLE_OS_WINRT)
++ Current *current = (Current*)TlsGetValue(currentTLS);
++ if (!current)
++ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
++ return current;
++#else
++ if (!currentTLS)
++ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
++ return (Current*)currentTLS;
++#endif
+ #else
+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
+ static gl::Current curr = { 0, 0 };
+diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+index 50dec6b..823d27b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/precompiled.h
++++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+@@ -32,13 +32,28 @@
+ #include <unordered_map>
+ #include <vector>
+
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
++#define ANGLE_OS_WINRT
++#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
++#define ANGLE_OS_WINPHONE
++#endif
++#endif
++
+ #ifndef ANGLE_ENABLE_D3D11
+ #include <d3d9.h>
+ #else
++#if !defined(ANGLE_OS_WINRT)
+ #include <D3D11.h>
++#else
++#include <d3d11_1.h>
++#define Sleep(x) WaitForSingleObjectEx(GetCurrentThread(), x, FALSE)
++#define GetVersion() WINVER
++#endif
+ #include <dxgi.h>
+ #endif
++#ifndef ANGLE_OS_WINPHONE
+ #include <D3Dcompiler.h>
++#endif
+
+ #ifdef _MSC_VER
+ #include <hash_map>
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+index 21ad223..7ba183d 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+@@ -28,13 +28,18 @@
+ #define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT(1, 0x876, 380)
+ #endif
+
+-#ifdef __MINGW32__
+-
+ #ifndef D3DCOMPILER_DLL
++#ifndef ANGLE_OS_WINPHONE
++#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator
++#else
++#define D3DCOMPILER_DLL L"qtd3dcompiler.dll" // Placeholder DLL for phone
++#endif // ANGLE_OS_WINPHONE
++#endif // D3DCOMPILER_DLL
+
+-//Add define + typedefs for older MinGW-w64 headers (pre 5783)
++#if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE)
+
+-#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
++//Add define + typedefs for older MinGW-w64 headers (pre 5783)
++//Also define these on Windows Phone, which doesn't have a shader compiler
+
+ HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+@@ -43,9 +48,7 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
+
+-#endif // D3DCOMPILER_DLL
+-
+-#endif // __MINGW32__
++#endif // __MINGW32__ || ANGLE_OS_WINPHONE
+
+ namespace rx
+ {
+@@ -81,7 +84,11 @@ bool Renderer::initializeCompiler()
+ }
+ #else
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
++#if !defined(ANGLE_OS_WINRT)
+ mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
++#else
++ mD3dCompilerModule = LoadPackagedLibrary(D3DCOMPILER_DLL, NULL);
++#endif
+ #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
+
+ if (!mD3dCompilerModule)
+@@ -225,4 +232,4 @@ void glDestroyRenderer(rx::Renderer *renderer)
+ delete renderer;
+ }
+
+-}
+\ No newline at end of file
++}
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+index 04e877b..ac67c27 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+@@ -1,3 +1,4 @@
++#include "../precompiled.h"
+ //
+ // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+@@ -13,6 +14,30 @@
+ #include "libGLESv2/Uniform.h"
+ #include "libGLESv2/angletypes.h"
+
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL0
++#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14)
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL1
++#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL2
++#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15))
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3
++#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15)
++#endif
++#ifndef D3DCOMPILE_DEBUG
++#define D3DCOMPILE_DEBUG (1 << 0)
++#endif
++#ifndef D3DCOMPILE_SKIP_OPTIMIZATION
++#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2)
++#endif
++#ifndef D3DCOMPILE_AVOID_FLOW_CONTROL
++#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9)
++#endif
++#ifndef D3DCOMPILE_PREFER_FLOW_CONTROL
++#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10)
++#endif
+ #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+ #endif
+@@ -107,7 +132,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 void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+index a431018..d04467b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+@@ -137,6 +137,7 @@ EGLint Renderer11::initialize()
+ return EGL_NOT_INITIALIZED;
+ }
+
++#if !defined(ANGLE_OS_WINRT)
+ mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+
+@@ -155,6 +156,7 @@ EGLint Renderer11::initialize()
+ ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
++#endif
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
+@@ -203,8 +205,12 @@ EGLint Renderer11::initialize()
+ }
+ }
+
++#if !defined(ANGLE_OS_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))
+ {
+@@ -524,7 +530,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)
+ {
+ return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+ }
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+index f024855..a7f5a39 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+@@ -52,7 +52,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 void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+index 14c0515..a6870eb 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+@@ -18,7 +18,7 @@ namespace rx
+ class SwapChain
+ {
+ 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)
+ {
+ }
+@@ -33,7 +33,7 @@ class SwapChain
+ virtual HANDLE getShareHandle() {return mShareHandle;};
+
+ 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;
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 0da58cb..0797fd7 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -17,7 +17,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)
+ {
+@@ -468,6 +468,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+
+ if (mWindow)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ // We cannot create a swap chain for an HWND that is owned by a different process
+ DWORD currentProcessId = GetCurrentProcessId();
+ DWORD wndProcessId;
+@@ -491,14 +492,34 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
++ swapChainDesc.Windowed = TRUE;
++ swapChainDesc.OutputWindow = mWindow;
++#else
++ IDXGIFactory2 *factory;
++ HRESULT result = mRenderer->getDxgiFactory()->QueryInterface(IID_PPV_ARGS(&factory));
++ ASSERT(SUCCEEDED(result));
++
++ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
++ swapChainDesc.BufferCount = 2;
++ swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
++ swapChainDesc.Width = backbufferWidth;
++ swapChainDesc.Height = backbufferHeight;
++ swapChainDesc.Stereo = FALSE;
++ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
++#endif
++
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.Flags = 0;
+- swapChainDesc.OutputWindow = mWindow;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+- swapChainDesc.Windowed = TRUE;
+
+- HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++#if !defined(ANGLE_OS_WINRT)
++ result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++#else
++ IDXGISwapChain1 *swapChain;
++ result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
++ mSwapChain = swapChain;
++#endif
+
+ if (FAILED(result))
+ {
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+index 8001046..2a030c8 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+@@ -19,7 +19,7 @@ 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();
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+index 32df49e..8fd193b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+@@ -10,6 +10,14 @@
+ #include "libGLESv2/utilities.h"
+ #include "libGLESv2/mathutil.h"
+
++#if defined(ANGLE_OS_WINRT)
++#include <locale>
++#include <codecvt>
++#include <wrl.h>
++#include <windows.storage.h>
++using namespace ABI::Windows::Storage;
++#endif
++
+ namespace gl
+ {
+
+@@ -737,7 +745,50 @@ bool IsTriangleMode(GLenum drawMode)
+
+ std::string getTempPath()
+ {
++#if defined(ANGLE_OS_WINRT)
++
++ static std::string path;
++
++ while (path.empty()) {
++ IApplicationDataStatics *applicationDataFactory;
++ HRESULT result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(),
++ IID_PPV_ARGS(&applicationDataFactory));
++ if (FAILED(result))
++ break;
++
++ IApplicationData *applicationData;
++ result = applicationDataFactory->get_Current(&applicationData);
++ if (FAILED(result))
++ break;
++
++ IStorageFolder *storageFolder;
++ result = applicationData->get_LocalFolder(&storageFolder);
++ if (FAILED(result))
++ break;
++
++ IStorageItem *localFolder;
++ result = storageFolder->QueryInterface(IID_PPV_ARGS(&localFolder));
++ if (FAILED(result))
++ break;
++
++ HSTRING localFolderPath;
++ result = localFolder->get_Path(&localFolderPath);
++ if (FAILED(result))
++ break;
++
++ std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
++ path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
++ if (path.empty())
++ {
++ UNREACHABLE();
++ break;
++ }
++ }
++
++#else
++
+ char path[MAX_PATH];
++
+ DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
+ if (pathLen == 0)
+ {
+@@ -751,6 +802,8 @@ std::string getTempPath()
+ UNREACHABLE();
+ return std::string();
+ }
++
++#endif
+
+ return path;
+ }
+diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
+index a94b9a6..12e26a9 100644
+--- a/src/angle/src/common/common.pri
++++ b/src/angle/src/common/common.pri
+@@ -7,7 +7,7 @@ INCLUDEPATH += \
+ LIBS = $$QMAKE_LIBS_CORE $$QMAKE_LIBS_GUI
+
+ # DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK.
+-win32-msvc2012 {
++win32-msvc2012|winrt {
+ FXC = fxc.exe
+ } else {
+ DX_DIR = $$(DXSDK_DIR)
+diff --git a/src/angle/src/compiler/translator_common.pro b/src/angle/src/compiler/translator_common.pro
+index b281215..5581c9d 100644
+--- a/src/angle/src/compiler/translator_common.pro
++++ b/src/angle/src/compiler/translator_common.pro
+@@ -78,7 +78,6 @@ SOURCES += \
+ $$ANGLE_DIR/src/compiler/intermOut.cpp \
+ $$ANGLE_DIR/src/compiler/IntermTraverse.cpp \
+ $$ANGLE_DIR/src/compiler/MapLongVariableNames.cpp \
+- $$ANGLE_DIR/src/compiler/ossource_win.cpp \
+ $$ANGLE_DIR/src/compiler/parseConst.cpp \
+ $$ANGLE_DIR/src/compiler/ParseHelper.cpp \
+ $$ANGLE_DIR/src/compiler/PoolAlloc.cpp \
+@@ -98,6 +97,12 @@ SOURCES += \
+ $$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp \
+ $$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp
+
++winrt {
++ SOURCES += $$ANGLE_DIR/src/compiler/ossource_winrt.cpp
++} else {
++ SOURCES += $$ANGLE_DIR/src/compiler/ossource_win.cpp
++}
++
+ # NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
+ flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
+ flex.output = ${QMAKE_FILE_BASE}_lex.cpp
+diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
+index 1c6d8b0..ed25581 100644
+--- a/src/angle/src/config.pri
++++ b/src/angle/src/config.pri
+@@ -37,8 +37,9 @@ DEFINES += _WINDOWS \
+ NOMINMAX \
+ WIN32_LEAN_AND_MEAN=1
+
+-# Defines specifying the API version (0x0600 = Vista)
+-DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
++# Defines specifying the API version (0x0600 = Vista, 0x0602 = Win8))
++winrt: DEFINES += _WIN32_WINNT=0x0602 WINVER=0x0602
++else: DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
+
+ # ANGLE specific defines
+ DEFINES += ANGLE_DISABLE_TRACE \
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch b/src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
new file mode 100644
index 0000000000..0a8e403e8d
--- /dev/null
+++ b/src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
@@ -0,0 +1,990 @@
+From a71ccc033fe2cf1c3c58633d3bd220c52b744478 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Fri, 8 Nov 2013 09:04:59 +0200
+Subject: [PATCH] ANGLE: Enable D3D11 for feature level 9 cards
+
+Enable use of ANGLE on lower-end hardware, such as Surface RT and
+Windows Phone 8.
+
+Based on https://codereview.appspot.com/12917046/
+
+Change-Id: Ice536802e4eedc1d264abd0dd65960638fce59e4
+---
+ src/3rdparty/angle/src/libGLESv2/Buffer.cpp | 8 +-
+ src/3rdparty/angle/src/libGLESv2/Buffer.h | 4 +-
+ src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 4 +-
+ .../angle/src/libGLESv2/renderer/BufferStorage.h | 2 +-
+ .../src/libGLESv2/renderer/BufferStorage11.cpp | 9 +-
+ .../angle/src/libGLESv2/renderer/BufferStorage11.h | 2 +-
+ .../src/libGLESv2/renderer/BufferStorage9.cpp | 2 +-
+ .../angle/src/libGLESv2/renderer/BufferStorage9.h | 2 +-
+ .../angle/src/libGLESv2/renderer/Image11.cpp | 7 +-
+ .../angle/src/libGLESv2/renderer/IndexBuffer11.cpp | 4 +-
+ .../src/libGLESv2/renderer/RenderStateCache.cpp | 3 +-
+ .../angle/src/libGLESv2/renderer/Renderer11.cpp | 288 +++++++++++++++------
+ .../angle/src/libGLESv2/renderer/Renderer11.h | 2 +
+ .../angle/src/libGLESv2/renderer/SwapChain11.cpp | 7 +-
+ .../src/libGLESv2/renderer/TextureStorage11.cpp | 8 +-
+ .../src/libGLESv2/renderer/renderer11_utils.cpp | 4 +-
+ .../src/libGLESv2/renderer/renderer11_utils.h | 2 +-
+ .../src/libGLESv2/renderer/shaders/Clear11.hlsl | 4 +
+ src/angle/src/libGLESv2/libGLESv2.pro | 8 +-
+ 19 files changed, 260 insertions(+), 110 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+index c007d5d..40baa95 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+@@ -37,11 +37,11 @@ Buffer::~Buffer()
+ delete mStaticIndexBuffer;
+ }
+
+-void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
++void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target)
+ {
+ mBufferStorage->clear();
+ mIndexRangeCache.clear();
+- mBufferStorage->setData(data, size, 0);
++ mBufferStorage->setData(data, size, 0, target);
+
+ mUsage = usage;
+
+@@ -54,9 +54,9 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
+ }
+ }
+
+-void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
++void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target)
+ {
+- mBufferStorage->setData(data, size, offset);
++ mBufferStorage->setData(data, size, offset, target);
+ mIndexRangeCache.invalidateRange(offset, size);
+
+ if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
+diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h
+index 4048f4b..9b86b97 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
++++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h
+@@ -33,8 +33,8 @@ class Buffer : public RefCountObject
+
+ virtual ~Buffer();
+
+- void bufferData(const void *data, GLsizeiptr size, GLenum usage);
+- void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
++ void bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target);
++ void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target);
+
+ GLenum usage() const;
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+index 320bbcc..91719f8 100644
+--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+@@ -758,7 +758,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+- buffer->bufferData(data, size, usage);
++ buffer->bufferData(data, size, usage, target);
+ }
+ }
+ catch(std::bad_alloc&)
+@@ -812,7 +812,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
+ return gl::error(GL_INVALID_VALUE);
+ }
+
+- buffer->bufferSubData(data, size, offset);
++ buffer->bufferSubData(data, size, offset, target);
+ }
+ }
+ catch(std::bad_alloc&)
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
+index ace1a11..14a8c27 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
+@@ -22,7 +22,7 @@ class BufferStorage
+
+ // The data returned is only guaranteed valid until next non-const method.
+ virtual void *getData() = 0;
+- virtual void setData(const void* data, unsigned int size, unsigned int offset) = 0;
++ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target) = 0;
+ virtual void clear() = 0;
+ virtual unsigned int getSize() const = 0;
+ virtual bool supportsDirectBinding() const = 0;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
+index 3647d8a..2f694db 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
+@@ -131,7 +131,7 @@ void *BufferStorage11::getData()
+ return mResolvedData;
+ }
+
+-void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset)
++void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset, unsigned int target)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+@@ -201,7 +201,10 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = requiredBufferSize;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+- bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
++ if (mRenderer->getFeatureLevel() > D3D_FEATURE_LEVEL_9_3)
++ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
++ else
++ bufferDesc.BindFlags = target == GL_ARRAY_BUFFER ? D3D11_BIND_VERTEX_BUFFER : D3D11_BIND_INDEX_BUFFER;
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+@@ -324,7 +327,7 @@ unsigned int BufferStorage11::getSize() const
+
+ bool BufferStorage11::supportsDirectBinding() const
+ {
+- return true;
++ return mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0;
+ }
+
+ void BufferStorage11::markBufferUsage()
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
+index b62348b..c948962 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
+@@ -24,7 +24,7 @@ class BufferStorage11 : public BufferStorage
+ static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage);
+
+ virtual void *getData();
+- virtual void setData(const void* data, unsigned int size, unsigned int offset);
++ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target);
+ virtual void clear();
+ virtual unsigned int getSize() const;
+ virtual bool supportsDirectBinding() const;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
+index e69e7a8..57fd29b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
+@@ -36,7 +36,7 @@ void *BufferStorage9::getData()
+ return mMemory;
+ }
+
+-void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset)
++void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset, unsigned int)
+ {
+ if (!mMemory || offset + size > mAllocatedSize)
+ {
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
+index 3e80396..82ae577 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
+@@ -23,7 +23,7 @@ class BufferStorage9 : public BufferStorage
+ static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage);
+
+ virtual void *getData();
+- virtual void setData(const void* data, unsigned int size, unsigned int offset);
++ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target = 0);
+ virtual void clear();
+ virtual unsigned int getSize() const;
+ virtual bool supportsDirectBinding() const;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
+index 09c8922..81e9e9e 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
+@@ -136,7 +136,7 @@ bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width,
+ mHeight = height;
+ mInternalFormat = internalformat;
+ // compute the d3d format that will be used
+- mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat);
++ mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat, mRenderer->getFeatureLevel());
+ mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat);
+
+ if (mStagingTexture)
+@@ -185,7 +185,10 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
+ switch (mInternalFormat)
+ {
+ case GL_ALPHA8_EXT:
+- loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
++ if (mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0)
++ loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
++ else
++ loadAlphaDataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_LUMINANCE8_EXT:
+ loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
+index 66604c4..36a62ad 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
+@@ -170,7 +170,7 @@ DXGI_FORMAT IndexBuffer11::getIndexFormat() const
+ {
+ case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT;
+ case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT;
+- case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT;
++ case GL_UNSIGNED_INT: return mRenderer->get32BitIndexSupport() ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
+ default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN;
+ }
+ }
+@@ -180,4 +180,4 @@ ID3D11Buffer *IndexBuffer11::getBuffer() const
+ return mBuffer;
+ }
+
+-}
+\ No newline at end of file
++}
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
+index b3111af..fd388df 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
+@@ -387,7 +387,8 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa
+ samplerDesc.BorderColor[2] = 0.0f;
+ samplerDesc.BorderColor[3] = 0.0f;
+ samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset);
+- samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset);
++ samplerDesc.MaxLOD = mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0
++ ? gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset) : FLT_MAX;
+
+ ID3D11SamplerState *dx11SamplerState = NULL;
+ HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+index d04467b..f83e9e9 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+@@ -160,9 +160,13 @@ EGLint Renderer11::initialize()
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
++ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
++ D3D_FEATURE_LEVEL_9_3,
++ D3D_FEATURE_LEVEL_9_2,
++ D3D_FEATURE_LEVEL_9_1,
+ };
+
+ HRESULT result = S_OK;
+@@ -1114,6 +1118,43 @@ void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLv
+ }
+ }
+
++template <typename T>
++static void drawLineLoopIndexed(T *data, GLenum type, const GLvoid *indices, GLsizei count)
++{
++ switch (type)
++ {
++ case GL_NONE: // Non-indexed draw
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = i;
++ }
++ data[count] = 0;
++ break;
++ case GL_UNSIGNED_BYTE:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLubyte*>(indices)[i];
++ }
++ data[count] = static_cast<const GLubyte*>(indices)[0];
++ break;
++ case GL_UNSIGNED_SHORT:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLushort*>(indices)[i];
++ }
++ data[count] = static_cast<const GLushort*>(indices)[0];
++ break;
++ case GL_UNSIGNED_INT:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLuint*>(indices)[i];
++ }
++ data[count] = static_cast<const GLuint*>(indices)[0];
++ break;
++ default: UNREACHABLE();
++ }
++}
++
+ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+ {
+ // Get the raw indices for an indexed draw
+@@ -1162,59 +1203,71 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
++ if (get32BitIndexSupport())
++ drawLineLoopIndexed(reinterpret_cast<unsigned int*>(mappedMemory), type, indices, count);
++ else
++ drawLineLoopIndexed(reinterpret_cast<unsigned short*>(mappedMemory), type, indices, count);
++
+ unsigned int indexBufferOffset = offset;
+
++ if (!mLineLoopIB->unmapBuffer())
++ {
++ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
++ return gl::error(GL_OUT_OF_MEMORY);
++ }
++
++ if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
++ {
++ IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
++
++ mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
++ mAppliedIBSerial = mLineLoopIB->getSerial();
++ mAppliedStorageIBSerial = 0;
++ mAppliedIBOffset = indexBufferOffset;
++ }
++
++ mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
++}
++
++template <typename T>
++static void drawTriangleFanIndexed(T *data, GLenum type, const GLvoid *indices, unsigned int numTris)
++{
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = i;
++ data[i*3 + 0] = 0;
++ data[i*3 + 1] = i + 1;
++ data[i*3 + 2] = i + 2;
+ }
+- data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = static_cast<const GLubyte*>(indices)[i];
++ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+ }
+- data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = static_cast<const GLushort*>(indices)[i];
++ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+ }
+- data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = static_cast<const GLuint*>(indices)[i];
++ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+ }
+- data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+-
+- if (!mLineLoopIB->unmapBuffer())
+- {
+- ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+- return gl::error(GL_OUT_OF_MEMORY);
+- }
+-
+- if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
+- {
+- IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
+-
+- mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
+- mAppliedIBSerial = mLineLoopIB->getSerial();
+- mAppliedStorageIBSerial = 0;
+- mAppliedIBOffset = indexBufferOffset;
+- }
+-
+- mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
+ }
+
+ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
+@@ -1267,45 +1320,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+- unsigned int indexBufferOffset = offset;
++ if (get32BitIndexSupport())
++ drawTriangleFanIndexed(reinterpret_cast<unsigned int*>(mappedMemory), type, indices, numTris);
++ else
++ drawTriangleFanIndexed(reinterpret_cast<unsigned short*>(mappedMemory), type, indices, numTris);
+
+- switch (type)
+- {
+- case GL_NONE: // Non-indexed draw
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = 0;
+- data[i*3 + 1] = i + 1;
+- data[i*3 + 2] = i + 2;
+- }
+- break;
+- case GL_UNSIGNED_BYTE:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+- }
+- break;
+- case GL_UNSIGNED_SHORT:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+- }
+- break;
+- case GL_UNSIGNED_INT:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+- }
+- break;
+- default: UNREACHABLE();
+- }
++ unsigned int indexBufferOffset = offset;
+
+ if (!mTriangleFanIB->unmapBuffer())
+ {
+@@ -1515,7 +1535,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
+ }
+
+ // needed for the point sprite geometry shader
+- if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
++ if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
+ {
+ mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
+ mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
+@@ -1929,9 +1949,13 @@ bool Renderer11::testDeviceResettable()
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
++ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
++ D3D_FEATURE_LEVEL_9_3,
++ D3D_FEATURE_LEVEL_9_2,
++ D3D_FEATURE_LEVEL_9_1,
+ };
+
+ ID3D11Device* dummyDevice;
+@@ -2110,11 +2134,17 @@ float Renderer11::getTextureMaxAnisotropy() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_MAX_MAXANISOTROPY;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_MAX_MAXANISOTROPY;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ return 16;
++ case D3D_FEATURE_LEVEL_9_1:
++ return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2129,11 +2159,17 @@ Range Renderer11::getViewportBounds() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
++ case D3D_FEATURE_LEVEL_9_3:
++ return Range(D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2);
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return Range(D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2);
+ default: UNREACHABLE();
+ return Range(0, 0);
+ }
+@@ -2144,10 +2180,15 @@ unsigned int Renderer11::getMaxVertexTextureImageUnits() const
+ META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return 0;
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2171,15 +2212,41 @@ unsigned int Renderer11::getReservedFragmentUniformVectors() const
+ unsigned int Renderer11::getMaxVertexUniformVectors() const
+ {
+ META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+- ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
+- return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
++ switch (mFeatureLevel)
++ {
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_10_1:
++ case D3D_FEATURE_LEVEL_10_0:
++ return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return MAX_VERTEX_UNIFORM_VECTORS_D3D9;
++ default:
++ UNIMPLEMENTED();
++ return 0;
++ }
+ }
+
+ unsigned int Renderer11::getMaxFragmentUniformVectors() const
+ {
+ META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+- ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
+- return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
++ switch (mFeatureLevel)
++ {
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_10_1:
++ case D3D_FEATURE_LEVEL_10_0:
++ return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
++ case D3D_FEATURE_LEVEL_9_3:
++ return 221;
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return 29;
++ default: UNREACHABLE();
++ return 0;
++ }
+ }
+
+ unsigned int Renderer11::getMaxVaryingVectors() const
+@@ -2187,11 +2254,17 @@ unsigned int Renderer11::getMaxVaryingVectors() const
+ META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_VS_OUTPUT_REGISTER_COUNT;
+ case D3D_FEATURE_LEVEL_10_1:
++ return D3D10_1_VS_OUTPUT_REGISTER_COUNT;
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_VS_OUTPUT_REGISTER_COUNT;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return 8;
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2201,10 +2274,15 @@ bool Renderer11::getNonPower2TextureSupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2214,10 +2292,15 @@ bool Renderer11::getOcclusionQuerySupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
+ return true;
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2227,10 +2310,15 @@ bool Renderer11::getInstancingSupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
++ case D3D_FEATURE_LEVEL_9_3:
+ return true;
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2248,10 +2336,15 @@ bool Renderer11::getDerivativeInstructionSupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
++ case D3D_FEATURE_LEVEL_9_3:
+ return true;
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2267,9 +2360,13 @@ int Renderer11::getMajorShaderModel() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ 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
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return 4; // SM4 level 9, but treat as 4
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2278,9 +2375,13 @@ int Renderer11::getMinorShaderModel() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ 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
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return 0;
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2301,11 +2402,17 @@ int Renderer11::getMaxViewportDimension() const
+
+ switch (mFeatureLevel)
+ {
+- case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
++ case D3D_FEATURE_LEVEL_9_3:
++ return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2315,9 +2422,13 @@ int Renderer11::getMaxTextureWidth() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
++ case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2326,9 +2437,13 @@ int Renderer11::getMaxTextureHeight() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
++ case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2337,9 +2452,13 @@ bool Renderer11::get32BitIndexSupport() const
+ {
+ switch (mFeatureLevel)
+ {
+- case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return false;
+ default: UNREACHABLE(); return false;
+ }
+ }
+@@ -2386,14 +2505,22 @@ unsigned int Renderer11::getMaxRenderTargets() const
+ {
+ META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
++ META_ASSERT(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
++ META_ASSERT(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
++ case D3D_FEATURE_LEVEL_9_3:
++ return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; // 4
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; // 1
+ default:
+ UNREACHABLE();
+ return 1;
+@@ -2821,7 +2948,7 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length
+
+ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type)
+ {
+- const char *profile = NULL;
++ std::string profile;
+
+ switch (type)
+ {
+@@ -2839,7 +2966,12 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
+ return NULL;
+ }
+
+- ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
++ if (mFeatureLevel == D3D_FEATURE_LEVEL_9_3)
++ profile += "_level_9_3";
++ else if (mFeatureLevel == D3D_FEATURE_LEVEL_9_2 || mFeatureLevel == D3D_FEATURE_LEVEL_9_1)
++ profile += "_level_9_1";
++
++ ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile.c_str(), D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
+ if (!binary)
+ return NULL;
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+index a7f5a39..433945d 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+@@ -32,6 +32,7 @@ class StreamingIndexBufferInterface;
+
+ enum
+ {
++ MAX_VERTEX_UNIFORM_VECTORS_D3D9 = 254,
+ MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024,
+ MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
+ };
+@@ -177,6 +178,7 @@ class Renderer11 : public Renderer
+ ID3D11Device *getDevice() { return mDevice; }
+ ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
+ IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
++ D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; }
+
+ bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
+ void unapplyRenderTargets();
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 0797fd7..9770772 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -500,12 +500,17 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+ ASSERT(SUCCEEDED(result));
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+- swapChainDesc.BufferCount = 2;
+ swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+ swapChainDesc.Width = backbufferWidth;
+ swapChainDesc.Height = backbufferHeight;
+ swapChainDesc.Stereo = FALSE;
++#if !defined(ANGLE_OS_WINPHONE)
++ swapChainDesc.BufferCount = 2;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
++#else
++ swapChainDesc.BufferCount = 1;
++ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
++#endif
+ #endif
+
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
+index 408b48e..32a407a 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
+@@ -222,14 +222,14 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
+ }
+
+ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+- : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
++ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable))
+ {
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mRenderTarget[i] = NULL;
+ }
+
+- DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
++ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel());
+ if (d3d11::IsDepthStencilFormat(convertedFormat))
+ {
+ mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+@@ -440,7 +440,7 @@ void TextureStorage11_2D::generateMipmap(int level)
+ }
+
+ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+- : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
++ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable))
+ {
+ for (unsigned int i = 0; i < 6; i++)
+ {
+@@ -450,7 +450,7 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLe
+ }
+ }
+
+- DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
++ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel());
+ if (d3d11::IsDepthStencilFormat(convertedFormat))
+ {
+ mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
+index 13800da..0624a61 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
+@@ -329,7 +329,7 @@ DXGI_FORMAT ConvertRenderbufferFormat(GLenum format)
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ }
+
+-DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
++DXGI_FORMAT ConvertTextureFormat(GLenum internalformat, D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (internalformat)
+ {
+@@ -342,7 +342,7 @@ DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case GL_ALPHA8_EXT:
+- return DXGI_FORMAT_A8_UNORM;
++ return featureLevel >= D3D_FEATURE_LEVEL_10_0 ? DXGI_FORMAT_A8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return DXGI_FORMAT_BC1_UNORM;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
+index 1bc48c1..70ad4fe 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
+@@ -32,7 +32,7 @@ FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset);
+ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
+
+ DXGI_FORMAT ConvertRenderbufferFormat(GLenum format);
+-DXGI_FORMAT ConvertTextureFormat(GLenum format);
++DXGI_FORMAT ConvertTextureFormat(GLenum format, D3D_FEATURE_LEVEL featureLevel);
+ }
+
+ namespace d3d11_gl
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
+index 042ac69..cb132dc 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
+@@ -12,10 +12,12 @@ struct PS_OutputMultiple
+ float4 color1 : SV_TARGET1;
+ float4 color2 : SV_TARGET2;
+ float4 color3 : SV_TARGET3;
++#ifdef SM4
+ float4 color4 : SV_TARGET4;
+ float4 color5 : SV_TARGET5;
+ float4 color6 : SV_TARGET6;
+ float4 color7 : SV_TARGET7;
++#endif
+ };
+
+ PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
+@@ -25,10 +27,12 @@ PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4
+ outColor.color1 = inColor;
+ outColor.color2 = inColor;
+ outColor.color3 = inColor;
++#ifdef SM4
+ outColor.color4 = inColor;
+ outColor.color5 = inColor;
+ outColor.color6 = inColor;
+ outColor.color7 = inColor;
++#endif
+ return outColor;
+ }
+
+diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro
+index ff2f888..b39ce78 100644
+--- a/src/angle/src/libGLESv2/libGLESv2.pro
++++ b/src/angle/src/libGLESv2/libGLESv2.pro
+@@ -190,7 +190,7 @@ for (ps, PIXEL_SHADERS_BLIT) {
+ QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
+ }
+ for (ps, PIXEL_SHADERS_PASSTHROUGH) {
+- fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
+ fxc_ps_$${ps}.input = PASSTHROUGH_INPUT
+ fxc_ps_$${ps}.dependency_type = TYPE_C
+@@ -199,7 +199,7 @@ for (ps, PIXEL_SHADERS_PASSTHROUGH) {
+ QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
+ }
+ for (ps, PIXEL_SHADERS_CLEAR) {
+- fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
+ fxc_ps_$${ps}.input = CLEAR_INPUT
+ fxc_ps_$${ps}.dependency_type = TYPE_C
+@@ -217,7 +217,7 @@ for (vs, VERTEX_SHADERS_BLIT) {
+ QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
+ }
+ for (vs, VERTEX_SHADERS_PASSTHROUGH) {
+- fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
+ fxc_vs_$${vs}.input = PASSTHROUGH_INPUT
+ fxc_vs_$${vs}.dependency_type = TYPE_C
+@@ -226,7 +226,7 @@ for (vs, VERTEX_SHADERS_PASSTHROUGH) {
+ QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
+ }
+ for (vs, VERTEX_SHADERS_CLEAR) {
+- fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
+ fxc_vs_$${vs}.input = CLEAR_INPUT
+ fxc_vs_$${vs}.dependency_type = TYPE_C
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch b/src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch
new file mode 100644
index 0000000000..dbe618102e
--- /dev/null
+++ b/src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch
@@ -0,0 +1,51 @@
+From 4d1906f0b81f2b61adf9640ae6cef9d503c33209 Mon Sep 17 00:00:00 2001
+From: Maurice Kalinowski <maurice.kalinowski@digia.com>
+Date: Tue, 3 Dec 2013 14:52:18 +0100
+Subject: [PATCH] ANGLE D3D11: Always execute QueryInterface
+
+ASSERT removes the condition when building for release mode. However,
+QueryInterface must be called in any case. Adopt to using ASSERT(false)
+like in other occurrences in angle.
+
+This is a follow-up patch to 331bc16afd23414493b842819e0b747e8f364243
+
+Change-Id: I4413bab06b5a529fcbd09bbc20828fcdcf4e4fc6
+---
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
+index ee8d480..99d0c1d 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
+@@ -118,7 +118,12 @@ bool Surface::resetSwapChain()
+ #else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+- ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ HRESULT result = mWindow->QueryInterface(IID_PPV_ARGS(&window));
++ if (FAILED(result))
++ {
++ ASSERT(false);
++ return false;
++ }
+ window->get_Bounds(&windowRect);
+ width = windowRect.Width;
+ height = windowRect.Height;
+@@ -342,7 +347,12 @@ bool Surface::checkForOutOfDateSwapChain()
+ #else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+- ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ HRESULT result = mWindow->QueryInterface(IID_PPV_ARGS(&window));
++ if (FAILED(result))
++ {
++ ASSERT(false);
++ return false;
++ }
+ window->get_Bounds(&windowRect);
+ int clientWidth = windowRect.Width;
+ int clientHeight = windowRect.Height;
+--
+1.7.11.msysgit.0
+
diff --git a/src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch b/src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch
new file mode 100644
index 0000000000..1955e12bf3
--- /dev/null
+++ b/src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch
@@ -0,0 +1,85 @@
+From 806fbe22a3515792b6716b5072a2131e2ce3437a Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Sat, 7 Dec 2013 23:57:39 +0200
+Subject: [PATCH] ANGLE: Dynamically load D3D compiler from a list or the
+ environment
+
+If the default compiler cannot be found, load it from a list of DLL names,
+including a non-versioned proxy DLL provided by Qt. On Desktop Windows,
+the default compiler can also be specified by an environment variable,
+QT_D3DCOMPILER_DLL.
+
+Change-Id: I0d7a8a8a36cc571836f8fa59ea14513b9b19c19b
+---
+ .../angle/src/libGLESv2/renderer/Renderer.cpp | 44 ++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 8 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+index 7ba183d..39fd0f4 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+@@ -29,12 +29,12 @@
+ #endif
+
+ #ifndef D3DCOMPILER_DLL
+-#ifndef ANGLE_OS_WINPHONE
+ #define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator
+-#else
+-#define D3DCOMPILER_DLL L"qtd3dcompiler.dll" // Placeholder DLL for phone
+-#endif // ANGLE_OS_WINPHONE
+-#endif // D3DCOMPILER_DLL
++#endif
++
++#ifndef QT_D3DCOMPILER_DLL
++#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
++#endif
+
+ #if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE)
+
+@@ -83,12 +83,40 @@ bool Renderer::initializeCompiler()
+ }
+ }
+ #else
+- // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
++ // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL
++#if !defined(ANGLE_OS_WINRT)
++ const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL");
++ if (!defaultCompiler)
++ defaultCompiler = QT_D3DCOMPILER_DLL;
++#else // !ANGLE_OS_WINRT
++# ifdef _DEBUG
++ const wchar_t *defaultCompiler = L"d3dcompiler_qtd.dll";
++# else
++ const wchar_t *defaultCompiler = L"d3dcompiler_qt.dll";
++# endif
++#endif // ANGLE_OS_WINRT
++
++ const wchar_t *compilerDlls[] = {
++ defaultCompiler,
++ L"d3dcompiler_47.dll",
++ L"d3dcompiler_46.dll",
++ L"d3dcompiler_45.dll",
++ L"d3dcompiler_44.dll",
++ L"d3dcompiler_43.dll",
++ 0
++ };
++
++ // Load the first available known compiler DLL
++ for (int i = 0; compilerDlls[i]; ++i)
++ {
+ #if !defined(ANGLE_OS_WINRT)
+- mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
++ mD3dCompilerModule = LoadLibrary(compilerDlls[i]);
+ #else
+- mD3dCompilerModule = LoadPackagedLibrary(D3DCOMPILER_DLL, NULL);
++ mD3dCompilerModule = LoadPackagedLibrary(compilerDlls[i], NULL);
+ #endif
++ if (mD3dCompilerModule)
++ break;
++ }
+ #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
+
+ if (!mD3dCompilerModule)
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch b/src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch
new file mode 100644
index 0000000000..99f458bc28
--- /dev/null
+++ b/src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch
@@ -0,0 +1,28 @@
+From 8229b84ddf0134ac11412262d23515dfb7ddb177 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Sun, 8 Dec 2013 22:50:38 +0200
+Subject: [PATCH] ANGLE D3D11: Fix build on desktop Windows
+
+This fixes a missing declaration caused by 11a2226c
+
+Change-Id: I4b8092c6b9592e886353af9193686238105a1512
+---
+ src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 9770772..2fe15ff 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -519,7 +519,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+ swapChainDesc.SampleDesc.Quality = 0;
+
+ #if !defined(ANGLE_OS_WINRT)
+- result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++ HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
+ #else
+ IDXGISwapChain1 *swapChain;
+ result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
+--
+1.8.4.msysgit.0
+