From 72ea1d59923ffb8591a8298c2b817940db81b615 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 12 Dec 2013 10:15:16 +0100 Subject: Moved d3dcompiler from src/angle to src/angle/src Even though it is not really part of the angle implementation, having it in source is more consistent with the rest of Qt and makes browsing the code easier. There was also an issue, that only a debug build was done when calling nmake or jom. While moving the implementation this issue was fixed by including config.pri to d3dcompiler's .pro file. Change-Id: I3e3630865c94adbe1a1f1af2ccfc2bcb046002a8 Reviewed-by: Andrew Knight Reviewed-by: Joerg Bornemann --- src/angle/angle.pro | 1 - src/angle/d3dcompiler/d3dcompiler.pro | 11 - src/angle/d3dcompiler/d3dcompiler_qt.def | 3 - src/angle/d3dcompiler/d3dcompiler_qtd.def | 3 - src/angle/d3dcompiler/main.cpp | 295 -------------------------- src/angle/src/d3dcompiler/d3dcompiler.pro | 14 ++ src/angle/src/d3dcompiler/d3dcompiler_qt.def | 3 + src/angle/src/d3dcompiler/d3dcompiler_qtd.def | 3 + src/angle/src/d3dcompiler/main.cpp | 295 ++++++++++++++++++++++++++ src/angle/src/src.pro | 1 + 10 files changed, 316 insertions(+), 313 deletions(-) delete mode 100644 src/angle/d3dcompiler/d3dcompiler.pro delete mode 100644 src/angle/d3dcompiler/d3dcompiler_qt.def delete mode 100644 src/angle/d3dcompiler/d3dcompiler_qtd.def delete mode 100644 src/angle/d3dcompiler/main.cpp create mode 100644 src/angle/src/d3dcompiler/d3dcompiler.pro create mode 100644 src/angle/src/d3dcompiler/d3dcompiler_qt.def create mode 100644 src/angle/src/d3dcompiler/d3dcompiler_qtd.def create mode 100644 src/angle/src/d3dcompiler/main.cpp (limited to 'src/angle') diff --git a/src/angle/angle.pro b/src/angle/angle.pro index a8040428d1..83510698d3 100644 --- a/src/angle/angle.pro +++ b/src/angle/angle.pro @@ -1,6 +1,5 @@ TEMPLATE = subdirs SUBDIRS += src -angle_d3d11: SUBDIRS += d3dcompiler # We do it this way instead of letting load(qt_module) handle it for two reasons: # 1) qt_module_headers assumes the TARGET is the same as the include directory (eg: libGLESv2 != GLES2) diff --git a/src/angle/d3dcompiler/d3dcompiler.pro b/src/angle/d3dcompiler/d3dcompiler.pro deleted file mode 100644 index 35b9be2025..0000000000 --- a/src/angle/d3dcompiler/d3dcompiler.pro +++ /dev/null @@ -1,11 +0,0 @@ -TEMPLATE = lib -TARGET = $$qtLibraryTarget(d3dcompiler_qt) -DLLDESTDIR = $$QT_BUILD_TREE/bin - -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/d3dcompiler/d3dcompiler_qt.def b/src/angle/d3dcompiler/d3dcompiler_qt.def deleted file mode 100644 index 0b8679c8e0..0000000000 --- a/src/angle/d3dcompiler/d3dcompiler_qt.def +++ /dev/null @@ -1,3 +0,0 @@ -LIBRARY d3dcompiler_qt -EXPORTS - D3DCompile @1 diff --git a/src/angle/d3dcompiler/d3dcompiler_qtd.def b/src/angle/d3dcompiler/d3dcompiler_qtd.def deleted file mode 100644 index 0bdd0a1ffd..0000000000 --- a/src/angle/d3dcompiler/d3dcompiler_qtd.def +++ /dev/null @@ -1,3 +0,0 @@ -LIBRARY d3dcompiler_qtd -EXPORTS - D3DCompile @1 diff --git a/src/angle/d3dcompiler/main.cpp b/src/angle/d3dcompiler/main.cpp deleted file mode 100644 index 96d71d5e0d..0000000000 --- a/src/angle/d3dcompiler/main.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -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(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(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 bool serviceAvailable(const QString &path) -{ - if (path.isEmpty()) - return false; - - // Look for a file, "control", and check if it has been touched in the last 60 seconds - QFileInfo control(path + QStringLiteral("control")); - return control.exists() && control.lastModified().secsTo(QDateTime::currentDateTime()) < 60; -} - -static QString cacheKeyFor(const void *data) -{ - return QString::fromUtf8(QCryptographicHash::hash(reinterpret_cast(data), QCryptographicHash::Sha1).toHex()); -} - -static QString makePath(const QDir &parent, const QString &child) -{ - const QString path = parent.absoluteFilePath(child); - if (!parent.mkpath(child)) { - qCWarning(QT_D3DCOMPILER) << "Path is inaccessible: " << path; - return QString(); - } - return path; -} - -} // namespace D3DCompiler - -extern "C" __declspec(dllexport) HRESULT WINAPI D3DCompile( - const void *, SIZE_T, const char *, const D3D_SHADER_MACRO *, ID3DInclude *, - const char *t, 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 QString basePath; - static QString binaryPath; - static QString sourcePath; - if (basePath.isEmpty()) { - QDir base; - if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) - base.setPath(QString::fromUtf8(qgetenv("QT_D3DCOMPILER_DIR"))); - else - base.setPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); - - if (!base.exists() && !base.mkdir(QStringLiteral("."))) { - qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist: " << QDir::toNativeSeparators(base.path()); - } else { - const QString path = base.absoluteFilePath(QStringLiteral("d3dcompiler/")); - if (!QFile::exists(path) && !base.mkdir(QStringLiteral("d3dcompiler"))) - qCWarning(QT_D3DCOMPILER) << "D3D compiler path could not be created: " << QDir::toNativeSeparators(path); - else - basePath = path; - } - } - - if (!basePath.isEmpty()) { - binaryPath = D3DCompiler::makePath(basePath, QStringLiteral("binary/")); - sourcePath = D3DCompiler::makePath(basePath, QStringLiteral("source/")); - } - - // Check if pre-compiled shader blob is available - const QByteArray sourceData = QByteArray::fromRawData(reinterpret_cast(data), data_size); - const QString cacheKey = D3DCompiler::cacheKeyFor(sourceData); - QFile blob(binaryPath + cacheKey); - if (!binaryPath.isEmpty() && blob.exists()) { - 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 (D3DCompiler::serviceAvailable(basePath)) { - - if (sourcePath.isEmpty()) { - qCWarning(QT_D3DCOMPILER) << "Compiler service is available, but source directory is not writable."; - return E_ACCESSDENIED; - } - - // 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(); - 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((*shader)->GetBufferPointer()), (*shader)->GetBufferSize()); - 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/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..96d71d5e0d --- /dev/null +++ b/src/angle/src/d3dcompiler/main.cpp @@ -0,0 +1,295 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +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(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(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 bool serviceAvailable(const QString &path) +{ + if (path.isEmpty()) + return false; + + // Look for a file, "control", and check if it has been touched in the last 60 seconds + QFileInfo control(path + QStringLiteral("control")); + return control.exists() && control.lastModified().secsTo(QDateTime::currentDateTime()) < 60; +} + +static QString cacheKeyFor(const void *data) +{ + return QString::fromUtf8(QCryptographicHash::hash(reinterpret_cast(data), QCryptographicHash::Sha1).toHex()); +} + +static QString makePath(const QDir &parent, const QString &child) +{ + const QString path = parent.absoluteFilePath(child); + if (!parent.mkpath(child)) { + qCWarning(QT_D3DCOMPILER) << "Path is inaccessible: " << path; + return QString(); + } + return path; +} + +} // namespace D3DCompiler + +extern "C" __declspec(dllexport) HRESULT WINAPI D3DCompile( + const void *, SIZE_T, const char *, const D3D_SHADER_MACRO *, ID3DInclude *, + const char *t, 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 QString basePath; + static QString binaryPath; + static QString sourcePath; + if (basePath.isEmpty()) { + QDir base; + if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) + base.setPath(QString::fromUtf8(qgetenv("QT_D3DCOMPILER_DIR"))); + else + base.setPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); + + if (!base.exists() && !base.mkdir(QStringLiteral("."))) { + qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist: " << QDir::toNativeSeparators(base.path()); + } else { + const QString path = base.absoluteFilePath(QStringLiteral("d3dcompiler/")); + if (!QFile::exists(path) && !base.mkdir(QStringLiteral("d3dcompiler"))) + qCWarning(QT_D3DCOMPILER) << "D3D compiler path could not be created: " << QDir::toNativeSeparators(path); + else + basePath = path; + } + } + + if (!basePath.isEmpty()) { + binaryPath = D3DCompiler::makePath(basePath, QStringLiteral("binary/")); + sourcePath = D3DCompiler::makePath(basePath, QStringLiteral("source/")); + } + + // Check if pre-compiled shader blob is available + const QByteArray sourceData = QByteArray::fromRawData(reinterpret_cast(data), data_size); + const QString cacheKey = D3DCompiler::cacheKeyFor(sourceData); + QFile blob(binaryPath + cacheKey); + if (!binaryPath.isEmpty() && blob.exists()) { + 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 (D3DCompiler::serviceAvailable(basePath)) { + + if (sourcePath.isEmpty()) { + qCWarning(QT_D3DCOMPILER) << "Compiler service is available, but source directory is not writable."; + return E_ACCESSDENIED; + } + + // 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(); + 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((*shader)->GetBufferPointer()), (*shader)->GetBufferSize()); + 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/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 -- cgit v1.2.3