Foundation
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Attributes | List of all members
Foundation::Rendering::GPUScene Class Reference

Scene data management for asynchronous data updates/uploads on the GPU. More...

#include <GPUScene.hpp>

Classes

struct  StagedDoubleBuffer
 Internal staged buffer with a CPU-side (non-driver) data for immediate writes. More...
 

Public Member Functions

 GPUScene (RHIDevice *device, GPUSceneBudgets const &budgets, Allocator *alloc)
 
void CreateUpdatePasses (Renderer *renderer, ResourceHandle &outInstanceBuffer, ResourceHandle &outSharedBuffer, ResourceHandle &outConstBuffer, RHIDeviceQueueType queue=RHIDeviceQueueType::Graphics)
 Creates a pass that performs per-frame updates with correct synchronization.
 
template<typename T >
Span< TMapInstanceData ()
 Maps the instance data for writing. The returned span is valid until UnmapInstanceData is called.
 
void UnmapInstanceData ()
 Unmaps the instance data, allowing other threads to map it again.
 
VirtualAllocation PushShared (Span< const char > data, size_t alignment)
 Push a block of data into the Shared buffer.
 
Pair< size_t, size_tQueryShared (VirtualAllocation allocation)
 
void UpdateShared (VirtualAllocation allocation, Span< const char > data)
 Updates a previously allocated Shared allocation.
 
void FreeShared (VirtualAllocation allocation)
 Frees a previously allocated Shared allocation.
 
VirtualAllocation PushConst (Span< const char > data, size_t alignment)
 Push a block of data into the Const buffer.
 
Pair< size_t, size_tQueryConst (VirtualAllocation id)
 Query a previous const allocation.
 
void UpdateConst (VirtualAllocation allocation, Span< const char > data)
 Updates a previously allocated Const allocation.
 
void FreeConst (VirtualAllocation allocation)
 Frees a previously allocated const.
 

Private Attributes

AllocatormAllocator
 
StagedDoubleBuffer mInstance
 
bool mInstanceDirty {false}
 
Async::Mutex mInstanceMutex
 
StagedDoubleBuffer mShared
 
VirtualAllocator mSharedAlloc
 
Vector< Pair< size_t, size_t > > mSharedUpdateRegions
 
StagedDoubleBuffer mConst
 
VirtualAllocator mConstAlloc
 
Vector< Pair< size_t, size_t > > mConstUpdateRegions
 

Detailed Description

Scene data management for asynchronous data updates/uploads on the GPU.

This implements a 3-tier buffer structure with:

The names are merely a hint to how you could update the data at rates that the names imply (i.e. Instance > Shared > Const), though there's no limit, or inherently how these are transferred to the GPU. However, it's still recommended to follow such patterns.

The update order is well-defined through CreateUpdatePasses You can expect:

Separation of buffers is done to reduce the amount of unnecessary barriers on buffers from e.g. to barrier the geometry data buffer even though we'd only touch bytes of instance data - if they're in the same unit.

Note
All updates are asynchronous - where incremental updates are deferred until GPU execution time, though may still block if the GPU transfer is unavailable

Constructor & Destructor Documentation

◆ GPUScene()

GPUScene::GPUScene ( RHIDevice device,
GPUSceneBudgets const budgets,
Allocator alloc 
)

Member Function Documentation

◆ CreateUpdatePasses()

void GPUScene::CreateUpdatePasses ( Renderer renderer,
ResourceHandle outInstanceBuffer,
ResourceHandle outSharedBuffer,
ResourceHandle outConstBuffer,
RHIDeviceQueueType  queue = RHIDeviceQueueType::Graphics 
)

Creates a pass that performs per-frame updates with correct synchronization.

Note
IMPORTANT: Resources created by this call must be used within the Renderer, or no updates will have any effect (i.e. the updates will never be executed), and the next-frame guarantee will not hold!

◆ FreeConst()

void GPUScene::FreeConst ( VirtualAllocation  allocation)

Frees a previously allocated const.

Parameters
allocationPreviously allocated const handle

◆ FreeShared()

void GPUScene::FreeShared ( VirtualAllocation  allocation)

Frees a previously allocated Shared allocation.

Parameters
allocationPreviously allocated Shared allocation

◆ MapInstanceData()

template<typename T >
Span< T > Foundation::Rendering::GPUScene::MapInstanceData ( )
inline

Maps the instance data for writing. The returned span is valid until UnmapInstanceData is called.

The entirety of the buffer will be updated to the GPU.

Note
The data update is not immediate, and will be automatically scheduled and performed at the beginning of the next frame (call to Renderer::ExecuteFrame)
This has the side effect of blocking GPU buffer updates, i.e. the CreateUpdatePasses passes, and can thus be used to batch updates and synchronize with the Renderer.
This locks the internal mutex, and thus is not reentrant.

