Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memoryless tiler #477

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions OgreMain/include/OgreDepthBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ namespace Ogre
POOL_NO_DEPTH = 0,
POOL_MANUAL_USAGE OGRE_DEPRECATED_ENUM_VER( 3 ) = 0,
POOL_DEFAULT = 1,

/// The depth buffer doesn't does not have memory backing it.
/// It will be created with TextureFlags::TilerMemoryless.
POOL_MEMORYLESS = 65533,

/// Deprecated.
///
/// Do NOT use this flag directly. It made sense in Ogre 2.1
Expand Down
4 changes: 4 additions & 0 deletions OgreMain/include/OgreRenderPassDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ namespace Ogre

protected:
void checkRequiresTextureFlipping();
void validateMemorylessTexture( const TextureGpu *texture,
const LoadAction::LoadAction loadAction,
const StoreAction::StoreAction storeAction,
const bool bIsDepthStencil );
virtual void colourEntriesModified();

public:
Expand Down
17 changes: 16 additions & 1 deletion OgreMain/include/OgreTextureGpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,21 @@ namespace Ogre
/// frames (e.g. HDR luminance change over time)
///
/// If this flag is present, either RenderToTexture or Uav must be present
DiscardableContent = 1u << 14u
DiscardableContent = 1u << 14u,
/// When this flag is present, we can save VRAM by using memoryless storage mode (Metal on
/// iOS and Apple Silicon macOS) aka TRANSIENT memory (Vulkan).
///
/// With this flag set, the texture will not be backed by memory, it will only ever live in
/// cache. Only TBDR GPUs support this. It will be ignored if unsupported.
///
/// Many operations are unsupported with TilerMemoryless textures (e.g. copy operations)
/// because there is no memory behind them.
///
/// An example is a depth or stencil texture thatʼs used only within a render pass
/// and isnʼt needed before or after GPU execution.
///
/// This flag requires RenderToTexture.
TilerMemoryless = 1u << 15u,
// clang-format on
};
}
Expand Down Expand Up @@ -649,6 +663,7 @@ namespace Ogre
bool isManualTexture() const;
bool isPoolOwner() const;
bool isDiscardableContent() const;
bool isTilerMemoryless() const { return ( mTextureFlags & TextureFlags::TilerMemoryless ) != 0; }

/// OpenGL RenderWindows are a bit specific:
/// * Their origins are upside down. Which means we need to flip Y.
Expand Down
5 changes: 4 additions & 1 deletion OgreMain/include/OgreWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ namespace Ogre

void setFinalResolution( uint32 widthPx, uint32 heightPx );

static bool requestedMemoryless( const NameValuePairList *ogre_nullable miscParams );

public:
Window( const String &title, uint32 widthPt, uint32 heightPt, bool fullscreenMode );
virtual ~Window();
Expand Down Expand Up @@ -288,7 +290,8 @@ namespace Ogre
void _setPrimary();
bool isPrimary() const;

virtual void _initialize( TextureGpuManager *textureGpuManager ) = 0;
virtual void _initialize( TextureGpuManager *textureGpuManager,
const NameValuePairList *ogre_nullable miscParams ) = 0;

/// Overloaded version of getMetrics from RenderTarget, including extra details
/// specific to windowing systems. Result is in pixels.
Expand Down
2 changes: 2 additions & 0 deletions OgreMain/src/OgreAsyncTextureTicket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ namespace Ogre
assert( ( !textureSrc->isMultisample() || !textureSrc->hasMsaaExplicitResolves() ||
textureSrc->isOpenGLRenderWindow() ) &&
"Cannot download from an explicitly resolved MSAA texture!" );
OGRE_ASSERT_LOW( !textureSrc->isTilerMemoryless() &&
"Cannot download from a memoryless texture!" );
}
//-----------------------------------------------------------------------------------
void AsyncTextureTicket::notifyTextureChanged( TextureGpu *texture,
Expand Down
57 changes: 57 additions & 0 deletions OgreMain/src/OgreRenderPassDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,47 @@ namespace Ogre
mRequiresTextureFlipping = mColour[0].resolveTexture->requiresTextureFlipping();
}
//-----------------------------------------------------------------------------------
void RenderPassDescriptor::validateMemorylessTexture( const TextureGpu *texture,
const LoadAction::LoadAction loadAction,
const StoreAction::StoreAction storeAction,
const bool bIsDepthStencil )
{
if( !texture->isTilerMemoryless() )
return;

if( loadAction != LoadAction::Clear && loadAction != LoadAction::DontCare &&
loadAction != LoadAction::ClearOnTilers )
{
OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
"Texture '" + texture->getNameStr() +
"' is TilerMemoryless. For load actions it can only use clear, "
"dont_care or clear_on_tilers.",
"RenderPassDescriptor::validateMemorylessTexture" );
}

