From bd3a732cdcd76e750127b2f49aa29a9e72f3520e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 13 Feb 2019 17:38:59 -0800 Subject: [PATCH 1/3] Introducing msaa to forward renderer --- .../render-utils/src/RenderCommonTask.cpp | 68 ++++++++++++++++++- libraries/render-utils/src/RenderCommonTask.h | 22 ++++++ .../render-utils/src/RenderForwardTask.cpp | 22 ++++-- .../render-utils/src/RenderForwardTask.h | 23 ++++++- 4 files changed, 128 insertions(+), 7 deletions(-) diff --git a/libraries/render-utils/src/RenderCommonTask.cpp b/libraries/render-utils/src/RenderCommonTask.cpp index 40724cbf5a..b4a77479db 100644 --- a/libraries/render-utils/src/RenderCommonTask.cpp +++ b/libraries/render-utils/src/RenderCommonTask.cpp @@ -197,7 +197,73 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer }); } -void ExtractFrustums::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) { + +void ResolveFramebuffer::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { + RenderArgs* args = renderContext->args; + auto srcFbo = inputs.get0(); + auto destFbo = inputs.get1(); + + if (!destFbo) { + destFbo = args->_blitFramebuffer; + } + outputs = destFbo; + + // Check valid src and dest + if (!srcFbo || !destFbo) { + return; + } + + // Check valid size for sr and dest + auto frameSize(srcFbo->getSize()); + if (destFbo->getSize() != frameSize) { + return; + } + + gpu::Vec4i rectSrc; + rectSrc.z = frameSize.x; + rectSrc.w = frameSize.y; + gpu::doInBatch("Resolve", args->_context, [&](gpu::Batch& batch) { + batch.blit(srcFbo, rectSrc, destFbo, rectSrc); + }); +} + +void ResolveNewFramebuffer::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { + RenderArgs* args = renderContext->args; + auto srcFbo = inputs; + outputs.reset(); + + // Check valid src + if (!srcFbo) { + return; + } + + // Check valid size for sr and dest + auto frameSize(srcFbo->getSize()); + + // Resizing framebuffers instead of re-building them seems to cause issues with threaded rendering + if (_outputFramebuffer && _outputFramebuffer->getSize() != frameSize) { + _outputFramebuffer.reset(); + } + + if (!_outputFramebuffer) { + _outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("resolvedNew.out")); + auto colorFormat = gpu::Element::COLOR_SRGBA_32; + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); + auto colorTexture = gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler); + _outputFramebuffer->setRenderBuffer(0, colorTexture); + } + + gpu::Vec4i rectSrc; + rectSrc.z = frameSize.x; + rectSrc.w = frameSize.y; + gpu::doInBatch("ResolveNew", args->_context, [&](gpu::Batch& batch) { batch.blit(srcFbo, rectSrc, _outputFramebuffer, rectSrc); }); + + outputs = _outputFramebuffer; +} + + + + void ExtractFrustums::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) { assert(renderContext->args); assert(renderContext->args->_context); diff --git a/libraries/render-utils/src/RenderCommonTask.h b/libraries/render-utils/src/RenderCommonTask.h index 29f195ffff..a1de50abba 100644 --- a/libraries/render-utils/src/RenderCommonTask.h +++ b/libraries/render-utils/src/RenderCommonTask.h @@ -90,6 +90,28 @@ public: void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer); }; + +class ResolveFramebuffer { +public: + using Inputs = render::VaryingSet2; + using Outputs = gpu::FramebufferPointer; + using JobModel = render::Job::ModelIO; + + void run(const render::RenderContextPointer& renderContext, const Inputs& source, Outputs& dest); +}; + +class ResolveNewFramebuffer { +public: + using Inputs = gpu::FramebufferPointer; + using Outputs = gpu::FramebufferPointer; + using JobModel = render::Job::ModelIO; + + void run(const render::RenderContextPointer& renderContext, const Inputs& source, Outputs& dest); +private: + gpu::FramebufferPointer _outputFramebuffer; +}; + + class ExtractFrustums { public: diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index ffdbc1c4b1..c47935c6fc 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -129,10 +129,16 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend task.addJob("DrawZoneStack", debugZoneInputs); } + // Just resolve the msaa +/* const auto resolveInputs = + ResolveFramebuffer::Inputs(framebuffer, static_cast(nullptr)).asVarying(); + auto resolvedFramebuffer = task.addJob("Resolve", resolveInputs); */ + auto resolvedFramebuffer = task.addJob("Resolve", framebuffer); + // Lighting Buffer ready for tone mapping // Forward rendering on GLES doesn't support tonemapping to and from the same FBO, so we specify // the output FBO as null, which causes the tonemapping to target the blit framebuffer - const auto toneMappingInputs = ToneMappingDeferred::Inputs(framebuffer, static_cast(nullptr) ).asVarying(); + const auto toneMappingInputs = ToneMappingDeferred::Inputs(resolvedFramebuffer, static_cast(nullptr)).asVarying(); task.addJob("ToneMapping", toneMappingInputs); // Layered Overlays @@ -144,26 +150,32 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // task.addJob("Blit", framebuffer); } +void PrepareFramebuffer::configure(const Config& config) { + _numSamples = config.getNumSamples(); +} + void PrepareFramebuffer::run(const RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer) { glm::uvec2 frameSize(renderContext->args->_viewport.z, renderContext->args->_viewport.w); // Resizing framebuffers instead of re-building them seems to cause issues with threaded rendering - if (_framebuffer && _framebuffer->getSize() != frameSize) { + if (_framebuffer && (_framebuffer->getSize() != frameSize || _framebuffer->getNumSamples() != _numSamples)) { _framebuffer.reset(); } if (!_framebuffer) { _framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("forward")); + int numSamples = _numSamples; + auto colorFormat = gpu::Element::COLOR_SRGBA_32; - auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); auto colorTexture = - gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler); + gpu::Texture::createRenderBufferMultisample(colorFormat, frameSize.x, frameSize.y, numSamples, defaultSampler); _framebuffer->setRenderBuffer(0, colorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format auto depthTexture = - gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler); + gpu::Texture::createRenderBufferMultisample(depthFormat, frameSize.x, frameSize.y, numSamples, defaultSampler); _framebuffer->setDepthStencilBuffer(depthTexture, depthFormat); } diff --git a/libraries/render-utils/src/RenderForwardTask.h b/libraries/render-utils/src/RenderForwardTask.h index e6a6008319..85b51ad5fa 100755 --- a/libraries/render-utils/src/RenderForwardTask.h +++ b/libraries/render-utils/src/RenderForwardTask.h @@ -27,16 +27,37 @@ public: void build(JobModel& task, const render::Varying& input, render::Varying& output); }; + +class PrepareFramebufferConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(int numSamples WRITE setNumSamples READ getNumSamples NOTIFY dirty) +public: + int getNumSamples() const { return numSamples; } + void setNumSamples(int num) { + numSamples = std::max(1, std::min(32, num)); + emit dirty(); + } + +signals: + void dirty(); + +protected: + int numSamples{ 4 }; +}; + class PrepareFramebuffer { public: using Inputs = gpu::FramebufferPointer; - using JobModel = render::Job::ModelO; + using Config = PrepareFramebufferConfig; + using JobModel = render::Job::ModelO; + void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer); private: gpu::FramebufferPointer _framebuffer; + int _numSamples; }; class PrepareForward { From 98a5ec84a9ac163c18593503aa5282b0a1708d2d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 14 Feb 2019 15:35:02 -0800 Subject: [PATCH 2/3] Adjusting the HUD operator render job to shave an extra framebuffer --- libraries/gpu/src/gpu/State.h | 2 +- libraries/render-utils/src/RenderCommonTask.cpp | 5 ++++- libraries/render-utils/src/RenderCommonTask.h | 8 +++++--- libraries/render-utils/src/RenderDeferredTask.cpp | 2 +- libraries/render-utils/src/RenderForwardTask.cpp | 12 ++++++------ 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/libraries/gpu/src/gpu/State.h b/libraries/gpu/src/gpu/State.h index abe0cd7731..2e8a3f2cab 100755 --- a/libraries/gpu/src/gpu/State.h +++ b/libraries/gpu/src/gpu/State.h @@ -246,7 +246,7 @@ public: struct Flags { Flags() : - frontFaceClockwise(false), depthClampEnable(false), scissorEnable(false), multisampleEnable(false), + frontFaceClockwise(false), depthClampEnable(false), scissorEnable(false), multisampleEnable(true), antialisedLineEnable(true), alphaToCoverageEnable(false), _spare1(0) {} bool frontFaceClockwise : 1; bool depthClampEnable : 1; diff --git a/libraries/render-utils/src/RenderCommonTask.cpp b/libraries/render-utils/src/RenderCommonTask.cpp index b4a77479db..9a70b1c1b3 100644 --- a/libraries/render-utils/src/RenderCommonTask.cpp +++ b/libraries/render-utils/src/RenderCommonTask.cpp @@ -101,7 +101,7 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& } } -void CompositeHUD::run(const RenderContextPointer& renderContext) { +void CompositeHUD::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& inputs) { assert(renderContext->args); assert(renderContext->args->_context); @@ -119,6 +119,9 @@ void CompositeHUD::run(const RenderContextPointer& renderContext) { renderContext->args->getViewFrustum().evalViewTransform(viewMat); batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat, true); + if (inputs) { + batch.setFramebuffer(inputs); + } if (renderContext->args->_hudOperator) { renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE); } diff --git a/libraries/render-utils/src/RenderCommonTask.h b/libraries/render-utils/src/RenderCommonTask.h index a1de50abba..bc1031a18c 100644 --- a/libraries/render-utils/src/RenderCommonTask.h +++ b/libraries/render-utils/src/RenderCommonTask.h @@ -77,10 +77,12 @@ protected: class CompositeHUD { public: - using JobModel = render::Job::Model; + // IF specified the input Framebuffer is actively set by the batch of this job before calling the HUDOperator. + // If not, the current Framebuffer is left unchanged. + //using Inputs = gpu::FramebufferPointer; + using JobModel = render::Job::ModelI; - CompositeHUD() {} - void run(const render::RenderContextPointer& renderContext); + void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& inputs); }; class Blit { diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index a685f3998e..44b38c0d8d 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -258,7 +258,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto primaryFramebuffer = task.addJob("PrimaryBufferUpscale", scaledPrimaryFramebuffer); // Composite the HUD and HUD overlays - task.addJob("HUD"); + task.addJob("HUD", primaryFramebuffer); const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f)); const auto overlayHUDOpaquesInputs = DrawOverlay3D::Inputs(overlaysHUDOpaque, lightingModel, nullJitter).asVarying(); diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index c47935c6fc..850de8eae9 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -130,20 +130,20 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend } // Just resolve the msaa -/* const auto resolveInputs = + const auto resolveInputs = ResolveFramebuffer::Inputs(framebuffer, static_cast(nullptr)).asVarying(); - auto resolvedFramebuffer = task.addJob("Resolve", resolveInputs); */ - auto resolvedFramebuffer = task.addJob("Resolve", framebuffer); + const auto resolvedFramebuffer = task.addJob("Resolve", resolveInputs); + //auto resolvedFramebuffer = task.addJob("Resolve", framebuffer); // Lighting Buffer ready for tone mapping // Forward rendering on GLES doesn't support tonemapping to and from the same FBO, so we specify // the output FBO as null, which causes the tonemapping to target the blit framebuffer - const auto toneMappingInputs = ToneMappingDeferred::Inputs(resolvedFramebuffer, static_cast(nullptr)).asVarying(); - task.addJob("ToneMapping", toneMappingInputs); + //const auto toneMappingInputs = ToneMappingDeferred::Inputs(resolvedFramebuffer, static_cast(nullptr)).asVarying(); + //task.addJob("ToneMapping", toneMappingInputs); // Layered Overlays // Composite the HUD and HUD overlays - task.addJob("HUD"); + task.addJob("HUD", resolvedFramebuffer); // Disable blit because we do tonemapping and compositing directly to the blit FBO // Blit! From 522a9ed7c1acfc14220a2bd32fe8c3c8cd53acb7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 14 Feb 2019 15:43:36 -0800 Subject: [PATCH 3/3] Keeping only the minimum for quest --- libraries/render-utils/src/RenderForwardTask.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 850de8eae9..95bd26e165 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -135,11 +135,14 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend const auto resolvedFramebuffer = task.addJob("Resolve", resolveInputs); //auto resolvedFramebuffer = task.addJob("Resolve", framebuffer); +#if defined(Q_OS_ANDROID) +#else // Lighting Buffer ready for tone mapping // Forward rendering on GLES doesn't support tonemapping to and from the same FBO, so we specify // the output FBO as null, which causes the tonemapping to target the blit framebuffer - //const auto toneMappingInputs = ToneMappingDeferred::Inputs(resolvedFramebuffer, static_cast(nullptr)).asVarying(); - //task.addJob("ToneMapping", toneMappingInputs); + const auto toneMappingInputs = ToneMappingDeferred::Inputs(resolvedFramebuffer, static_cast(nullptr)).asVarying(); + task.addJob("ToneMapping", toneMappingInputs); +#endif // Layered Overlays // Composite the HUD and HUD overlays