From 18af60f3ebafe298fa4310ff8cc1fa1f390c5b15 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 19 Feb 2018 18:48:58 +0100 Subject: [PATCH] Added RingBuffer mechanism to gpu lib --- libraries/gpu/src/gpu/Batch.cpp | 21 +++++++ libraries/gpu/src/gpu/Batch.h | 13 +++- libraries/gpu/src/gpu/Framebuffer.h | 3 + libraries/gpu/src/gpu/ResourceRing.h | 62 +++++++++++++++++++ .../render-utils/src/AntialiasingEffect.cpp | 40 ++++++------ .../render-utils/src/AntialiasingEffect.h | 5 +- 6 files changed, 119 insertions(+), 25 deletions(-) create mode 100644 libraries/gpu/src/gpu/ResourceRing.h diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 6a07b2bb61..2c53d4a20c 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -320,6 +320,14 @@ void Batch::setResourceTexture(uint32 slot, const TextureView& view) { setResourceTexture(slot, view._texture); } +void Batch::setResourceFramebufferRingTexture(uint32 slot, const FramebufferRingPointer& framebuffer, unsigned int ringIndex) { + ADD_COMMAND(setResourceFramebufferRingTexture); + + _params.emplace_back(_ringbuffers.cache(framebuffer)); + _params.emplace_back(slot); + _params.emplace_back(ringIndex); +} + void Batch::setFramebuffer(const FramebufferPointer& framebuffer) { ADD_COMMAND(setFramebuffer); @@ -327,6 +335,19 @@ void Batch::setFramebuffer(const FramebufferPointer& framebuffer) { } +void Batch::setFramebufferRing(const FramebufferRingPointer& framebuffer, unsigned int ringIndex) { + ADD_COMMAND(setFramebufferRing); + + _params.emplace_back(_ringbuffers.cache(framebuffer)); + _params.emplace_back(ringIndex); +} + +void Batch::advance(const RingBufferPointer& ringbuffer) { + ADD_COMMAND(advance); + + _params.emplace_back(_ringbuffers.cache(ringbuffer)); +} + void Batch::clearFramebuffer(Framebuffer::Masks targets, const Vec4& color, float depth, int stencil, bool enableScissor) { ADD_COMMAND(clearFramebuffer); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 4f4ea33679..eb716b1926 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -187,11 +187,14 @@ public: void setResourceTexture(uint32 slot, const TexturePointer& texture); void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView - + void setResourceFramebufferRingTexture(uint32 slot, const FramebufferRingPointer& framebuffer, unsigned int ringIndex); // not a command, just a shortcut from a TextureView // Ouput Stage void setFramebuffer(const FramebufferPointer& framebuffer); - + void setFramebufferRing(const FramebufferRingPointer& framebuffer, unsigned int ringIndex); + + void advance(const RingBufferPointer& ringbuffer); + // Clear framebuffer layers // Targets can be any of the render buffers contained in the currnetly bound Framebuffer // Optionally the scissor test can be enabled locally for this command and to restrict the clearing command to the pixels contained in the scissor rectangle @@ -299,12 +302,16 @@ public: COMMAND_setUniformBuffer, COMMAND_setResourceBuffer, COMMAND_setResourceTexture, + COMMAND_setResourceFramebufferRingTexture, COMMAND_setFramebuffer, + COMMAND_setFramebufferRing, COMMAND_clearFramebuffer, COMMAND_blit, COMMAND_generateTextureMips, + COMMAND_advance, + COMMAND_beginQuery, COMMAND_endQuery, COMMAND_getQuery, @@ -421,6 +428,7 @@ public: typedef Cache::Vector TransformCaches; typedef Cache::Vector PipelineCaches; typedef Cache::Vector FramebufferCaches; + typedef Cache::Vector RingBufferCaches; typedef Cache::Vector QueryCaches; typedef Cache::Vector StringCaches; typedef Cache>::Vector LambdaCache; @@ -475,6 +483,7 @@ public: TransformCaches _transforms; PipelineCaches _pipelines; FramebufferCaches _framebuffers; + RingBufferCaches _ringbuffers; QueryCaches _queries; LambdaCache _lambdas; StringCaches _profileRanges; diff --git a/libraries/gpu/src/gpu/Framebuffer.h b/libraries/gpu/src/gpu/Framebuffer.h index f470cc8aa9..b0cd898eea 100755 --- a/libraries/gpu/src/gpu/Framebuffer.h +++ b/libraries/gpu/src/gpu/Framebuffer.h @@ -12,6 +12,7 @@ #define hifi_gpu_Framebuffer_h #include "Texture.h" +#include "ResourceRing.h" #include class Transform; // Texcood transform util @@ -177,6 +178,8 @@ protected: Framebuffer() {} }; typedef std::shared_ptr FramebufferPointer; +typedef ResourceRing FramebufferRing; +typedef std::shared_ptr FramebufferRingPointer; } diff --git a/libraries/gpu/src/gpu/ResourceRing.h b/libraries/gpu/src/gpu/ResourceRing.h new file mode 100644 index 0000000000..c61f7a02f7 --- /dev/null +++ b/libraries/gpu/src/gpu/ResourceRing.h @@ -0,0 +1,62 @@ +// +// Created by Olivier Prat on 2018/02/19 +// Copyright 2013-2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_gpu_ResourceRing_h +#define hifi_gpu_ResourceRing_h + +#include +#include + +namespace gpu { + class RingBuffer { + public: + + RingBuffer(unsigned int size = 2U) : _size{ size } {} + virtual ~RingBuffer() {} + + void advance() { + _frontIndex = (_frontIndex + 1) % _size; + } + + unsigned int getSize() const { return _size; } + + protected: + unsigned int _size; + unsigned int _frontIndex{ 0U }; + + }; + typedef std::shared_ptr RingBufferPointer; + + template + class ResourceRing : public RingBuffer { + public: + + enum { + MAX_SIZE = 4 + }; + + using Type = R; + using TypePointer = std::shared_ptr; + + ResourceRing(unsigned int size = 2U) : RingBuffer{ size } {} + + void reset() { + for (auto& ptr : _resources) { + ptr.reset(); + } + } + + TypePointer& edit(unsigned int index) { return _resources[(index + _frontIndex) % _size]; } + const TypePointer& get(unsigned int index) const { return _resources[(index + _frontIndex) % _size]; } + + private: + + std::array _resources; + }; +} + +#endif diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index f6b4b4d9d8..9f2678770f 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -188,13 +188,13 @@ const int AntialiasingPass_NextMapSlot = 4; Antialiasing::Antialiasing() { + _antialiasingBuffers = std::make_shared(2U); } Antialiasing::~Antialiasing() { - _antialiasingBuffer[0].reset(); - _antialiasingBuffer[1].reset(); - _antialiasingTexture[0].reset(); - _antialiasingTexture[1].reset(); + _antialiasingBuffers.reset(); + _antialiasingTextures[0].reset(); + _antialiasingTextures[1].reset(); } const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { @@ -316,27 +316,26 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const int width = sourceBuffer->getWidth(); int height = sourceBuffer->getHeight(); - if (_antialiasingBuffer[0]) { - if (_antialiasingBuffer[0]->getSize() != uvec2(width, height)) {// || (sourceBuffer && (_antialiasingBuffer->getRenderBuffer(1) != sourceBuffer->getRenderBuffer(0)))) { - _antialiasingBuffer[0].reset(); - _antialiasingBuffer[1].reset(); - _antialiasingTexture[0].reset(); - _antialiasingTexture[1].reset(); + if (_antialiasingBuffers->get(0)) { + if (_antialiasingBuffers->get(0)->getSize() != uvec2(width, height)) {// || (sourceBuffer && (_antialiasingBuffer->getRenderBuffer(1) != sourceBuffer->getRenderBuffer(0)))) { + _antialiasingBuffers->edit(0).reset(); + _antialiasingBuffers->edit(1).reset(); + _antialiasingTextures[0].reset(); + _antialiasingTextures[1].reset(); } } - if (!_antialiasingBuffer[0]) { + if (!_antialiasingBuffers->get(0)) { // Link the antialiasing FBO to texture for (int i = 0; i < 2; i++) { - _antialiasingBuffer[i] = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); + auto& antiAliasingBuffer = _antialiasingBuffers->edit(i); + antiAliasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get()->getLightingTexture()->getTexelFormat(); auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); - _antialiasingTexture[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); - _antialiasingBuffer[i]->setRenderBuffer(0, _antialiasingTexture[i]); + _antialiasingTextures[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); + antiAliasingBuffer->setRenderBuffer(0, _antialiasingTextures[i]); } } - int nextFrame = (_currentFrame++) % 2; - int prevFrame = (nextFrame + 1) % 2; gpu::doInBatch("Antialiasing::run", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); @@ -344,7 +343,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const // TAA step getAntialiasingPipeline(); - batch.setResourceTexture(AntialiasingPass_HistoryMapSlot, _antialiasingTexture[prevFrame]); + batch.setResourceFramebufferRingTexture(AntialiasingPass_HistoryMapSlot, _antialiasingBuffers, 0); batch.setResourceTexture(AntialiasingPass_SourceMapSlot, sourceBuffer->getRenderBuffer(0)); batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, velocityBuffer->getVelocityTexture()); batch.setResourceTexture(AntialiasingPass_DepthMapSlot, linearDepthBuffer->getLinearDepthTexture()); @@ -352,7 +351,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.setUniformBuffer(AntialiasingPass_ParamsSlot, _params); batch.setUniformBuffer(AntialiasingPass_FrameTransformSlot, deferredFrameTransform->getFrameTransformBuffer()); - batch.setFramebuffer(_antialiasingBuffer[nextFrame]); + batch.setFramebufferRing(_antialiasingBuffers, 1); batch.setPipeline(getAntialiasingPipeline()); batch.draw(gpu::TRIANGLE_STRIP, 4); @@ -365,8 +364,9 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const } else { batch.setPipeline(getBlendPipeline()); } - batch.setResourceTexture(AntialiasingPass_NextMapSlot, _antialiasingTexture[nextFrame]); - batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setResourceFramebufferRingTexture(AntialiasingPass_NextMapSlot, _antialiasingBuffers, 1); + batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.advance(_antialiasingBuffers); batch.setUniformBuffer(AntialiasingPass_ParamsSlot, nullptr); batch.setUniformBuffer(AntialiasingPass_FrameTransformSlot, nullptr); diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index d201be3f73..f47a64c589 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -191,15 +191,14 @@ private: // Uniforms for AA gpu::int32 _texcoordOffsetLoc; - gpu::FramebufferPointer _antialiasingBuffer[2]; - gpu::TexturePointer _antialiasingTexture[2]; + gpu::FramebufferRingPointer _antialiasingBuffers; + gpu::TexturePointer _antialiasingTextures[2]; gpu::PipelinePointer _antialiasingPipeline; gpu::PipelinePointer _blendPipeline; gpu::PipelinePointer _debugBlendPipeline; TAAParamsBuffer _params; - int _currentFrame{ 0 }; };