◆ PushConst()

VirtualAllocation GPUScene::PushConst ( Span< const char data,
size_t  alignment 
)

Push a block of data into the Const buffer.

The data can be anything from plain old vertex-index buffers, meshlet data and/or any data that's expected to be updated at a different (not necessarily lower) granularity.

Note
The data update is not immediate, and will be automatically scheduled and performed at the beginning of the next frame (call to Renderer::ExecuteFrame)
However, it's valid to QueryConst the allocation right after this call.
To batch updates, you can acquire MapInstanceData before pushing, and use UnmapInstanceData afterward to flush all updates at once.
Parameters
dataData to push
alignmentAlignment requirement for the data. Must be a multiple of 4.
Returns
Allocation handle. Use QueryConst to get offset/size, and FreeConst to free it.

◆ PushShared()

VirtualAllocation GPUScene::PushShared ( Span< const char data,
size_t  alignment 
)

Push a block of data into the Shared buffer.

The data can be anything from something like an array of matrices, to a custom structure that contains material information, AABB and/or offsets from QueryConst etc. that's expected to be updated at a different (not necessarily lower) granularity.

Note
The data update is not immediate, and will be automatically scheduled and performed at the beginning of the next frame (call to Renderer::ExecuteFrame)
However, it's valid to QueryShared the allocation right after this call.
To batch updates, you can acquire MapInstanceData before pushing, and use UnmapInstanceData afterward to flush all updates at once.
Parameters
dataData to push
alignmentAlignment requirement for the data. Must be a multiple of 4.
Returns
Allocation handle. Use QueryShared to get offset/size, and FreeShared to free it.

◆ QueryConst()

Pair< size_t, size_t > GPUScene::QueryConst ( VirtualAllocation  id)

Query a previous const allocation.

Parameters
idPreviously allocated const handle
Returns
[Raw offset in bytes, Size in bytes]

◆ QueryShared()

Pair< size_t, size_t > GPUScene::QueryShared ( VirtualAllocation  allocation)

Queries the Shared allocation for a given allocation.

Parameters
allocationPreviously allocated Shared allocation
Returns
[Raw offset in bytes, Size in bytes]

◆ UnmapInstanceData()

void Foundation::Rendering::GPUScene::UnmapInstanceData ( )
inline

Unmaps the instance data, allowing other threads to map it again.

Note
The update is guaranteed to be completed by the next frame (call to Renderer::ExecuteFrame)

◆ UpdateConst()

void GPUScene::UpdateConst ( VirtualAllocation  allocation,
Span< const char data 
)

Updates a previously allocated Const allocation.

Note
The data update is not immediate, and will be automatically scheduled and performed at the beginning of the next frame (call to Renderer::ExecuteFrame)
To batch updates, you can acquire MapInstanceData before pushing, and use UnmapInstanceData afterward to flush all updates at once.
Parameters
allocationPreviously allocated const allocation
dataNew data to write. Must be the same size as the original allocation.

◆ UpdateShared()

void GPUScene::UpdateShared ( VirtualAllocation  allocation,
Span< const char data 
)

Updates a previously allocated Shared allocation.

Note
The update is guaranteed to be completed by the next frame (call to Renderer::ExecuteFrame)
To batch updates, you can acquire MapInstanceData before pushing, and use UnmapInstanceData afterward to flush all updates at once.
Parameters
allocationPreviously allocated shared allocation
dataNew data to write. Must be the same size as the original allocation.

Member Data Documentation

◆ mAllocator

Allocator* Foundation::Rendering::GPUScene::mAllocator
private

◆ mConst

StagedDoubleBuffer Foundation::Rendering::GPUScene::mConst
private

◆ mConstAlloc

VirtualAllocator Foundation::Rendering::GPUScene::mConstAlloc
private

◆ mConstUpdateRegions

Vector<Pair<size_t, size_t> > Foundation::Rendering::GPUScene::mConstUpdateRegions
private

◆ mInstance

StagedDoubleBuffer Foundation::Rendering::GPUScene::mInstance
private

◆ mInstanceDirty

bool Foundation::Rendering::GPUScene::mInstanceDirty {false}
private

◆ mInstanceMutex

Async::Mutex Foundation::Rendering::GPUScene::mInstanceMutex
private

◆ mShared

StagedDoubleBuffer Foundation::Rendering::GPUScene::mShared
private

◆ mSharedAlloc

VirtualAllocator Foundation::Rendering::GPUScene::mSharedAlloc
private

◆ mSharedUpdateRegions

Vector<Pair<size_t, size_t> > Foundation::Rendering::GPUScene::mSharedUpdateRegions
private

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