aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-06-28 15:42:53 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-06-29 12:00:05 +0000
commitb87fd4752afd6b559d69ec2e08b2e3df69373b9e (patch)
tree49497c0aefb1fdb379f69c9f96ee4cfb596defb0
parentee595e9c0a4a24733195db22244cbf17b8514f72 (diff)
D3D12: Add support for shader sources in files
Now we support all combinations: source strings, HLSL source in files and bytecode in files. The type of file contents is detected automatically. Change-Id: Id6ab269df52463fb95a9a1ef2598ed5576a873d3 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp2
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp36
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc15
3 files changed, 37 insertions, 16 deletions
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp
index 7e62421380..84b12303d9 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12rendercontext.cpp
@@ -153,7 +153,7 @@ QSGRendererInterface::ShaderCompilationTypes QSGD3D12RenderContext::shaderCompil
QSGRendererInterface::ShaderSourceTypes QSGD3D12RenderContext::shaderSourceType() const
{
- return ShaderSourceString | ShaderByteCode;
+ return ShaderSourceString | ShaderSourceFile | ShaderByteCode;
}
QT_END_NAMESPACE
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
index baf7571910..d459ec29ab 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
@@ -840,16 +840,19 @@ void QSGD3D12ShaderCompileTask::run()
emit mgr->logAndStatusChanged();
}
+static const int BYTECODE_MAGIC = 0x43425844; // 'DXBC'
+
void QSGD3D12GuiThreadShaderEffectManager::prepareShaderCode(ShaderInfo::Type typeHint, const QByteArray &src, ShaderInfo *result)
{
// The D3D12 backend's ShaderEffect implementation supports both HLSL
- // source strings and bytecode in files as input. The latter is strongly
- // recommended, but in order to make ShaderEffect users' (and
- // qtgraphicaleffects') life easier, and since we link to d3dcompiler
+ // source strings and bytecode or source in files as input. Bytecode is
+ // strongly recommended, but in order to make ShaderEffect users' (and
+ // anything that stiches shader strings together dynamically, e.g.
+ // qtgraphicaleffects) life easier, and since we link to d3dcompiler
// anyways, compiling from source is also supported.
- // For simplicity, assume that file = bytecode, string = HLSL.
- QUrl srcUrl(src);
+ QByteArray shaderSourceCode = src;
+ QUrl srcUrl(QString::fromUtf8(src));
if (!srcUrl.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) || srcUrl.isLocalFile()) {
if (!m_fileSelector) {
m_fileSelector = new QFileSelector(this);
@@ -862,16 +865,25 @@ void QSGD3D12GuiThreadShaderEffectManager::prepareShaderCode(ShaderInfo::Type ty
emit shaderCodePrepared(false, typeHint, src, result);
return;
}
- result->blob = f.readAll();
+ QByteArray blob = f.readAll();
f.close();
- const bool ok = reflect(result);
- m_status = ok ? Compiled : Error;
- emit shaderCodePrepared(ok, typeHint, src, result);
- emit logAndStatusChanged();
- return;
+ if (blob.size() > 4) {
+ const quint32 *p = reinterpret_cast<const quint32 *>(blob.constData());
+ if (*p == BYTECODE_MAGIC) {
+ // already compiled D3D bytecode, skip straight to reflection
+ result->blob = blob;
+ const bool ok = reflect(result);
+ m_status = ok ? Compiled : Error;
+ emit shaderCodePrepared(ok, typeHint, src, result);
+ emit logAndStatusChanged();
+ return;
+ }
+ // assume the file contained HLSL source code
+ shaderSourceCode = blob;
+ }
}
- QThreadPool::globalInstance()->start(new QSGD3D12ShaderCompileTask(this, typeHint, src, result));
+ QThreadPool::globalInstance()->start(new QSGD3D12ShaderCompileTask(this, typeHint, shaderSourceCode, result));
}
bool QSGD3D12GuiThreadShaderEffectManager::reflect(ShaderInfo *result)
diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
index d506e68d6a..fbbc947c4c 100644
--- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
@@ -236,9 +236,18 @@ different than with OpenGL.
With D3D12, these strings can either be an URL for a local file or a file in
the resource system, or a HLSL source string. The former indicates that the
file in question contains pre-compiled D3D shader bytecode generated by the
-\c fxc tool.
-
-See the ShaderEffect documentation for a detailed description.
+\c fxc tool, or, alternatively, HLSL source code. The type of the file is detected
+automatically. This means that the D3D12 backend supports all options from
+GraphicsInfo.shaderCompilationType and GraphicsInfo.shaderSourceType.
+
+Unlike OpenGL, there is a QFileSelector with the extra selector \c hlsl used
+whenever opening a file. This allows easy creation of ShaderEffect items that
+are functional across both backends, for example by placing the GLSL source
+code into "shaders/effect.frag", the HLSL source code or - preferably -
+pre-compiled bytecode into "shaders/+hlsl/effect.frag", while simply writing
+\c{fragmentShader: "qrc:shaders/effect.frag"} in QML.
+
+See the ShaderEffect documentation for more details.
\section2 Unsupported Features