From d2900b886967b64acda1788d58b49012e8571551 Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Sun, 23 Apr 2023 18:23:16 +0200 Subject: [PATCH] [MultiView] Recreate resolve layers if user calls RenderStage::setFrameBufferObject() or RenderStage::setMultisampleResolveFramebufferObject --- include/osgUtil/RenderStage | 4 +- src/osgUtil/RenderStage.cpp | 118 +++++++++++++++++++++++++----------- 2 files changed, 87 insertions(+), 35 deletions(-) diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index 3dc70b499c4..04d33cc34e5 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -167,7 +167,7 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin /** Set a framebuffer object to render into. It is permissible for the * framebuffer object to be multisampled, in which case you should also * set a resolve framebuffer object - see setMultisampleResolveFramebufferObject(). */ - void setFrameBufferObject(osg::FrameBufferObject* fbo) { _fbo = fbo; } + void setFrameBufferObject(osg::FrameBufferObject* fbo); osg::FrameBufferObject* getFrameBufferObject() { return _fbo.get(); } const osg::FrameBufferObject* getFrameBufferObject() const { return _fbo.get(); } @@ -316,6 +316,8 @@ protected: // VRV_PATCH BEGIN // for resolving individual layers of a multisampled texture 2d array + void runResolveArrayLayersSetup(); + bool _resolveArrayLayersNeedSetup; std::vector> _arrayLayerFbos; std::vector> _resolveArrayLayerFbos; // VRV_PATCH END diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index 0ed49909c97..432d9a3f2c4 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -64,6 +64,8 @@ RenderStage::RenderStage(): _imageReadPixelFormat = GL_RGBA; _imageReadPixelDataType = GL_UNSIGNED_BYTE; + + _resolveArrayLayersNeedSetup = false; } RenderStage::RenderStage(SortMode mode): @@ -131,6 +133,69 @@ RenderStage::~RenderStage() { } +void osgUtil::RenderStage::runResolveArrayLayersSetup() +{ + _resolveArrayLayersNeedSetup = false; + + if (!_fbo || !_resolveFbo) return; + + OSG_INFO << "RenderStage::runResolveArrayLayersSetup() " << this << std::endl; + + const osg::FrameBufferObject::AttachmentMap& bufferAttachments = _fbo->getAttachmentMap(); + const osg::FrameBufferObject::AttachmentMap& resolveBufferAttachments = _resolveFbo->getAttachmentMap(); + _resolveArrayLayerFbos.clear(); + _arrayLayerFbos.clear(); + + for (osg::FrameBufferObject::AttachmentMap::const_iterator itr = bufferAttachments.begin(); + itr != bufferAttachments.end(); + ++itr) + { + osg::FrameBufferObject::BufferComponent buffer = itr->first; + if (resolveBufferAttachments.count(buffer) == 0) + continue; + + osg::FrameBufferAttachment msaaAttachment = _fbo->getAttachment(buffer); + osg::FrameBufferAttachment resolveAttachment = _resolveFbo->getAttachment(buffer); + osg::Texture2DMultisampleArray* msaaAttachmentAsTex2dArray = dynamic_cast(msaaAttachment.getTexture()); + osg::Texture2DArray* attachmentAsTex2dArray = dynamic_cast(resolveAttachment.getTexture()); + + int depth = attachmentAsTex2dArray->getTextureDepth(); + + // make a read and draw fbos for each layer so we can resolve later + for (unsigned int i = 0; i < static_cast(depth); i++) + { + osg::ref_ptr layerfbo; + osg::ref_ptr resolvelayerfbo; + + if (static_cast(_arrayLayerFbos.size()) <= i) + { + layerfbo = new osg::FrameBufferObject; + layerfbo->setName(_camera->getName() + "_layer_"); + _arrayLayerFbos.push_back(layerfbo); + } + else + { + layerfbo = _arrayLayerFbos[i]; + } + + if (static_cast(_resolveArrayLayerFbos.size()) <= i) + { + resolvelayerfbo = new osg::FrameBufferObject; + resolvelayerfbo->setName(_camera->getName() + "_resolvelayer_"); + _resolveArrayLayerFbos.push_back(resolvelayerfbo); + } + else + { + resolvelayerfbo = _resolveArrayLayerFbos[i]; + } + + resolvelayerfbo->setAttachment(buffer, osg::FrameBufferAttachment(attachmentAsTex2dArray, i, 0)); + layerfbo->setAttachment(buffer, osg::FrameBufferAttachment(msaaAttachmentAsTex2dArray, i, 0)); + + } + } +} + void RenderStage::reset() { _stageDrawnThisFrame = false; @@ -465,39 +530,11 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) osg::Texture2DMultisampleArray* multiSampleTexArray = new osg::Texture2DMultisampleArray(width, height, depth, internalFormat, samples, GL_FALSE); fbo_multisample->setAttachment(buffer, osg::FrameBufferAttachment(multiSampleTexArray, attachment._face, 0)); - osg::Texture2DArray* attachmentAsTex2dArray = dynamic_cast(attachment._texture.get()); + // Since we're using a texture instead of a RenderBuffer, we have to disable mipmap generation + // by changing the MIN_FILTER which defaults to LINEAR_MIPMAP_LINEAR. + multiSampleTexArray->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); - // make a read and draw fbos for each layer so we can resolve later - for(unsigned int i=0; i layerfbo; - osg::ref_ptr resolvelayerfbo; - - if(static_cast(_arrayLayerFbos.size()) <= i) - { - layerfbo = new osg::FrameBufferObject; - layerfbo->setName(_camera->getName() + "_layer_"); - _arrayLayerFbos.push_back(layerfbo); - } - else - { - layerfbo = _arrayLayerFbos[i]; - } - - if (static_cast(_resolveArrayLayerFbos.size()) <= i) - { - resolvelayerfbo = new osg::FrameBufferObject; - resolvelayerfbo->setName(_camera->getName() + "_resolvelayer_"); - _resolveArrayLayerFbos.push_back(resolvelayerfbo); - } - else - { - resolvelayerfbo = _resolveArrayLayerFbos[i]; - } - - resolvelayerfbo->setAttachment(buffer, osg::FrameBufferAttachment(attachmentAsTex2dArray, i, 0)); - layerfbo->setAttachment(buffer, osg::FrameBufferAttachment(multiSampleTexArray, i, 0)); - } + _resolveArrayLayersNeedSetup = true; } else { @@ -1101,9 +1138,12 @@ void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, b else { // VRV_PATCH BEGIN - if (blitMask) + if (_resolveArrayLayersNeedSetup || _arrayLayerFbos.empty() || _resolveArrayLayerFbos.empty()) + runResolveArrayLayersSetup(); + + for (unsigned int i = 0; i < _resolveArrayLayerFbos.size(); i++) { - for(unsigned int i = 0; i < _resolveArrayLayerFbos.size(); i++) + if (blitMask) { //_arrayLayerFbos[i]->dirtyAll(); _arrayLayerFbos[i]->apply(state, FrameBufferObject::READ_FRAMEBUFFER); @@ -1579,6 +1619,13 @@ unsigned int RenderStage::computeNumberOfDynamicRenderLeaves() const } +void osgUtil::RenderStage::setFrameBufferObject(osg::FrameBufferObject* fbo) +{ + _fbo = fbo; + if (!_arrayLayerFbos.empty()) + _resolveArrayLayersNeedSetup = true; +} + void RenderStage::setMultisampleResolveFramebufferObject(osg::FrameBufferObject* fbo) { if (fbo && fbo->isMultisample()) @@ -1587,6 +1634,9 @@ void RenderStage::setMultisampleResolveFramebufferObject(osg::FrameBufferObject* " multisampled." << std::endl; } _resolveFbo = fbo; + + if (!_resolveArrayLayerFbos.empty()) + _resolveArrayLayersNeedSetup = true; } void RenderStage::collateReferencesToDependentCameras()