OGRE-Next  4.0.0unstable
Object-Oriented Graphics Rendering Engine
Ogre::StagingBuffer Class Referenceabstract

A staging buffer is a buffer that resides on the GPU and be written to/from both CPU & GPU However the access in both cases is limited. More...

#include <OgreStagingBuffer.h>

+ Inheritance diagram for Ogre::StagingBuffer:

Classes

struct  Destination
 

Public Types

typedef vector< Destination >::type DestinationVec
 

Public Member Functions

 StagingBuffer (size_t internalBufferStart, size_t sizeBytes, VaoManager *vaoManager, bool uploadOnly)
 
virtual ~StagingBuffer ()
 
virtual size_t _asyncDownload (BufferPacked *source, size_t srcOffset, size_t srcLength)=0
 Copies the GPU data in BufferPacked to the StagingBuffer so that it can be later read by the CPU using an AsyncTicket. More...
 
virtual void _cancelDownload (size_t offset, size_t sizeBytes)
 Releases memory assigned to a download that hasn't been mapped yet, to make space for another _asyncDownload call. More...
 
const void * _mapForRead (size_t offset, size_t sizeBytes)
 Maps the buffer for read acces for the CPU. More...
 
void addReferenceCount ()
 Adds a reference count to the StagingBuffer. More...
 
virtual bool canDownload (size_t length) const
 Checks if this staging buffer has enough free space to use _asyncDownload. More...
 
uint64 getLastUsedTimestamp () const
 Returns the time in millisecond when the ref. count became 0. More...
 
uint32 getLifetimeThreshold () const
 Returns the time in milliseconds in which a StagingBuffer should live with a reference count of 0 before being deleted. More...
 
MappingState getMappingState () const
 
size_t getMaxSize ()
 
int16 getReferenceCount () const
 
uint32 getUnfencedTimeThreshold () const
 Returns the time in milliseconds in which a StagingBuffer should hazards unfenced while with a reference count of 0. More...
 
bool getUploadOnly () const
 When true, this buffer can only be used for uploading to GPU. More...
 
void * map (size_t sizeBytes)
 Maps the given amount of bytes. More...
 
void removeReferenceCount ()
 Decreases the reference count by one. More...
 
void unmap (const Destination &destination)
 Unmaps the mapped region and copies the data to the given region. More...
 
void unmap (const Destination *destinations, size_t numDestinations)
 
void unmap (const DestinationVec &destinations)
 Unmaps the mapped region and copies the data to multiple buffers. More...
 
virtual StagingStallType uploadWillStall (size_t sizeBytes)
 Returns true if our next call to map() with the same parameters will stall. More...
 

Detailed Description

A staging buffer is a buffer that resides on the GPU and be written to/from both CPU & GPU However the access in both cases is limited.