if( !texture->isMultisample() || bIsDepthStencil )
{
if( storeAction != StoreAction::DontCare )
{
OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
"Texture '" + texture->getNameStr() +
"' is TilerMemoryless. For store actions it can only use dont_care.",
"RenderPassDescriptor::validateMemorylessTexture" );
}
}
else
{
if( storeAction != StoreAction::DontCare && storeAction != StoreAction::MultisampleResolve )
{
OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
"MSAA Texture '" + texture->getNameStr() +
"' is TilerMemoryless. For store actions it can only use dont_care "
"or resolve.",
"RenderPassDescriptor::validateMemorylessTexture" );
}
}
}
//-----------------------------------------------------------------------------------
void RenderPassDescriptor::colourEntriesModified()
{
mNumColourEntries = 0;
Expand All @@ -176,6 +217,9 @@ namespace Ogre
{
const RenderPassColourTarget &colourEntry = mColour[mNumColourEntries];

validateMemorylessTexture( colourEntry.texture, colourEntry.loadAction,
colourEntry.storeAction, false );

if( colourEntry.texture->isRenderWindowSpecific() )
{
RenderPassColourTarget &colourEntryRW = mColour[mNumColourEntries];
Expand Down Expand Up @@ -208,6 +252,14 @@ namespace Ogre
"RenderPassDescriptor::colourEntriesModified" );
}

if( colourEntry.resolveTexture->isTilerMemoryless() )
{
OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
"Resolving to Texture '" + colourEntry.resolveTexture->getNameStr() +
"' which is memoryless!",
"RenderPassDescriptor::colourEntriesModified" );
}

if( colourEntry.texture != colourEntry.resolveTexture &&
!colourEntry.texture->hasMsaaExplicitResolves() )
{
Expand Down Expand Up @@ -305,6 +357,8 @@ namespace Ogre
"RenderPassDescriptor::entriesModified" );
}
}

validateMemorylessTexture( mDepth.texture, mDepth.loadAction, mDepth.storeAction, true );
}

if( mStencil.texture && mStencil.texture != mDepth.texture )
Expand All @@ -323,6 +377,9 @@ namespace Ogre
"RenderPassDescriptor::entriesModified" );
}
}

validateMemorylessTexture( mStencil.texture, mStencil.loadAction, mStencil.storeAction,
true );
}

checkRequiresTextureFlipping();
Expand Down
3 changes: 3 additions & 0 deletions OgreMain/src/OgreRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,9 @@ namespace Ogre
if( !preferDepthTexture )
textureFlags |= TextureFlags::NotTexture | TextureFlags::DiscardableContent;

if( colourTexture->getDepthBufferPoolId() == DepthBuffer::POOL_MEMORYLESS )
textureFlags |= TextureFlags::TilerMemoryless;

char tmpBuffer[64];
LwString depthBufferName( LwString::FromEmptyPointer( tmpBuffer, sizeof( tmpBuffer ) ) );
depthBufferName.a( "DepthBuffer_", Id::generateNewId<TextureGpu>() );
Expand Down
8 changes: 8 additions & 0 deletions OgreMain/src/OgreStagingTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ namespace Ogre
"Did you modify it? Did it get corrupted?" );
assert( ( !cpuSrcBox || srcBox.equalSize( *cpuSrcBox ) ) && "Src & cpuSrcBox must be equal" );

