Remove d3dcompiler_qt

This library was created as a work around for limitations on Windows
Phone 8.0, which will not be supported going forward (Qt 5.4). Therefore,
we no longer need (or want to maintain) this experimental feature and
should remove it from the repository.

Change-Id: Ia417833f9de43e2d3e0940df93625e7d87a555ea
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
Andrew Knight 2014-07-19 11:57:13 +03:00
parent 1e72704d88
commit a93bfc1ebe
7 changed files with 0 additions and 725 deletions

View File

@ -1,17 +0,0 @@
TARGET = d3dcompiler_qt
CONFIG += installed
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
winrt:equals(WINSDK_VER, 8.1) {
DEFINES += D3DCOMPILER_LINKED
LIBS += -ld3dcompiler
}
# __stdcall exports get mangled, so use a def file
DEF_FILE += $${TARGET}.def

View File

@ -1,3 +0,0 @@
LIBRARY d3dcompiler_qt
EXPORTS
D3DCompile @1

View File

@ -1,3 +0,0 @@
LIBRARY d3dcompiler_qtd
EXPORTS
D3DCompile @1

View File

@ -1,328 +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 <QByteArray>
#include <QCryptographicHash>
#include <QDateTime>
#include <QDir>
#include <QElapsedTimer>
#include <QFile>
#include <QLoggingCategory>
#include <QStandardPaths>
#include <QThread>
#include <qt_windows.h>
#include <d3dcommon.h>
#ifdef D3DCOMPILER_LINKED
namespace D3D {
# include <d3dcompiler.h>
}
#endif // D3DCOMPILER_LINKED
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()
{
#ifndef D3DCOMPILER_LINKED
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.";
}
#else // !D3DCOMPILER_LINKED
compile = &D3D::D3DCompile;
#endif // D3DCOMPILER_LINKED
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)
{
// Shortcut to compile using the runtime compiler if it is available
static bool compilerAvailable =
!qgetenv("QT_D3DCOMPILER_DISABLE_DLL").toInt() && D3DCompiler::loadCompiler();
if (compilerAvailable) {
HRESULT hr = D3DCompiler::compile(data, data_size, filename, defines, include, entrypoint,
target, sflags, eflags, shader, errorMsgs);
return hr;
}
static bool initialized = false;
static QStringList binaryPaths;
static QString sourcePath;
if (!initialized) {
// Precompiled directory
QString precompiledPath;
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_BINARY_DIR"))
precompiledPath = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_BINARY_DIR"));
else
precompiledPath = QStringLiteral(":/qt.d3dcompiler/"); // Default QRC path
if (QDir(precompiledPath).exists())
binaryPaths.append(precompiledPath);
// Service directory
QString base;
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR"));
if (base.isEmpty()) {
const QString location = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
if (!location.isEmpty())
base = location + QStringLiteral("/d3dcompiler");
}
// Create the directory structure
QDir baseDir(base);
if (!baseDir.exists()) {
baseDir.cdUp();
if (!baseDir.mkdir(QStringLiteral("d3dcompiler"))) {
qCWarning(QT_D3DCOMPILER) << "Unable to create shader base directory:"
<< QDir::toNativeSeparators(baseDir.absolutePath());
if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
return E_FAIL;
}
baseDir.cd(QStringLiteral("d3dcompiler"));
}
if (!baseDir.exists(QStringLiteral("binary")) && !baseDir.mkdir(QStringLiteral("binary"))) {
qCWarning(QT_D3DCOMPILER) << "Unable to create shader binary directory:"
<< QDir::toNativeSeparators(baseDir.absoluteFilePath(QStringLiteral("binary")));
if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
return E_FAIL;
} else {
binaryPaths.append(baseDir.absoluteFilePath(QStringLiteral("binary/")));
}
if (!baseDir.exists(QStringLiteral("source")) && !baseDir.mkdir(QStringLiteral("source"))) {
qCWarning(QT_D3DCOMPILER) << "Unable to create shader source directory:"
<< QDir::toNativeSeparators(baseDir.absoluteFilePath(QStringLiteral("source")));
} else {
sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/"));
}
initialized = true;
}
QByteArray macros;
if (const D3D_SHADER_MACRO *macro = defines) {
while (macro) {
macros.append('#').append(macro->Name).append(' ').append(macro->Definition).append('\n');
++macro;
}
}
const QByteArray sourceData = macros + QByteArray::fromRawData(reinterpret_cast<const char *>(data), data_size);
const QString fileName = D3DCompiler::cacheKeyFor(sourceData)
+ QLatin1Char('!') + QString::fromUtf8(entrypoint)
+ QLatin1Char('!') + QString::fromUtf8(target)
+ QLatin1Char('!') + QString::number(sflags);
// Check if pre-compiled shader blob is available
foreach (const QString &path, binaryPaths) {
QString blobName = path + fileName;
QFile blob(blobName);
while (!blob.exists()) {
// Progressively drop optional parts
blobName.truncate(blobName.lastIndexOf(QLatin1Char('!')));
if (blobName.isEmpty())
break;
blob.setFileName(blobName);
}
if (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();
break;
}
}
// Shader blob is not available; write out shader source
if (!sourcePath.isEmpty()) {
// Dump source to source path; wait for blob to appear
QFile source(sourcePath + fileName);
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(binaryPaths.last() + fileName);
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;
}
*errorMsgs = new D3DCompiler::Blob("No shader compiler or service could be found.");
return E_FAIL;
}

