diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-21 17:43:11 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-23 10:29:53 +0000 |
commit | 4d32060a81201f8cb0419c6f9eff5df3edd1bfaf (patch) | |
tree | 00cada9eeab9e354501fbb3bbf8c2e9a9409ead3 | |
parent | 53fc739e3d530a70e5371a08d001bacabc0233de (diff) |
Generate native resource binding map for MSL
Task-number: QTBUG-79368
Change-Id: I74f6bdab13e5ee0f7c97e78e776f59e191af2fdb
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
-rw-r--r-- | src/shadertools/qshaderbaker.cpp | 6 | ||||
-rw-r--r-- | src/shadertools/qspirvshader.cpp | 27 | ||||
-rw-r--r-- | src/shadertools/qspirvshader_p.h | 4 | ||||
-rw-r--r-- | tools/qsb/qsb.cpp | 33 |
4 files changed, 54 insertions, 16 deletions
diff --git a/src/shadertools/qshaderbaker.cpp b/src/shadertools/qshaderbaker.cpp index df30436..700901f 100644 --- a/src/shadertools/qshaderbaker.cpp +++ b/src/shadertools/qshaderbaker.cpp @@ -420,12 +420,16 @@ QShader QShaderBaker::bake() } break; case QShader::MslShader: - shader.setShader(currentSpirvShader->translateToMSL(req.second.version())); + { + QShader::NativeResourceBindingMap nativeBindings; + shader.setShader(currentSpirvShader->translateToMSL(req.second.version(), &nativeBindings)); if (shader.shader().isEmpty()) { d->errorMessage = currentSpirvShader->translationErrorMessage(); return QShader(); } shader.setEntryPoint(QByteArrayLiteral("main0")); + bs.setResourceBindingMap(key, nativeBindings); + } break; default: Q_UNREACHABLE(); diff --git a/src/shadertools/qspirvshader.cpp b/src/shadertools/qspirvshader.cpp index 88c8702..7900359 100644 --- a/src/shadertools/qspirvshader.cpp +++ b/src/shadertools/qspirvshader.cpp @@ -500,7 +500,7 @@ QByteArray QSpirvShader::translateToHLSL(int version) const } } -QByteArray QSpirvShader::translateToMSL(int version) const +QByteArray QSpirvShader::translateToMSL(int version, QShader::NativeResourceBindingMap *nativeBindings) const { d->spirvCrossErrorMsg.clear(); @@ -515,6 +515,31 @@ QByteArray QSpirvShader::translateToMSL(int version) const const std::string msl = d->mslGen->compile(); + if (nativeBindings) { + spirv_cross::ShaderResources resources = d->mslGen->get_shader_resources(); + for (const spirv_cross::Resource &r : resources.uniform_buffers) { + uint32_t binding = d->mslGen->get_decoration(r.id, spv::DecorationBinding); + uint32_t nativeBinding = d->mslGen->get_automatic_msl_resource_binding(r.id); + nativeBindings->insert(int(binding), { int(nativeBinding), 0 }); + } + for (const spirv_cross::Resource &r : resources.storage_buffers) { + uint32_t binding = d->mslGen->get_decoration(r.id, spv::DecorationBinding); + uint32_t nativeBinding = d->mslGen->get_automatic_msl_resource_binding(r.id); + nativeBindings->insert(int(binding), { int(nativeBinding), 0 }); + } + for (const spirv_cross::Resource &r : resources.sampled_images) { + uint32_t binding = d->mslGen->get_decoration(r.id, spv::DecorationBinding); + uint32_t nativeTextureBinding = d->mslGen->get_automatic_msl_resource_binding(r.id); + uint32_t nativeSamplerBinding = d->mslGen->get_automatic_msl_resource_binding_secondary(r.id); + nativeBindings->insert(int(binding), { int(nativeTextureBinding), int(nativeSamplerBinding) }); + } + for (const spirv_cross::Resource &r : resources.storage_images) { + uint32_t binding = d->mslGen->get_decoration(r.id, spv::DecorationBinding); + uint32_t nativeBinding = d->mslGen->get_automatic_msl_resource_binding(r.id); + nativeBindings->insert(int(binding), { int(nativeBinding), 0 }); + } + } + return QByteArray::fromStdString(msl); } catch (const std::runtime_error &e) { d->spirvCrossErrorMsg = QString::fromUtf8(e.what()); diff --git a/src/shadertools/qspirvshader_p.h b/src/shadertools/qspirvshader_p.h index 018fc30..b00a30e 100644 --- a/src/shadertools/qspirvshader_p.h +++ b/src/shadertools/qspirvshader_p.h @@ -49,7 +49,7 @@ // #include <QtShaderTools/private/qtshadertoolsglobal_p.h> -#include <QtGui/private/qshaderdescription_p.h> +#include <QtGui/private/qshader_p.h> QT_BEGIN_NAMESPACE @@ -84,7 +84,7 @@ public: QByteArray translateToGLSL(int version = 120, GlslFlags flags = GlslFlags()) const; QByteArray translateToHLSL(int version = 50) const; - QByteArray translateToMSL(int version = 12) const; + QByteArray translateToMSL(int version = 12, QShader::NativeResourceBindingMap *nativeBindings = nullptr) const; QString translationErrorMessage() const; diff --git a/tools/qsb/qsb.cpp b/tools/qsb/qsb.cpp index 1288c94..b5b98d9 100644 --- a/tools/qsb/qsb.cpp +++ b/tools/qsb/qsb.cpp @@ -155,24 +155,29 @@ static void dump(const QShader &bs) { QTextStream ts(stdout); ts << "Stage: " << stageStr(bs.stage()) << "\n\n"; - QVector<QShaderKey> s = bs.availableShaders(); - ts << "Has " << s.count() << " shaders: (unordered list)\n"; - for (int i = 0; i < s.count(); ++i) { - ts << " Shader " << i << ": " << sourceStr(s[i].source()) - << " " << sourceVersionStr(s[i].sourceVersion()) - << " [" << sourceVariantStr(s[i].sourceVariant()) << "]\n"; + const QVector<QShaderKey> keys = bs.availableShaders(); + ts << "Has " << keys.count() << " shaders: (unordered list)\n"; + for (int i = 0; i < keys.count(); ++i) { + ts << " Shader " << i << ": " << sourceStr(keys[i].source()) + << " " << sourceVersionStr(keys[i].sourceVersion()) + << " [" << sourceVariantStr(keys[i].sourceVariant()) << "]\n"; } ts << "\n"; ts << "Reflection info: " << bs.description().toJson() << "\n\n"; - for (int i = 0; i < s.count(); ++i) { - ts << "Shader " << i << ": " << sourceStr(s[i].source()) - << " " << sourceVersionStr(s[i].sourceVersion()) - << " [" << sourceVariantStr(s[i].sourceVariant()) << "]\n"; - QShaderCode shader = bs.shader(s[i]); + for (int i = 0; i < keys.count(); ++i) { + ts << "Shader " << i << ": " << sourceStr(keys[i].source()) + << " " << sourceVersionStr(keys[i].sourceVersion()) + << " [" << sourceVariantStr(keys[i].sourceVariant()) << "]\n"; + QShaderCode shader = bs.shader(keys[i]); if (!shader.entryPoint().isEmpty()) ts << "Entry point: " << shader.entryPoint() << "\n"; + if (const QShader::NativeResourceBindingMap *map = bs.nativeResourceBindingMap(keys[i])) { + ts << "Native resource binding map:\n"; + for (auto mapIt = map->cbegin(), mapItEnd = map->cend(); mapIt != mapItEnd; ++mapIt) + ts << mapIt.key() << " -> [" << mapIt.value().first << ", " << mapIt.value().second << "]\n"; + } ts << "Contents:\n"; - switch (s[i].source()) { + switch (keys[i].source()) { case QShader::SpirvShader: Q_FALLTHROUGH(); case QShader::DxbcShader: @@ -497,6 +502,8 @@ int main(int argc, char **argv) dxbcKey.setSource(QShader::DxbcShader); QShaderCode dxbcShader(bytecode, s.entryPoint()); bs.setShader(dxbcKey, dxbcShader); + if (const QShader::NativeResourceBindingMap *map = bs.nativeResourceBindingMap(k)) + bs.setResourceBindingMap(dxbcKey, *map); bs.removeShader(k); } } @@ -574,6 +581,8 @@ int main(int argc, char **argv) mtlKey.setSource(QShader::MetalLibShader); QShaderCode mtlShader(bytecode, s.entryPoint()); bs.setShader(mtlKey, mtlShader); + if (const QShader::NativeResourceBindingMap *map = bs.nativeResourceBindingMap(k)) + bs.setResourceBindingMap(mtlKey, *map); bs.removeShader(k); } } |