if( dstTexture->isTilerMemoryless() )
{
OGRE_EXCEPT(
Exception::ERR_INVALIDPARAMS,
"Cannot upload to texture '" + dstTexture->getNameStr() + "' because it's memoryless.",
"StagingTexture::upload" );
}

if( dstTexture->isMultisample() )
{
OGRE_EXCEPT(
Expand Down
5 changes: 5 additions & 0 deletions OgreMain/src/OgreTextureGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ THE SOFTWARE.

#include "OgreTextureGpu.h"

#include "OgreDepthBuffer.h"
#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreLwString.h"
Expand Down Expand Up @@ -668,6 +669,8 @@ namespace Ogre
assert( this != dst || !srcBox.overlaps( dstBox ) );
assert( srcMipLevel < this->getNumMipmaps() && dstMipLevel < dst->getNumMipmaps() );
OGRE_ASSERT_LOW( ( this->getOrientationMode() & 0x01 ) == ( dst->getOrientationMode() & 0x01 ) );
OGRE_ASSERT_LOW( !this->isTilerMemoryless() );
OGRE_ASSERT_LOW( !dst->isTilerMemoryless() );
}
//-----------------------------------------------------------------------------------
void TextureGpu::_setDepthBufferDefaults( uint16 depthBufferPoolId, bool preferDepthTexture,
Expand Down Expand Up @@ -912,6 +915,8 @@ namespace Ogre
if( this->getInternalWidth() == colourTarget->getInternalWidth() &&
this->getInternalHeight() == colourTarget->getInternalHeight() &&
this->getSampleDescription() == colourTarget->getSampleDescription() &&
this->isTilerMemoryless() ==
( colourTarget->getDepthBufferPoolId() == DepthBuffer::POOL_MEMORYLESS ) &&
this->isRenderWindowSpecific() == colourTarget->isRenderWindowSpecific() )
{
return true;
Expand Down
15 changes: 15 additions & 0 deletions OgreMain/src/OgreWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ THE SOFTWARE.
#include "OgreWindow.h"

#include "OgreException.h"
#include "OgreStringConverter.h"

namespace Ogre
{
Expand Down Expand Up @@ -71,6 +72,20 @@ namespace Ogre
if( mStencilBuffer )
mStencilBuffer->setResolution( widthPx, heightPx, 1u );
}
//-------------------------------------------------------------------------
bool Window::requestedMemoryless( const NameValuePairList *ogre_nullable miscParams )
{
if( !miscParams )
return false;

NameValuePairList::const_iterator opt;
NameValuePairList::const_iterator end = miscParams->end();

opt = miscParams->find( "memoryless_depth_buffer" );
if( opt != end )
return StringConverter::parseBool( opt->second );
return false;
}
//-----------------------------------------------------------------------------------
void Window::setTitle( const String &title ) { mTitle = title; }
//-----------------------------------------------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion RenderSystems/Direct3D11/include/OgreD3D11Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ namespace Ogre
D3D11RenderSystem *renderSystem );
~D3D11WindowSwapChainBased() override;

void _initialize( TextureGpuManager *textureGpuManager ) override;
void _initialize( TextureGpuManager *textureGpuManager,
const NameValuePairList *ogre_nullable miscParams ) override;
void destroy() override;

/// @copydoc Window::setFsaa
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ namespace Ogre
D3D11Device &device, D3D11RenderSystem *renderSystem );
~D3D11WindowHwnd() override;

void _initialize( TextureGpuManager *textureGpuManager ) override;
void _initialize( TextureGpuManager *textureGpuManager,
const NameValuePairList *ogre_nullable miscParams ) override;
void destroy() override;

void reposition( int32 left, int32 top ) override;
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ namespace Ogre
mSecondaryWindows.push_back( win );
}

win->_initialize( mTextureGpuManager );
win->_initialize( mTextureGpuManager, miscParams );

