diff options
Diffstat (limited to 'src/angle/src')
-rw-r--r-- | src/angle/src/common/common.pri | 2 | ||||
-rw-r--r-- | src/angle/src/compiler/translator_common.pro | 7 | ||||
-rw-r--r-- | src/angle/src/config.pri | 5 | ||||
-rw-r--r-- | src/angle/src/d3dcompiler/d3dcompiler.pro | 14 | ||||
-rw-r--r-- | src/angle/src/d3dcompiler/d3dcompiler_qt.def | 3 | ||||
-rw-r--r-- | src/angle/src/d3dcompiler/d3dcompiler_qtd.def | 3 | ||||
-rw-r--r-- | src/angle/src/d3dcompiler/main.cpp | 294 | ||||
-rw-r--r-- | src/angle/src/libGLESv2/libGLESv2.pro | 8 | ||||
-rw-r--r-- | src/angle/src/src.pro | 1 |
9 files changed, 329 insertions, 8 deletions
diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri index 514c80dbd1..58ad88673a 100644 --- a/src/angle/src/common/common.pri +++ b/src/angle/src/common/common.pri @@ -7,7 +7,7 @@ INCLUDEPATH += \ LIBS_PRIVATE = $$QMAKE_LIBS_CORE $$QMAKE_LIBS_GUI # DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK. -win32-msvc2012|win32-msvc2013 { +win32-msvc2012|win32-msvc2013|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 b2812158e1..5581c9dc58 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 1c6d8b0167..ed2558117e 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 \ diff --git a/src/angle/src/d3dcompiler/d3dcompiler.pro b/src/angle/src/d3dcompiler/d3dcompiler.pro new file mode 100644 index 0000000000..0ee3d1f72d --- /dev/null +++ b/src/angle/src/d3dcompiler/d3dcompiler.pro @@ -0,0 +1,14 @@ +TEMPLATE = lib +TARGET = $$qtLibraryTarget(d3dcompiler_qt) +DLLDESTDIR = $$QT_BUILD_TREE/bin + +include(../config.pri) +CONFIG += qt + +QT = core +DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII +SOURCES += main.cpp +win32:!winrt: LIBS += -lole32 + +# __stdcall exports get mangled, so use a def file +DEF_FILE += $${TARGET}.def diff --git a/src/angle/src/d3dcompiler/d3dcompiler_qt.def b/src/angle/src/d3dcompiler/d3dcompiler_qt.def new file mode 100644 index 0000000000..0b8679c8e0 --- /dev/null +++ b/src/angle/src/d3dcompiler/d3dcompiler_qt.def @@ -0,0 +1,3 @@ +LIBRARY d3dcompiler_qt +EXPORTS + D3DCompile @1 diff --git a/src/angle/src/d3dcompiler/d3dcompiler_qtd.def b/src/angle/src/d3dcompiler/d3dcompiler_qtd.def new file mode 100644 index 0000000000..0bdd0a1ffd --- /dev/null +++ b/src/angle/src/d3dcompiler/d3dcompiler_qtd.def @@ -0,0 +1,3 @@ +LIBRARY d3dcompiler_qtd +EXPORTS + D3DCompile @1 diff --git a/src/angle/src/d3dcompiler/main.cpp b/src/angle/src/d3dcompiler/main.cpp new file mode 100644 index 0000000000..3f00df63eb --- /dev/null +++ b/src/angle/src/d3dcompiler/main.cpp @@ -0,0 +1,294 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QByteArray> +#include <QCryptographicHash> +#include <QDateTime> +#include <QDir> +#include <QElapsedTimer> +#include <QFile> +#include <QLoggingCategory> +#include <QStandardPaths> +#include <QThread> + +#include <qt_windows.h> +#include <d3dcommon.h> + +Q_LOGGING_CATEGORY(QT_D3DCOMPILER, "qt.angle.d3dcompiler") + +namespace D3DCompiler { + +typedef HRESULT (WINAPI *D3DCompileFunc)(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); +static D3DCompileFunc compile; + +class Blob : public ID3DBlob +{ +public: + Blob(const QByteArray &data) : m_data(data) + { + IIDFromString(L"00000000-0000-0000-C000-000000000046", &IID_IUnknown); + IIDFromString(L"8BA5FB08-5195-40e2-AC58-0D989C3A0102", &IID_ID3DBlob); + } + + virtual ~Blob() + { + } + + // ID3DBlob + LPVOID __stdcall GetBufferPointer() + { + return m_data.data(); + } + + SIZE_T __stdcall GetBufferSize() + { + return m_data.size(); + } + + // IUnknown + HRESULT __stdcall QueryInterface(REFIID riid, void **ppv) + { + IUnknown *out = 0; + if (riid == IID_IUnknown) + out = static_cast<IUnknown*>(this); + else if (riid == IID_ID3DBlob) + out = this; + + *ppv = out; + if (!out) + return E_NOINTERFACE; + + out->AddRef(); + return S_OK; + } + + ULONG __stdcall AddRef() + { + return ++m_ref; + } + + ULONG __stdcall Release() + { + ULONG ref = --m_ref; + if (!m_ref) + delete this; + + return ref; + } + +private: + QByteArray m_data; + ULONG m_ref; + + // These symbols might be missing, so define them here + IID IID_IUnknown; + IID IID_ID3DBlob; +}; + +static bool loadCompiler() +{ + static HMODULE d3dcompiler = 0; + if (!d3dcompiler) { + const wchar_t *dllNames[] = { + L"d3dcompiler_47.dll", + L"d3dcompiler_46.dll", + L"d3dcompiler_45.dll", + L"d3dcompiler_44.dll", + L"d3dcompiler_43.dll", + 0 + }; + for (int i = 0; const wchar_t *name = dllNames[i]; ++i) { +#ifndef Q_OS_WINRT + d3dcompiler = LoadLibrary(name); +#else + d3dcompiler = LoadPackagedLibrary(name, NULL); +#endif + if (d3dcompiler) { + qCDebug(QT_D3DCOMPILER) << "Found" << QString::fromWCharArray(name); + D3DCompiler::compile = reinterpret_cast<D3DCompiler::D3DCompileFunc>(GetProcAddress(d3dcompiler, "D3DCompile")); + if (D3DCompiler::compile) { + qCDebug(QT_D3DCOMPILER) << "Loaded" << QString::fromWCharArray(name); + break; + } + qCDebug(QT_D3DCOMPILER) << "Failed to load" << QString::fromWCharArray(name); + } + } + + if (!d3dcompiler) + qCDebug(QT_D3DCOMPILER) << "Unable to load D3D shader compiler."; + } + + return bool(compile); +} + +static QString cacheKeyFor(const void *data) +{ + return QString::fromUtf8(QCryptographicHash::hash(reinterpret_cast<const char *>(data), QCryptographicHash::Sha1).toHex()); +} + +} // namespace D3DCompiler + +#ifdef __MINGW32__ +extern "C" +#endif +__declspec(dllexport) HRESULT WINAPI D3DCompile( + const void *, SIZE_T, const char *, const D3D_SHADER_MACRO *, ID3DInclude *, + const char *, const char *, UINT, UINT, ID3DBlob **, ID3DBlob **); + +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 **errorMsgs) +{ + static bool initialized = false; + static bool serviceAvailable = false; + static QString binaryPath; + static QString sourcePath; + if (!initialized) { + QString base; + if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) { + base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR")); + } else { + const QString location = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + if (!location.isEmpty()) + base = location + QStringLiteral("/d3dcompiler"); + } + + QDir baseDir(base); + if (!base.isEmpty() && baseDir.exists()) { + // Check if we have can read/write blobs + if (baseDir.exists(QStringLiteral("binary"))) { + binaryPath = baseDir.absoluteFilePath(QStringLiteral("binary/")); + } else { + qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the binary directory does not.\n" + "Check the compiler service."; + } + + // Check if we can write shader source + if (baseDir.exists(QStringLiteral("source"))) { + sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/")); + } else { + qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the source directory does not.\n" + "Check the compiler service."; + } + + // Look for a file, "control", and check if it has been touched in the last 60 seconds + QFileInfo control(baseDir.absoluteFilePath(QStringLiteral("control"))); + serviceAvailable = control.exists() && control.lastModified().secsTo(QDateTime::currentDateTime()) < 60; + } else { + qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist:" + << QDir::toNativeSeparators(base) + << "\nThe compiler service won't be used."; + } + + initialized = true; + } + + const QByteArray sourceData = QByteArray::fromRawData(reinterpret_cast<const char *>(data), data_size); + const QString cacheKey = D3DCompiler::cacheKeyFor(sourceData); + + // Check if pre-compiled shader blob is available + if (!binaryPath.isEmpty()) { + QFile blob(binaryPath + cacheKey); + if (blob.open(QFile::ReadOnly)) { + qCDebug(QT_D3DCOMPILER) << "Opening precompiled shader blob at" << blob.fileName(); + *shader = new D3DCompiler::Blob(blob.readAll()); + return S_FALSE; + } + qCDebug(QT_D3DCOMPILER) << "Found, but unable to open, precompiled shader blob at" << blob.fileName(); + } + + // Shader blob is not available, compile with compilation service if possible + if (!sourcePath.isEmpty() && serviceAvailable) { + // Dump source to source path; wait for blob to appear + QFile source(sourcePath + cacheKey); + if (!source.open(QFile::WriteOnly)) { + qCDebug(QT_D3DCOMPILER) << "Unable to write shader source to file:" << source.fileName() << source.errorString(); + return E_ACCESSDENIED; + } + + source.write(sourceData); + qCDebug(QT_D3DCOMPILER) << "Wrote shader source, waiting for blob:" << source.fileName(); + source.close(); + + qint64 timeout = qgetenv("QT_D3DCOMPILER_TIMEOUT").toLong(); + if (!timeout) + timeout = 3000; + + QElapsedTimer timer; + timer.start(); + QFile blob(binaryPath + cacheKey); + while (!(blob.exists() && blob.open(QFile::ReadOnly)) && timer.elapsed() < timeout) + QThread::msleep(100); + + if (blob.isOpen()) { + *shader = new D3DCompiler::Blob(blob.readAll()); + return S_FALSE; + } + + qCDebug(QT_D3DCOMPILER) << "Shader blob failed to materialize after" << timeout << "ms."; + *errorMsgs = new D3DCompiler::Blob("Shader compilation timeout."); + return E_ABORT; + } + + // Fall back to compiler DLL + if (D3DCompiler::loadCompiler()) { + HRESULT hr = D3DCompiler::compile(data, data_size, filename, defines, include, entrypoint, + target, sflags, eflags, shader, errorMsgs); + // Cache shader + if (SUCCEEDED(hr) && !binaryPath.isEmpty()) { + const QByteArray blobContents = QByteArray::fromRawData( + reinterpret_cast<const char *>((*shader)->GetBufferPointer()), (*shader)->GetBufferSize()); + + QFile blob(binaryPath + cacheKey); + if (blob.open(QFile::WriteOnly) && blob.write(blobContents)) + qCDebug(QT_D3DCOMPILER) << "Cached shader blob at" << blob.fileName(); + else + qCDebug(QT_D3DCOMPILER) << "Unable to write shader blob at" << blob.fileName(); + } + return hr; + } + + *errorMsgs = new D3DCompiler::Blob("Unable to load D3D compiler DLL."); + return E_FAIL; +} diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro index 5d54c0f86a..5b3a49ed56 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 diff --git a/src/angle/src/src.pro b/src/angle/src/src.pro index d1f5f57591..2b7d523207 100644 --- a/src/angle/src/src.pro +++ b/src/angle/src/src.pro @@ -1,3 +1,4 @@ TEMPLATE = subdirs SUBDIRS += compiler libGLESv2 libEGL +angle_d3d11: SUBDIRS += d3dcompiler CONFIG += ordered |