From cbe5814c64347ecfdcf8ca1770d6fabfccf6e924 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 16 Nov 2018 14:53:53 -0800 Subject: [PATCH] shader compilation prototype --- interface/src/Application.cpp | 44 +------------- interface/src/Application.h | 2 + interface/src/Application_render.cpp | 60 ++++++++++++------- .../display-plugins/OpenGLDisplayPlugin.cpp | 15 +++++ .../src/display-plugins/OpenGLDisplayPlugin.h | 3 + .../gpu-gl-common/src/gpu/gl/GLShader.cpp | 1 + libraries/plugins/src/plugins/DisplayPlugin.h | 4 ++ 7 files changed, 65 insertions(+), 64 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 969a05a792..6d13305af7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2382,6 +2382,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo checkLoginTimer->start(); } #endif + + const QString SPLASH_SKYBOX { "{\"ProceduralEntity\":{ \"version\":2, \"shaderUrl\":\"qrc:///shaders/splashSkybox.frag\" } }" }; + _splashScreen->parse(SPLASH_SKYBOX); } void Application::updateVerboseLogging() { @@ -2862,8 +2865,6 @@ void Application::initializeGL() { DependencyManager::get()->setGPUContext(_gpuContext); } -static const QString SPLASH_SKYBOX{ "{\"ProceduralEntity\":{ \"version\":2, \"shaderUrl\":\"qrc:///shaders/splashSkybox.frag\" } }" }; - void Application::initializeDisplayPlugins() { auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); Setting::Handle activeDisplayPluginSetting{ ACTIVE_DISPLAY_PLUGIN_SETTING_NAME, displayPlugins.at(0)->getName() }; @@ -2899,45 +2900,6 @@ void Application::initializeDisplayPlugins() { // Submit a default frame to render until the engine starts up updateRenderArgs(0.0f); - -#define ENABLE_SPLASH_FRAME 0 -#if ENABLE_SPLASH_FRAME - { - QMutexLocker viewLocker(&_renderArgsMutex); - - if (_appRenderArgs._isStereo) { - _gpuContext->enableStereo(true); - _gpuContext->setStereoProjections(_appRenderArgs._eyeProjections); - _gpuContext->setStereoViews(_appRenderArgs._eyeOffsets); - } - - // Frame resources - auto framebufferCache = DependencyManager::get(); - gpu::FramebufferPointer finalFramebuffer = framebufferCache->getFramebuffer(); - std::shared_ptr procedural = std::make_shared(); - procedural->parse(SPLASH_SKYBOX); - - _gpuContext->beginFrame(_appRenderArgs._view, _appRenderArgs._headPose); - gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) { - batch.resetStages(); - batch.enableStereo(false); - batch.setFramebuffer(finalFramebuffer); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 0, 0, 1 }); - batch.enableSkybox(true); - batch.enableStereo(_appRenderArgs._isStereo); - batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); - procedural->render(batch, _appRenderArgs._renderArgs.getViewFrustum()); - }); - auto frame = _gpuContext->endFrame(); - frame->frameIndex = 0; - frame->framebuffer = finalFramebuffer; - frame->pose = _appRenderArgs._headPose; - frame->framebufferRecycler = [framebufferCache, procedural](const gpu::FramebufferPointer& framebuffer) { - framebufferCache->releaseFramebuffer(framebuffer); - }; - _displayPlugin->submitFrame(frame); - } -#endif } void Application::initializeRenderEngine() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 9b8aac425a..fb1c916c36 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -793,5 +793,7 @@ private: bool _showTrackedObjects { false }; bool _prevShowTrackedObjects { false }; + + std::shared_ptr _splashScreen { std::make_shared() }; }; #endif // hifi_Application_h diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index a87caeb9a8..47cde80ab3 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -62,6 +62,7 @@ void Application::paintGL() { glm::mat4 HMDSensorPose; glm::mat4 eyeToWorld; glm::mat4 sensorToWorld; + ViewFrustum viewFrustum; bool isStereo; glm::mat4 stereoEyeOffsets[2]; @@ -84,6 +85,7 @@ void Application::paintGL() { stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; }); + viewFrustum = _appRenderArgs._renderArgs.getViewFrustum(); } { @@ -94,21 +96,12 @@ void Application::paintGL() { gpu::doInBatch("Application_render::gpuContextReset", _gpuContext, [&](gpu::Batch& batch) { batch.resetStages(); }); - } - - { - PROFILE_RANGE(render, "/renderOverlay"); - PerformanceTimer perfTimer("renderOverlay"); - // NOTE: There is no batch associated with this renderArgs - // the ApplicationOverlay class assumes it's viewport is setup to be the device size - renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize()); - _applicationOverlay.renderOverlay(&renderArgs); - } - - { - PROFILE_RANGE(render, "/updateCompositor"); - getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld); + if (isStereo) { + renderArgs._context->enableStereo(true); + renderArgs._context->setStereoProjections(stereoEyeProjections); + renderArgs._context->setStereoViews(stereoEyeOffsets); + } } gpu::FramebufferPointer finalFramebuffer; @@ -122,17 +115,38 @@ void Application::paintGL() { finalFramebuffer = framebufferCache->getFramebuffer(); } - { - if (isStereo) { - renderArgs._context->enableStereo(true); - renderArgs._context->setStereoProjections(stereoEyeProjections); - renderArgs._context->setStereoViews(stereoEyeOffsets); + if (!displayPlugin->areAllProgramsLoaded()) { + gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) { + batch.enableStereo(false); + batch.setFramebuffer(finalFramebuffer); + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 0, 0, 1 }); + batch.enableSkybox(true); + batch.enableStereo(isStereo); + batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); + _splashScreen->render(batch, viewFrustum); + }); + } else { + { + PROFILE_RANGE(render, "/renderOverlay"); + PerformanceTimer perfTimer("renderOverlay"); + // NOTE: There is no batch associated with this renderArgs + // the ApplicationOverlay class assumes it's viewport is setup to be the device size + renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize()); + _applicationOverlay.renderOverlay(&renderArgs); } - renderArgs._hudOperator = displayPlugin->getHUDOperator(); - renderArgs._hudTexture = _applicationOverlay.getOverlayTexture(); - renderArgs._blitFramebuffer = finalFramebuffer; - runRenderFrame(&renderArgs); + { + PROFILE_RANGE(render, "/updateCompositor"); + getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld); + } + + { + PROFILE_RANGE(render, "/runRenderFrame"); + renderArgs._hudOperator = displayPlugin->getHUDOperator(); + renderArgs._hudTexture = _applicationOverlay.getOverlayTexture(); + renderArgs._blitFramebuffer = finalFramebuffer; + runRenderFrame(&renderArgs); + } } auto frame = _gpuContext->endFrame(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 190d4d4104..f562efbe22 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -637,6 +638,17 @@ void OpenGLDisplayPlugin::present() { auto frameId = (uint64_t)presentCount(); PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId) uint64_t startPresent = usecTimestampNow(); + + if (!_allProgramsLoaded) { + const auto& programIDs = shader::allPrograms(); + if (_currentLoadingProgramIndex < programIDs.size()) { + auto shader = gpu::Shader::createProgram(programIDs.at(_currentLoadingProgramIndex++)); + gpu::gl::GLShader::sync(*getGLBackend(), *shader); + } else { + _allProgramsLoaded = true; + } + } + { PROFILE_RANGE_EX(render, "updateFrameData", 0xff00ff00, frameId) updateFrameData(); @@ -829,6 +841,9 @@ void OpenGLDisplayPlugin::render(std::function f) { _gpuContext->executeBatch(batch); } +OpenGLDisplayPlugin::OpenGLDisplayPlugin() : DisplayPlugin() { + _allProgramsLoaded = false; +} OpenGLDisplayPlugin::~OpenGLDisplayPlugin() { } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 1cc060161b..1e3983d366 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -38,6 +38,7 @@ protected: using Lock = std::unique_lock; using Condition = std::condition_variable; public: + OpenGLDisplayPlugin(); ~OpenGLDisplayPlugin(); // These must be final to ensure proper ordering of operations // between the main thread and the presentation thread @@ -180,5 +181,7 @@ protected: // be serialized through this mutex mutable Mutex _presentMutex; float _hudAlpha{ 1.0f }; + + size_t _currentLoadingProgramIndex { 0 }; }; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLShader.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLShader.cpp index 44d2bd6ca0..cf123a3f66 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLShader.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLShader.cpp @@ -37,6 +37,7 @@ GLShader* GLShader::sync(GLBackend& backend, const Shader& shader, const Shader: if (object) { return object; } + PROFILE_RANGE(render, "/GLShader::sync"); // need to have a gpu object? if (shader.isProgram()) { GLShader* tempObject = backend.compileBackendProgram(shader, handler); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index ad49ceafe6..e925309042 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -217,6 +217,8 @@ public: static const QString& MENU_PATH(); + bool areAllProgramsLoaded() { return _allProgramsLoaded; } + signals: void recommendedFramebufferSizeChanged(const QSize& size); void resetSensorsRequested(); @@ -233,6 +235,8 @@ protected: float _renderResolutionScale { 1.0f }; + std::atomic _allProgramsLoaded { true }; + private: QMutex _presentMutex; QWaitCondition _presentCondition;