return win;
}
Expand Down
3 changes: 2 additions & 1 deletion RenderSystems/Direct3D11/src/OgreD3D11Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ namespace Ogre
return mUseFlipMode ? 2 : mRenderSystem->getVaoManager()->getDynamicBufferMultiplier() - 1u;
}
//-----------------------------------------------------------------------------------
void D3D11WindowSwapChainBased::_initialize( TextureGpuManager *textureGpuManager )
void D3D11WindowSwapChainBased::_initialize( TextureGpuManager *textureGpuManager,
const NameValuePairList * )
{
_createSwapChain();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,10 @@ namespace Ogre
setHidden( mHidden );
}
//-----------------------------------------------------------------------------------
void D3D11WindowHwnd::_initialize( TextureGpuManager *textureGpuManager )
void D3D11WindowHwnd::_initialize( TextureGpuManager *textureGpuManager,
const NameValuePairList *miscParams )
{
D3D11WindowSwapChainBased::_initialize( textureGpuManager );
D3D11WindowSwapChainBased::_initialize( textureGpuManager, miscParams );

IDXGIFactory1 *dxgiFactory1 = mDevice.GetDXGIFactory();
dxgiFactory1->MakeWindowAssociation( mHwnd,
Expand Down
7 changes: 6 additions & 1 deletion RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ THE SOFTWARE.

namespace Ogre
{
OGRE_ASSUME_NONNULL_BEGIN

class _OgrePrivate GLXWindow final : public Window
{
protected:
Expand All @@ -60,7 +62,8 @@ namespace Ogre
GLXGLSupport *glsupport );
~GLXWindow() override;

void _initialize( TextureGpuManager *textureManager ) override;
void _initialize( TextureGpuManager *textureManager,
const NameValuePairList *ogre_nullable miscParams ) override;

void setVSync( bool vSync, uint32 vSyncInterval ) override;
void reposition( int32 left, int32 top ) override;
Expand Down Expand Up @@ -108,6 +111,8 @@ namespace Ogre

bool requiresTextureFlipping() const { return false; }
};

OGRE_ASSUME_NONNULL_END
} // namespace Ogre

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ namespace Ogre
Win32GLSupport &glsupport );
virtual ~Win32Window();

virtual void _initialize( TextureGpuManager *textureGpuManager );
virtual void _initialize( TextureGpuManager *textureGpuManager,
const NameValuePairList *ogre_nullable miscParams );
virtual void destroy();

virtual void reposition( int32 left, int32 top );
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ namespace Ogre
mTextureGpuManager->_update( true );
}

win->_initialize( mTextureGpuManager );
win->_initialize( mTextureGpuManager, miscParams );

return win;
}
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/GL3Plus/src/windowing/GLX/OgreGLXWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ namespace Ogre
mClosed = false;
}
//-----------------------------------------------------------------------------------
void GLXWindow::_initialize( TextureGpuManager *_textureManager )
void GLXWindow::_initialize( TextureGpuManager *_textureManager, const NameValuePairList * )
{
GL3PlusTextureGpuManager *textureManager =
static_cast<GL3PlusTextureGpuManager *>( _textureManager );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ namespace Ogre
mFullscreenMode = mRequestedFullscreenMode;
}
//-----------------------------------------------------------------------------------
void Win32Window::_initialize( TextureGpuManager *textureGpuManager )
void Win32Window::_initialize( TextureGpuManager *textureGpuManager, const NameValuePairList * )
{
GL3PlusTextureGpuManager *textureManager =
static_cast<GL3PlusTextureGpuManager *>( textureGpuManager );
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/Metal/include/OgreMetalTextureGpuManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace Ogre
If caller doesn't delete it, it will leak.
*/
TextureGpu *createTextureGpuWindow( MetalWindow *window );
TextureGpu *createWindowDepthBuffer();
TextureGpu *createWindowDepthBuffer( const bool bMemoryLess );

id<MTLTexture> getBlankTextureMetalName( TextureTypes::TextureTypes textureType ) const;

Expand Down
3 changes: 2 additions & 1 deletion RenderSystems/Metal/include/OgreMetalWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ namespace Ogre
virtual void create( bool fullScreen, const NameValuePairList *miscParams );
void destroy() override;

void _initialize( TextureGpuManager *textureGpuManager ) override;
void _initialize( TextureGpuManager *textureGpuManager,
const NameValuePairList *miscParams ) override;

void reposition( int32 left, int32 top ) override;
void requestResolution( uint32 width, uint32 height ) override;
Expand Down
Loading
Loading