diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2016-06-28 15:42:53 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2016-06-29 12:00:05 +0000 |
commit | b87fd4752afd6b559d69ec2e08b2e3df69373b9e (patch) | |
tree | 49497c0aefb1fdb379f69c9f96ee4cfb596defb0 | |
parent | ee595e9c0a4a24733195db22244cbf17b8514f72 (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>
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 |