View File

@ -1,4 +1,3 @@
TEMPLATE = subdirs
SUBDIRS += compiler libGLESv2 libEGL
angle_d3d11: SUBDIRS += d3dcompiler
CONFIG += ordered

View File

@ -1,5 +0,0 @@
CONFIG += testcase
TARGET = tst_d3dcompiler
QT = core testlib
SOURCES = tst_d3dcompiler.cpp

View File

@ -1,368 +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 test suite 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$
**
****************************************************************************/
// This test verifies the behavior of d3dcompiler_qt, which is only built when ANGLE is enabled
#include <QCryptographicHash>
#include <QDir>
#include <QFuture>
#include <QObject>
#include <QStandardPaths>
#include <QTemporaryDir>
#include <QTest>
#include <QThread>
#if defined(Q_OS_WIN)
#include <d3dcommon.h>
#ifndef Q_OS_WINRT
#define loadLibrary(library) LoadLibrary(library)
#else
#define loadLibrary(library) LoadPackagedLibrary(library, NULL)
#endif
#ifdef D3DCOMPILER_DLL
#undef D3DCOMPILER_DLL
#endif
#ifdef QT_NO_DEBUG
#define D3DCOMPILER_DLL L"d3dcompiler_qt"
#else
#define D3DCOMPILER_DLL L"d3dcompiler_qtd"
#endif
#define getCompilerFunc(dll) reinterpret_cast<D3DCompileFunc>(GetProcAddress(dll, "D3DCompile"))
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 const wchar_t *compilerDlls[] = {
L"d3dcompiler_47.dll",
L"d3dcompiler_46.dll",
L"d3dcompiler_45.dll",
L"d3dcompiler_44.dll",
L"d3dcompiler_43.dll",
0
};
static const char hlsl[] =
"uniform SamplerState Sampler : register(s0);\n"
"uniform Texture2D Texture : register(t0);\n"
"float4 main(in float4 gl_Position : SV_POSITION, in float2 coord : TEXCOORD0) : SV_TARGET0\n"
"{\n"
"return Texture.Sample(Sampler, coord);\n"
"}\n";
static inline QByteArray blobToByteArray(ID3DBlob *blob)
{
return blob ? QByteArray::fromRawData(reinterpret_cast<const char *>(blob->GetBufferPointer()), blob->GetBufferSize()) : QByteArray();
}
class CompileRunner : public QThread
{
public:
CompileRunner(D3DCompileFunc d3dCompile, const QByteArray &data, ID3DBlob **shader, ID3DBlob **error)
: m_d3dCompile(d3dCompile), m_data(data), m_shader(shader), m_error(error)
{
}
HRESULT result() const
{
return m_result;
}
private:
void run()
{
m_result = m_d3dCompile(m_data.constData(), m_data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, m_shader, m_error);
}
HRESULT m_result;
D3DCompileFunc m_d3dCompile;
QByteArray m_data;
ID3DBlob **m_shader;
ID3DBlob **m_error;
};
class tst_d3dcompiler : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void init();
void cleanup();
void service_data();
void service();
void offlineCompile();
void onlineCompile();
private:
QString blobPath();
HMODULE d3dcompiler_qt;
HMODULE d3dcompiler_win;
D3DCompileFunc d3dCompile;
QTemporaryDir tempDir;
};
QString tst_d3dcompiler::blobPath()
{
QDir path;
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
path.setPath(qgetenv("QT_D3DCOMPILER_DIR"));
else
path.setPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QStringLiteral("/d3dcompiler"));
path.mkdir(QStringLiteral("binary"));
path.mkdir(QStringLiteral("source"));
return path.absolutePath();
}
void tst_d3dcompiler::initTestCase()
{
QVERIFY(tempDir.isValid());
}
void tst_d3dcompiler::init()
{
qunsetenv("QT_D3DCOMPILER_DIR");
qunsetenv("QT_D3DCOMPILER_TIMEOUT");
qunsetenv("QT_D3DCOMPILER_DISABLE_DLL");
}
void tst_d3dcompiler::cleanup()
{
FreeLibrary(d3dcompiler_qt);
FreeLibrary(d3dcompiler_win);
QDir path(blobPath());
foreach (const QString &entry, path.entryList(QStringList(), QDir::Files|QDir::NoDotAndDotDot))
path.remove(entry);
foreach (const QString &entry, path.entryList(QStringList(), QDir::Dirs|QDir::NoDotAndDotDot)) {
QDir dir(path.absoluteFilePath(entry + QStringLiteral("/")));
dir.removeRecursively();
}
}
void tst_d3dcompiler::service_data()
{
QTest::addColumn<QByteArray>("compilerDir");
QTest::addColumn<bool>("exists");
QTest::addColumn<HRESULT>("result");
// Don't test the default case, as it would clutter the AppData directory
//QTest::newRow("default") << QByteArrayLiteral("") << true << E_ABORT;
QTest::newRow("temporary") << QFile::encodeName(tempDir.path()) << true << E_ABORT;
QTest::newRow("invalid") << QByteArrayLiteral("ZZ:\\") << false << E_FAIL;
QTest::newRow("empty") << QByteArrayLiteral("") << false << E_FAIL;
}
void tst_d3dcompiler::service()
{
QFETCH(QByteArray, compilerDir);
QFETCH(bool, exists);
QFETCH(HRESULT, result);
qputenv("QT_D3DCOMPILER_DIR", compilerDir);
qputenv("QT_D3DCOMPILER_DISABLE_DLL", QByteArrayLiteral("1"));
const QDir path = blobPath();
if (exists) {
// Activate service
QVERIFY(path.exists());
} else {
QVERIFY(!path.exists());
}
// Run compiler (fast fail)
d3dcompiler_qt = loadLibrary(D3DCOMPILER_DLL);
QVERIFY(d3dcompiler_qt);
d3dCompile = getCompilerFunc(d3dcompiler_qt);
QVERIFY(d3dCompile);
qputenv("QT_D3DCOMPILER_TIMEOUT", "1");
const QByteArray data(hlsl);
ID3DBlob *shader = 0, *errorMessage = 0;
HRESULT hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &shader, &errorMessage);
QVERIFY2(hr == result, blobToByteArray(errorMessage));
// Check that passthrough works
if (hr == S_OK) {
for (int i = 0; compilerDlls[i]; ++i) {
d3dcompiler_win = loadLibrary(compilerDlls[i]);
if (d3dcompiler_win)
break;
}
QVERIFY(d3dcompiler_win);
d3dCompile = getCompilerFunc(d3dcompiler_win);
QVERIFY(d3dCompile);
// Compile a shader to compare with
ID3DBlob *reference = 0;
HRESULT hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &reference, &errorMessage);
QVERIFY2(SUCCEEDED(hr), blobToByteArray(errorMessage));
QByteArray shaderData(reinterpret_cast<const char *>(shader->GetBufferPointer()), shader->GetBufferSize());
QByteArray referenceData(reinterpret_cast<const char *>(reference->GetBufferPointer()), reference->GetBufferSize());
reference->Release();
QCOMPARE(shaderData, referenceData);
} else {
QVERIFY(FAILED(hr));
}
if (shader)
shader->Release();
}
void tst_d3dcompiler::offlineCompile()
{
qputenv("QT_D3DCOMPILER_DIR", QFile::encodeName(tempDir.path()));
qputenv("QT_D3DCOMPILER_DISABLE_DLL", QByteArrayLiteral("1"));
for (int i = 0; compilerDlls[i]; ++i) {
d3dcompiler_win = loadLibrary(compilerDlls[i]);
if (d3dcompiler_win)
break;
}
QVERIFY(d3dcompiler_win);
d3dCompile = getCompilerFunc(d3dcompiler_win);
QVERIFY(d3dCompile);
// Compile a shader to place in binary directory
const QByteArray data(hlsl);
ID3DBlob *shader = 0, *errorMessage = 0;
HRESULT hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &shader, &errorMessage);
QVERIFY2(SUCCEEDED(hr), blobToByteArray(errorMessage));
QVERIFY(shader);
QDir outputPath(blobPath());
QVERIFY(outputPath.exists());
QVERIFY(outputPath.exists(QStringLiteral("binary")));
outputPath.cd(QStringLiteral("binary"));
QFile output(outputPath.absoluteFilePath(QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex()));
QVERIFY(output.open(QFile::WriteOnly));
output.write(reinterpret_cast<const char *>(shader->GetBufferPointer()), shader->GetBufferSize());
shader->Release();
// Run compiler
d3dcompiler_qt = loadLibrary(D3DCOMPILER_DLL);
QVERIFY(d3dcompiler_qt);
d3dCompile = getCompilerFunc(d3dcompiler_qt);
QVERIFY(d3dCompile);
hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &shader, &errorMessage);
// Returns S_FALSE if a cached shader was found
QVERIFY2(hr == S_FALSE, blobToByteArray(errorMessage));
}
void tst_d3dcompiler::onlineCompile()
{
qputenv("QT_D3DCOMPILER_DIR", QFile::encodeName(tempDir.path()));
qputenv("QT_D3DCOMPILER_TIMEOUT", QByteArray::number(3000));
qputenv("QT_D3DCOMPILER_DISABLE_DLL", QByteArrayLiteral("1"));
QByteArray data(hlsl);
const QDir path = blobPath();
// Activate service
QVERIFY(path.exists());
d3dcompiler_qt = loadLibrary(D3DCOMPILER_DLL);
QVERIFY(d3dcompiler_qt);
D3DCompileFunc concurrentCompile = getCompilerFunc(d3dcompiler_qt);
QVERIFY(d3dCompile);
// Run async
ID3DBlob *shader = 0, *errorMessage = 0;
CompileRunner runner(concurrentCompile, data, &shader, &errorMessage);
runner.start();
// Wait for source to appear
QVERIFY(path.exists());
QVERIFY(path.exists(QStringLiteral("source")));
QVERIFY(path.exists(QStringLiteral("binary")));
const QString fileName = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex()
+ QStringLiteral("!main!ps_4_0!0");
QFile input(path.absoluteFilePath(QStringLiteral("source/") + fileName));
QTRY_VERIFY_WITH_TIMEOUT(input.exists(), 3000);
QTRY_VERIFY_WITH_TIMEOUT(input.isOpen() || input.open(QFile::ReadOnly), 1000);
// Compile passed source
const QByteArray inputData = input.readAll();
for (int i = 0; compilerDlls[i]; ++i) {
d3dcompiler_win = loadLibrary(compilerDlls[i]);
if (d3dcompiler_win)
break;
}
QVERIFY(d3dcompiler_win);
d3dCompile = getCompilerFunc(d3dcompiler_win);
QVERIFY(d3dCompile);
ID3DBlob *reference = 0, *errorMessage2 = 0;
HRESULT hr = d3dCompile(inputData.constData(), inputData.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &reference, &errorMessage2);
QVERIFY2(SUCCEEDED(hr), blobToByteArray(errorMessage2));
const QByteArray referenceData(reinterpret_cast<const char *>(reference->GetBufferPointer()), reference->GetBufferSize());
reference->Release();
// Write to output directory
QFile output(path.absoluteFilePath(QStringLiteral("binary/") + fileName));
QVERIFY(output.open(QFile::WriteOnly));
output.write(referenceData);
output.close();
// All done
QVERIFY(runner.wait(3000));
hr = runner.result();
QVERIFY2(hr == S_FALSE, blobToByteArray(errorMessage2));
const QByteArray resultData(reinterpret_cast<const char *>(shader->GetBufferPointer()), shader->GetBufferSize());
shader->Release();
QVERIFY(referenceData == resultData);
}
QTEST_MAIN(tst_d3dcompiler)
#include "tst_d3dcompiler.moc"
#endif // Q_OS_WIN