GPUs can only copy (i.e. memcpy) to another real buffer (can't be used directly as i.e. texture or vertex buffer) and CPUs can only map it. In other words, a staging buffer is an intermediate buffer to transfer data between CPU & GPU

Remarks
The interface is very similar to BufferPacked (
See also
BufferPacked) but it's not the same. A staging buffer can only map/unmap, and it's mapping operations don't accept an "elementStart" argument. Staging buffers always deal with bytes, not elements or bytes per element. RenderSystem implementations also synchronize the mapping differently to avoid excessive memory waste or stalling.
Internally, the staging buffer will have a maximum size and use it as a ring buffer. i.e. if you have a 32MB staging buffer, you can upload 4 meshes of 8 MBs each. On the 5th one the system will first check if the first mesh has already been copied, otherwise it will stall. Trying to map more bytes than the total size is an error.
Staging buffers can't be persistently mapped, since it beats the point.

Member Typedef Documentation

◆ DestinationVec

Constructor & Destructor Documentation

◆ StagingBuffer()

Ogre::StagingBuffer::StagingBuffer ( size_t  internalBufferStart,
size_t  sizeBytes,
VaoManager vaoManager,
bool  uploadOnly 
)

◆ ~StagingBuffer()

virtual Ogre::StagingBuffer::~StagingBuffer ( )
virtual

Member Function Documentation

◆ _asyncDownload()

virtual size_t Ogre::StagingBuffer::_asyncDownload ( BufferPacked source,
size_t  srcOffset,
size_t  srcLength 
)
pure virtual

Copies the GPU data in BufferPacked to the StagingBuffer so that it can be later read by the CPU using an AsyncTicket.

See also
AsyncTicket.
Remarks
For internal use. May throw if it can't handle the request (i.e. requested size is too big, or too many _asyncDownload operations are pending until calling _mapForRead)
See also
canDownload mUploadOnly must be true.
Parameters
sourceThe buffer to copy from.
srcOffsetThe offset, in bytes, of the buffer to copy from.
srcLengthThe size in bytes, of the data to transfer to this staging buffer.
Returns
The offset in bytes that will be used by
See also
_mapForRead

Implemented in Ogre::VulkanStagingBuffer, Ogre::NULLStagingBuffer, Ogre::MetalStagingBuffer, Ogre::GL3PlusStagingBuffer, Ogre::D3D11StagingBuffer, and Ogre::GLES2StagingBuffer.

◆ _cancelDownload()

virtual void Ogre::StagingBuffer::_cancelDownload ( size_t  offset,
size_t  sizeBytes 
)
virtual

Releases memory assigned to a download that hasn't been mapped yet, to make space for another _asyncDownload call.

Useful when you suddenly don't intend to call _mapForRead.

Reimplemented in Ogre::MetalStagingBuffer.

◆ _mapForRead()

const void* Ogre::StagingBuffer::_mapForRead ( size_t  offset,
size_t  sizeBytes 
)

Maps the buffer for read acces for the CPU.

Remarks
For internal use. mUploadOnly must be true. Attempting to const cast the returned pointer and write to it is undefined behavior. Call unmap( 0, 0 ) to unmap. Once mapped and unmapped, the same region shouldn't be remapped.
Parameters
offsetThe returned value from _asyncDownload.
sizeBytesThe size in bytes of the data to map. Should be parameter 'srcLength' passed to _asyncDownload.
Returns
The pointer with the data read from the GPU. Read only.

◆ addReferenceCount()

void Ogre::StagingBuffer::addReferenceCount ( )

Adds a reference count to the StagingBuffer.

See also
removeReferenceCount

◆ canDownload()

virtual bool Ogre::StagingBuffer::canDownload ( size_t  length) const
virtual

Checks if this staging buffer has enough free space to use _asyncDownload.

Otherwise such function would raise an exception.

Remarks
mUploadOnly must be true. It is the counter side of
See also
uploadWillStall
Parameters
lengthThe size in bytes that need to be downloaded.

Reimplemented in Ogre::MetalStagingBuffer.

◆ getLastUsedTimestamp()

uint64 Ogre::StagingBuffer::getLastUsedTimestamp ( ) const
inline

Returns the time in millisecond when the ref. count became 0.

◆ getLifetimeThreshold()

uint32 Ogre::StagingBuffer::getLifetimeThreshold ( ) const
inline

Returns the time in milliseconds in which a StagingBuffer should live with a reference count of 0 before being deleted.

◆ getMappingState()

MappingState Ogre::StagingBuffer::getMappingState ( ) const
inline

◆ getMaxSize()

size_t Ogre::StagingBuffer::getMaxSize ( )
inline

◆ getReferenceCount()

int16 Ogre::StagingBuffer::getReferenceCount ( ) const
inline

◆ getUnfencedTimeThreshold()

uint32 Ogre::StagingBuffer::getUnfencedTimeThreshold ( ) const
inline

Returns the time in milliseconds in which a StagingBuffer should hazards unfenced while with a reference count of 0.

See also
getLifetimeThreshold

◆ getUploadOnly()

bool Ogre::StagingBuffer::getUploadOnly ( ) const
inline

When true, this buffer can only be used for uploading to GPU.

When false, can only be used for downloading from GPU

◆ map()

void* Ogre::StagingBuffer::map ( size_t  sizeBytes)

Maps the given amount of bytes.

May block if not ready. See uploadWillStall() if you wish to know.

Remarks
Will throw if sizeBytes > this->getMaxSize()

◆ removeReferenceCount()

void Ogre::StagingBuffer::removeReferenceCount ( )

Decreases the reference count by one.

StagingBuffers are manually reference counted. The first reason is performance. The second main reason is that the pointer doesn't get immediately deleted when the reference hits 0.

Instead, a reference count of 0 means the Vao manager will monitor its lifetime. If it has been 0 for too long (past certain time threshold) the Vao manager will destroy this staging buffer.
Meanwhile, the Staging Buffer will live in a pool until it's requested again or the time threshold is met. This prevents unwanted hiccups due to buffers getting recreated and destroyed all the time. Keep a non-zero ref. count to ensure the StagingBuffer won't be deleted due to timeouts (i.e. you know this buffer will get used at long regular intervals, like once every 15 minutes)
Having a non-zero reference count doesn't mean the pointer will live forever though, as the memory is owned by the VaoManager: if the VaoManager is shutdown, this StagingBuffer will be freed.

◆ unmap() [1/3]

void Ogre::StagingBuffer::unmap ( const Destination destination)
inline

Unmaps the mapped region and copies the data to the given region.

See also
Destination

References unmap().

Referenced by unmap().

◆ unmap() [2/3]

void Ogre::StagingBuffer::unmap ( const Destination destinations,
size_t  numDestinations 
)

◆ unmap() [3/3]

void Ogre::StagingBuffer::unmap ( const DestinationVec destinations)
inline

Unmaps the mapped region and copies the data to multiple buffers.

Useful when loading many meshes or textures at once (i.e. from multiple threads)

◆ uploadWillStall()

virtual StagingStallType Ogre::StagingBuffer::uploadWillStall ( size_t  sizeBytes)
virtual

Returns true if our next call to map() with the same parameters will stall.

See also
StagingStallType
Remarks
Not all RenderSystems can accurately give this information and will always return STALL_PARTIAL (i.e. GLES2) The chances of getting a STALL_FULL get higher as sizeBytes gets closer to this->getMaxSize() mUploadOnly must be false. It is the counter side of
See also
canDownload

Reimplemented in Ogre::VulkanStagingBuffer, Ogre::NULLStagingBuffer, Ogre::MetalStagingBuffer, Ogre::GL3PlusStagingBuffer, Ogre::D3D11StagingBuffer, and Ogre::GLES2StagingBuffer.


The documentation for this class was generated from the following file: