diff options
author | Antti Määttä <antti.maatta@qt.io> | 2020-02-07 14:12:42 +0200 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2020-02-10 14:02:35 +0200 |
commit | bff0bf78b328b730843abf0e79f58e8411908de5 (patch) | |
tree | 6fcf341f3d79dfc6d9af50d52b99f4c603fba287 | |
parent | 90dd0bdcf1c9e3a1eddee8abcf4307c06e82e37b (diff) |
Implement shader cache loading error handling
Task-number: QT3DS-4040
Change-Id: Ie5f8284ab76cd4aa5f3ff0701457f4ef84c3e215
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r-- | src/api/studio3d/q3dspresentation.h | 1 | ||||
-rw-r--r-- | src/api/studio3dqml/q3dsrenderer.cpp | 2 | ||||
-rw-r--r-- | src/api/studio3dqml/q3dsrenderer_p.h | 1 | ||||
-rw-r--r-- | src/api/studio3dqml/q3dsstudio3d.cpp | 2 | ||||
-rw-r--r-- | src/engine/Qt3DSRuntimeView.cpp | 9 | ||||
-rw-r--r-- | src/engine/Qt3DSRuntimeView.h | 3 | ||||
-rw-r--r-- | src/runtime/Qt3DSApplication.cpp | 11 | ||||
-rw-r--r-- | src/runtime/Qt3DSApplication.h | 3 | ||||
-rw-r--r-- | src/runtimerender/Qt3DSRenderShaderCache.cpp | 19 | ||||
-rw-r--r-- | src/runtimerender/Qt3DSRenderShaderCache.h | 2 | ||||
-rw-r--r-- | src/viewer/Qt3DSViewerApp.cpp | 7 | ||||
-rw-r--r-- | src/viewer/Qt3DSViewerApp.h | 1 |
12 files changed, 45 insertions, 16 deletions
diff --git a/src/api/studio3d/q3dspresentation.h b/src/api/studio3d/q3dspresentation.h index 114eaec..1e8dedf 100644 --- a/src/api/studio3d/q3dspresentation.h +++ b/src/api/studio3d/q3dspresentation.h @@ -160,6 +160,7 @@ Q_SIGNALS: void meshesCreated(const QStringList &meshNames, const QString &error); void shaderCacheFileChanged(const QUrl &fileName); void shaderCacheExported(bool success); + void shaderCacheLoadErrors(const QString &errors); private: Q_DISABLE_COPY(Q3DSPresentation) diff --git a/src/api/studio3dqml/q3dsrenderer.cpp b/src/api/studio3dqml/q3dsrenderer.cpp index c902934..1f78bf7 100644 --- a/src/api/studio3dqml/q3dsrenderer.cpp +++ b/src/api/studio3dqml/q3dsrenderer.cpp @@ -235,6 +235,8 @@ bool Q3DSRenderer::initializeRuntime(QOpenGLFramebufferObject *inFbo) this, &Q3DSRenderer::presentationReady); connect(m_runtime, &Q3DSViewer::Q3DSViewerApp::SigPresentationLoaded, this, &Q3DSRenderer::presentationLoaded); + connect(m_runtime, &Q3DSViewer::Q3DSViewerApp::SigLoadShaderCacheErrors, + this, &Q3DSRenderer::shaderCacheLoadErrors); int theWidth = inFbo->width(); int theHeight = inFbo->height(); diff --git a/src/api/studio3dqml/q3dsrenderer_p.h b/src/api/studio3dqml/q3dsrenderer_p.h index dbc85a2..0ba6c31 100644 --- a/src/api/studio3dqml/q3dsrenderer_p.h +++ b/src/api/studio3dqml/q3dsrenderer_p.h @@ -81,6 +81,7 @@ Q_SIGNALS: void materialsCreated(const QStringList &materialNames, const QString &error); void meshesCreated(const QStringList &meshNames, const QString &error); void dataOutputValueUpdated(const QString &name, const QVariant &newValue); + void shaderCacheLoadErrors(const QString &errors); protected Q_SLOTS: void handleRuntimeInitializedAsync(); diff --git a/src/api/studio3dqml/q3dsstudio3d.cpp b/src/api/studio3dqml/q3dsstudio3d.cpp index f1e383f..503b713 100644 --- a/src/api/studio3dqml/q3dsstudio3d.cpp +++ b/src/api/studio3dqml/q3dsstudio3d.cpp @@ -430,6 +430,8 @@ QQuickFramebufferObject::Renderer *Q3DSStudio3D::createRenderer() const m_presentation->d_ptr, &Q3DSPresentationPrivate::handleMaterialsCreated); connect(renderer, &Q3DSRenderer::meshesCreated, m_presentation->d_ptr, &Q3DSPresentationPrivate::handleMeshesCreated); + connect(renderer, &Q3DSRenderer::shaderCacheLoadErrors, + m_presentation, &Q3DSPresentation::shaderCacheLoadErrors); connect(renderer, &Q3DSRenderer::exitSlide, m_presentation, &Q3DSPresentation::slideExited); connect(renderer, &Q3DSRenderer::customSignalEmitted, diff --git a/src/engine/Qt3DSRuntimeView.cpp b/src/engine/Qt3DSRuntimeView.cpp index c1b5669..7cebdd6 100644 --- a/src/engine/Qt3DSRuntimeView.cpp +++ b/src/engine/Qt3DSRuntimeView.cpp @@ -172,7 +172,8 @@ public: bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override; bool HasOfflineLoadingCompleted() override; bool InitializeGraphics(const QSurfaceFormat &format, bool delayedLoading, - bool initInRenderThread, const QByteArray &shaderCache) override; + bool initInRenderThread, const QByteArray &shaderCache, + QString &errors) override; void connectSignals() override; void finishAsyncInit() override; @@ -302,7 +303,8 @@ bool CRuntimeView::HasOfflineLoadingCompleted() } bool CRuntimeView::InitializeGraphics(const QSurfaceFormat &format, bool delayedLoading, - bool initInRenderThread, const QByteArray &shaderCache) + bool initInRenderThread, const QByteArray &shaderCache, + QString &errors) { m_ApplicationCore->EndLoad(); // Next call will initialize the render portion of the scenes. This *must* have a loaded @@ -311,7 +313,8 @@ bool CRuntimeView::InitializeGraphics(const QSurfaceFormat &format, bool delayed m_Application = m_ApplicationCore->CreateApplication(*m_InputEngine, m_AudioPlayer, *m_RuntimeFactory, shaderCache, - initInRenderThread); + initInRenderThread, + errors); if (!m_Application->createSuccessful()) return false; diff --git a/src/engine/Qt3DSRuntimeView.h b/src/engine/Qt3DSRuntimeView.h index e0061b0..e114633 100644 --- a/src/engine/Qt3DSRuntimeView.h +++ b/src/engine/Qt3DSRuntimeView.h @@ -177,7 +177,8 @@ public: // loading virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) = 0; virtual bool HasOfflineLoadingCompleted() = 0; virtual bool InitializeGraphics(const QSurfaceFormat &format, bool delayedLoading, - bool initInRenderThread, const QByteArray &shaderCache) = 0; + bool initInRenderThread, const QByteArray &shaderCache, + QString &errors) = 0; virtual void connectSignals() = 0; virtual void finishAsyncInit() = 0; diff --git a/src/runtime/Qt3DSApplication.cpp b/src/runtime/Qt3DSApplication.cpp index 20a8e5a..b8d3d31 100644 --- a/src/runtime/Qt3DSApplication.cpp +++ b/src/runtime/Qt3DSApplication.cpp @@ -1801,7 +1801,8 @@ struct SApp : public IApplication Q3DStudio::IAudioPlayer *inAudioPlayer, Q3DStudio::IRuntimeFactory &inFactory, const QByteArray &shaderCache, - bool initInRenderThread) override + bool initInRenderThread, + QString &shaderCacheErrors) override { { QT3DS_PERF_SCOPED_TIMER(m_CoreFactory->GetPerfTimer(), @@ -1871,8 +1872,12 @@ struct SApp : public IApplication } - if (!shaderCache.isEmpty()) - inFactory.GetQt3DSRenderContext().GetShaderCache().importShaderCache(shaderCache); + if (!shaderCache.isEmpty()) { + QString errors; + inFactory.GetQt3DSRenderContext().GetShaderCache().importShaderCache(shaderCache, errors); + if (!errors.isEmpty()) + shaderCacheErrors = errors; + } m_AudioPlayer.SetPlayer(inAudioPlayer); diff --git a/src/runtime/Qt3DSApplication.h b/src/runtime/Qt3DSApplication.h index 97d8528..ce1b366 100644 --- a/src/runtime/Qt3DSApplication.h +++ b/src/runtime/Qt3DSApplication.h @@ -251,7 +251,8 @@ public: Q3DStudio::IAudioPlayer *inAudioPlayer, Q3DStudio::IRuntimeFactory &inFactory, const QByteArray &shaderCache, - bool initInRenderThread) = 0; + bool initInRenderThread, + QString &shaderCacheErrors) = 0; // maintains reference to runtime factory core. AppDir is where the executable is located; // the system will expect res directory diff --git a/src/runtimerender/Qt3DSRenderShaderCache.cpp b/src/runtimerender/Qt3DSRenderShaderCache.cpp index e26405c..3794a83 100644 --- a/src/runtimerender/Qt3DSRenderShaderCache.cpp +++ b/src/runtimerender/Qt3DSRenderShaderCache.cpp @@ -571,10 +571,11 @@ struct ShaderCache : public IShaderCache return retval; } - void importShaderCache(const QByteArray &shaderCache) override + void importShaderCache(const QByteArray &shaderCache, QString &errors) override { #define BAILOUT(details) { \ - qWarning() << "importShaderCache failed to import shader cache:" << details; \ + errors = "importShaderCache failed to import shader cache: " details; \ + qWarning() << errors; \ return; \ } @@ -634,9 +635,13 @@ struct ShaderCache : public IShaderCache qCInfo(TRACE_INFO) << "Loading binary program from shader cache: '<" << key << ">'"; eastl::pair<TShaderMap::iterator, bool> theInserter = m_Shaders.insert(tempKey); - theInserter.first->second - = m_RenderContext.CompileBinary(theKey, format, binary).mShader; - theShader = theInserter.first->second; + auto ret = m_RenderContext.CompileBinary(theKey, format, binary); + if (!ret.errors.isEmpty()) { + errors += ret.errors + "\n"; + } else { + theInserter.first->second = ret.mShader; + theShader = ret.mShader; + } } else { QByteArray loadVertexData; QByteArray loadFragmentData; @@ -663,6 +668,10 @@ struct ShaderCache : public IShaderCache qt3ds::foundation::toDataRef( features.data(), static_cast<QT3DSU32>(features.size())), error, false, true); + if (!error.isEmpty()) { + errors += error + "\n"; + theShader = nullptr; + } } } // If something doesn't save or load correctly, get the runtime to re-generate. diff --git a/src/runtimerender/Qt3DSRenderShaderCache.h b/src/runtimerender/Qt3DSRenderShaderCache.h index d03bc65..35713bd 100644 --- a/src/runtimerender/Qt3DSRenderShaderCache.h +++ b/src/runtimerender/Qt3DSRenderShaderCache.h @@ -103,7 +103,7 @@ namespace render { // source code is exported virtual QByteArray exportShaderCache(bool binaryShaders) = 0; // This call immediately blocks and attempts to load all shaders from the shaderCache - virtual void importShaderCache(const QByteArray &shaderCache) = 0; + virtual void importShaderCache(const QByteArray &shaderCache, QString &errors) = 0; // It is up to the caller to ensure that inFeatures contains unique keys. // It is also up the the caller to ensure the keys are ordered in some way. virtual NVRenderShaderProgram * diff --git a/src/viewer/Qt3DSViewerApp.cpp b/src/viewer/Qt3DSViewerApp.cpp index ce8163f..ae671d0 100644 --- a/src/viewer/Qt3DSViewerApp.cpp +++ b/src/viewer/Qt3DSViewerApp.cpp @@ -427,10 +427,13 @@ bool Q3DSViewerApp::InitializeApp(int winWidth, int winHeight, const QSurfaceFor qCritical() << m_Impl.m_error; return false; } - + QString errors; bool success = m_Impl.m_view->InitializeGraphics(format, delayedLoading, initInRenderThread, - shaderCache); + shaderCache, errors); + if (!errors.isEmpty()) + Q_EMIT SigLoadShaderCacheErrors(errors); + if (!success) { m_Impl.m_error = QObject::tr("Viewer launch failure! Failed to load: '%1'").arg(source); m_Impl.m_error.append("\n"); diff --git a/src/viewer/Qt3DSViewerApp.h b/src/viewer/Qt3DSViewerApp.h index db8ba57..a23b5f9 100644 --- a/src/viewer/Qt3DSViewerApp.h +++ b/src/viewer/Qt3DSViewerApp.h @@ -549,6 +549,7 @@ Q_SIGNALS: void SigDataOutputValueUpdated(const QString &name, const QVariant &newValue); void SigPresentationReady(); void SigPresentationLoaded(); + void SigLoadShaderCacheErrors(const QString &errors); }; } // end namespace |