d3dcompiler_qt: Improve shader source structure

The following adjustments are made:
 - A precompiled path, defaulting to a QRC path, is added for looking
   up precompiled shaders
 - The standard service source/binary paths are created if needed, in
   order to avoid fast-fails when the service cannot create the structure
   itself fast enough.

Change-Id: I966e54c0b35bafdaf0b3a32b76eb896308aca6db
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
Andrew Knight 2014-03-31 11:14:36 +03:00 committed by The Qt Project
parent c4aabeb2b8
commit 423823dd2d

View File

@ -199,9 +199,19 @@ HRESULT WINAPI D3DCompile(
} }
static bool initialized = false; static bool initialized = false;
static QString binaryPath; static QStringList binaryPaths;
static QString sourcePath; static QString sourcePath;
if (!initialized) { 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; QString base;
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR")); base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR"));
@ -212,28 +222,33 @@ HRESULT WINAPI D3DCompile(
base = location + QStringLiteral("/d3dcompiler"); base = location + QStringLiteral("/d3dcompiler");
} }
// Unless the service has run, this directory won't exist. // Create the directory structure
QDir baseDir(base); QDir baseDir(base);
if (baseDir.exists()) { if (!baseDir.exists()) {
// Check if we have can read/write blobs baseDir.cdUp();
if (baseDir.exists(QStringLiteral("binary"))) { if (!baseDir.mkdir(QStringLiteral("d3dcompiler"))) {
binaryPath = baseDir.absoluteFilePath(QStringLiteral("binary/")); qCWarning(QT_D3DCOMPILER) << "Unable to create shader base directory:"
} else { << QDir::toNativeSeparators(baseDir.absolutePath());
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the binary directory does not.\n" if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
"Check the compiler service."; return E_FAIL;
} }
baseDir.cd(QStringLiteral("d3dcompiler"));
}
// Check if we can write shader source if (!baseDir.exists(QStringLiteral("binary")) && !baseDir.mkdir(QStringLiteral("binary"))) {
if (baseDir.exists(QStringLiteral("source"))) { qCWarning(QT_D3DCOMPILER) << "Unable to create shader binary directory:"
sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/")); << QDir::toNativeSeparators(baseDir.absoluteFilePath(QStringLiteral("binary")));
} else { if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the source directory does not.\n" return E_FAIL;
"Check the compiler service.";
}
} else { } else {
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist:" binaryPaths.append(baseDir.absoluteFilePath(QStringLiteral("binary/")));
<< QDir::toNativeSeparators(base) }
<< "\nCheck that the compiler service is running.";
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; initialized = true;
@ -254,8 +269,8 @@ HRESULT WINAPI D3DCompile(
+ QLatin1Char('!') + QString::number(sflags); + QLatin1Char('!') + QString::number(sflags);
// Check if pre-compiled shader blob is available // Check if pre-compiled shader blob is available
if (!binaryPath.isEmpty()) { foreach (const QString &path, binaryPaths) {
QString blobName = binaryPath + fileName; QString blobName = path + fileName;
QFile blob(blobName); QFile blob(blobName);
while (!blob.exists()) { while (!blob.exists()) {
// Progressively drop optional parts // Progressively drop optional parts
@ -271,6 +286,7 @@ HRESULT WINAPI D3DCompile(
return S_FALSE; return S_FALSE;
} }
qCDebug(QT_D3DCOMPILER) << "Found, but unable to open, precompiled shader blob at" << blob.fileName(); qCDebug(QT_D3DCOMPILER) << "Found, but unable to open, precompiled shader blob at" << blob.fileName();
break;
} }
} }
@ -293,7 +309,7 @@ HRESULT WINAPI D3DCompile(
QElapsedTimer timer; QElapsedTimer timer;
timer.start(); timer.start();
QFile blob(binaryPath + fileName); QFile blob(binaryPaths.last() + fileName);
while (!(blob.exists() && blob.open(QFile::ReadOnly)) && timer.elapsed() < timeout) while (!(blob.exists() && blob.open(QFile::ReadOnly)) && timer.elapsed() < timeout)
QThread::msleep(100); QThread::msleep(100);