d3dcompiler_qt: Remove control file semantics
This simplifies the compiler control semantics by always using the packaged compiler if it is available. With no packaged compiler, the service is assumed to be running if the directory structure is present. Use of a packaged library can be overridden by setting the environment variable QT_D3DCOMPILER_DISABLE_DLL to 1. When the runtime compiler is used, the source will no longer be logged, and the compilation output will no longer be cached. Change-Id: Ib07f517e7043d7785bdfa9da55abd34df518eeed Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
parent
bcfc68f9cd
commit
42afaa992a
@ -180,22 +180,32 @@ HRESULT WINAPI D3DCompile(
|
||||
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 bool serviceAvailable = false;
|
||||
static QString binaryPath;
|
||||
static QString sourcePath;
|
||||
if (!initialized) {
|
||||
QString base;
|
||||
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) {
|
||||
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
|
||||
base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR"));
|
||||
} else {
|
||||
|
||||
if (base.isEmpty()) {
|
||||
const QString location = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
if (!location.isEmpty())
|
||||
base = location + QStringLiteral("/d3dcompiler");
|
||||
}
|
||||
|
||||
// Unless the service has run, this directory won't exist.
|
||||
QDir baseDir(base);
|
||||
if (!base.isEmpty() && baseDir.exists()) {
|
||||
if (baseDir.exists()) {
|
||||
// Check if we have can read/write blobs
|
||||
if (baseDir.exists(QStringLiteral("binary"))) {
|
||||
binaryPath = baseDir.absoluteFilePath(QStringLiteral("binary/"));
|
||||
@ -211,14 +221,10 @@ HRESULT WINAPI D3DCompile(
|
||||
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.";
|
||||
<< "\nCheck that the compiler service is running.";
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
@ -259,8 +265,8 @@ HRESULT WINAPI D3DCompile(
|
||||
}
|
||||
}
|
||||
|
||||
// Shader blob is not available, compile with compilation service if possible
|
||||
if (!sourcePath.isEmpty() && serviceAvailable) {
|
||||
// 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)) {
|
||||
@ -292,24 +298,6 @@ HRESULT WINAPI D3DCompile(
|
||||
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 + fileName);
|
||||
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.");
|
||||
*errorMsgs = new D3DCompiler::Blob("No shader compiler or service could be found.");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
@ -170,6 +170,7 @@ void tst_d3dcompiler::init()
|
||||
{
|
||||
qunsetenv("QT_D3DCOMPILER_DIR");
|
||||
qunsetenv("QT_D3DCOMPILER_TIMEOUT");
|
||||
qunsetenv("QT_D3DCOMPILER_DISABLE_DLL");
|
||||
}
|
||||
|
||||
void tst_d3dcompiler::cleanup()
|
||||
@ -195,8 +196,8 @@ void tst_d3dcompiler::service_data()
|
||||
// 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 << S_OK;
|
||||
QTest::newRow("empty") << QByteArrayLiteral("") << false << S_OK;
|
||||
QTest::newRow("invalid") << QByteArrayLiteral("ZZ:\\") << false << E_FAIL;
|
||||
QTest::newRow("empty") << QByteArrayLiteral("") << false << E_FAIL;
|
||||
}
|
||||
|
||||
void tst_d3dcompiler::service()
|
||||
@ -205,16 +206,12 @@ void tst_d3dcompiler::service()
|
||||
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());
|
||||
|
||||
QFile control(path.absoluteFilePath(QStringLiteral("control")));
|
||||
QVERIFY(control.open(QFile::WriteOnly));
|
||||
control.close();
|
||||
QVERIFY(control.exists());
|
||||
} else {
|
||||
QVERIFY(!path.exists());
|
||||
}
|
||||
@ -262,6 +259,7 @@ void tst_d3dcompiler::service()
|
||||
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]);
|
||||
@ -302,6 +300,8 @@ void tst_d3dcompiler::offlineCompile()
|
||||
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);
|
||||
|
||||
@ -309,10 +309,6 @@ void tst_d3dcompiler::onlineCompile()
|
||||
|
||||
// Activate service
|
||||
QVERIFY(path.exists());
|
||||
QFile control(path.absoluteFilePath(QStringLiteral("control")));
|
||||
QVERIFY(control.open(QFile::WriteOnly));
|
||||
control.close();
|
||||
QVERIFY(control.exists());
|
||||
|
||||
d3dcompiler_qt = loadLibrary(D3DCOMPILER_DLL);
|
||||
QVERIFY(d3dcompiler_qt);
|
||||
|
Loading…
Reference in New Issue
Block a user