ngscopeclient 0.1-dev+51fbda87c
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
AcceleratorBuffer< T > Class Template Reference

A buffer of memory which may be used by GPU acceleration. More...

#include <AcceleratorBuffer.h>

Collaboration diagram for AcceleratorBuffer< T >:
Collaboration graph
[legend]

Public Types

enum  MemoryAttributes {
  MEM_ATTRIB_CPU_SIDE = 0x1 , MEM_ATTRIB_GPU_SIDE = 0x2 , MEM_ATTRIB_CPU_REACHABLE = 0x4 , MEM_ATTRIB_GPU_REACHABLE = 0x8 ,
  MEM_ATTRIB_CPU_FAST = 0x10 , MEM_ATTRIB_GPU_FAST = 0x20
}
 Attributes that a memory buffer can have.
 
enum  MemoryType {
  MEM_TYPE_NULL = 0 , MEM_TYPE_CPU_PAGED , MEM_TYPE_CPU_ONLY , MEM_TYPE_CPU_DMA_CAPABLE ,
  MEM_TYPE_GPU_ONLY , MEM_TYPE_GPU_DMA_CAPABLE
}
 Types of memory buffer.
 
enum  UsageHint { HINT_NEVER , HINT_UNLIKELY , HINT_LIKELY }
 

Public Member Functions

 AcceleratorBuffer (const std::string &name="")
 Creates a new AcceleratorBuffer with no content.
 
size_t size () const
 Returns the actual size of the container (may be smaller than what was allocated)
 
size_t capacity () const
 Returns the allocated size of the container.
 
size_t GetCpuMemoryBytes () const
 Returns the total reserved CPU memory, in bytes.
 
size_t GetGpuMemoryBytes () const
 Returns the total reserved GPU memory, in bytes.
 
bool empty () const
 Returns true if the container is empty.
 
bool IsCpuBufferStale () const
 Returns true if the CPU-side buffer is stale.
 
bool IsGpuBufferStale () const
 Returns true if the GPU-side buffer is stale.
 
bool HasCpuBuffer () const
 Returns true if there is currently a CPU-side buffer.
 
bool HasGpuBuffer () const
 Returns true if there is currently a GPU-side buffer.
 
bool IsSingleSharedBuffer () const
 Returns true if the object contains only a single buffer.
 
vk::Buffer GetBuffer ()
 Returns the preferred buffer for GPU-side access. More...
 
T * GetCpuPointer ()
 Gets a pointer to the CPU-side buffer.
 
vk::DescriptorBufferInfo GetBufferInfo ()
 Returns a vk::DescriptorBufferInfo suitable for binding this object to.
 
void resize (size_t size)
 Change the usable size of the container.
 
void clear ()
 Resize the container to be empty (but don't free memory)
 
void reserve (size_t size)
 Reallocates buffers so that at least size elements of storage are available.
 
void shrink_to_fit ()
 Frees unused memory so that m_size == m_capacity.
 
 __attribute__ ((noinline)) void CopyFrom(const AcceleratorBuffer< T > &rhs)
 Copies our content from another AcceleratorBuffer.
 
const T & operator[] (size_t i) const
 
T & operator[] (size_t i)
 
void push_back (const T &value)
 Adds a new element to the end of the container, allocating space if needed.
 
void pop_back ()
 Removes the last item in the container.
 
void push_front (const T &value)
 Inserts a new item at the beginning of the container. This is inefficient due to copying. More...
 
void pop_front ()
 Removes the first item in the container. More...
 
AcceleratorBufferIterator< T > begin ()
 
AcceleratorBufferIterator< T > end ()
 
void SetCpuAccessHint (UsageHint hint, bool reallocateImmediately=false)
 Sets a hint to the buffer on how often we expect to use it on the CPU in the future. More...
 
void SetGpuAccessHint (UsageHint hint, bool reallocateImmediately=false)
 Sets a hint to the buffer on how often we expect to use it on the GPU in the future. More...
 
void MarkModifiedFromCpu ()
 Marks the CPU-side copy of the buffer as modified. More...
 
void MarkModifiedFromGpu ()
 Marks the GPU-side copy of the buffer as modified. More...
 
void PrepareForCpuAccess ()
 Prepares the buffer to be accessed from the CPU. More...
 
void PrepareForGpuAccess (bool outputOnly=false)
 Prepares the buffer to be accessed from the GPU. More...
 
void PrepareForGpuAccessNonblocking (bool outputOnly, vk::raii::CommandBuffer &cmdBuf)
 Prepares the buffer to be accessed from the GPU. More...
 
void FreeGpuBuffer (bool dataLossOK=false)
 Free the GPU-side buffer and underlying physical memory. More...
 
void SetName (std::string name)
 Sets the debug name for this buffer. More...
 

Static Public Member Functions

static void HostToDeviceTransferMemoryBarrier (vk::raii::CommandBuffer &cmdBuf)
 Adds a memory barrier for transferring data from host to device.
 

Protected Member Functions

bool IsReachableFromCpu (MemoryType mt)
 Returns true if the given buffer type can be reached from the CPU.
 
bool IsReachableFromGpu (MemoryType mt)
 Returns true if the given buffer type can be reached from the GPU.
 
bool IsFastFromCpu (MemoryType mt)
 Returns true if the given buffer type is fast to access from the CPU.
 
bool IsFastFromGpu (MemoryType mt)
 Returns true if the given buffer type is fast to access from the GPU.
 
 __attribute__ ((noinline)) void Reallocate(size_t size)
 Reallocates the buffer so that it contains exactly size elements.
 
void CopyToCpu ()
 Copy the buffer contents from GPU to CPU and blocks until the transfer completes.
 
void CopyToGpu ()
 Copy the buffer contents from CPU to GPU and blocks until the transfer completes.
 
void CopyToGpuNonblocking (vk::raii::CommandBuffer &cmdBuf)
 Copy the buffer contents from CPU to GPU without blocking on the CPU. More...
 
void FreeCpuBuffer ()
 Free the CPU-side buffer and underlying physical memory.
 
 __attribute__ ((noinline)) void AllocateCpuBuffer(size_t size)
 Allocates a buffer for CPU access.
 
 __attribute__ ((noinline)) void FreeCpuPointer(T *ptr
 Frees a CPU-side buffer. More...
 
 __attribute__ ((noinline)) void UpdateGpuNames()
 Pushes our friendly name to the underlying Vulkan objects.
 
 __attribute__ ((noinline)) void UpdateCpuNames()
 Pushes our friendly name to the underlying Vulkan objects.
 

Protected Attributes

AlignedAllocator< T, 32 > m_cpuAllocator
 
MemoryType m_cpuMemoryType
 Type of the CPU-side buffer.
 
MemoryType m_gpuMemoryType
 Type of the GPU-side buffer.
 
T * m_cpuPtr
 CPU-side mapped pointer.
 
std::unique_ptr< vk::raii::DeviceMemory > m_cpuPhysMem
 CPU-side physical memory.
 
std::unique_ptr< vk::raii::DeviceMemory > m_gpuPhysMem
 GPU-side physical memory.
 
std::unique_ptr< vk::raii::Buffer > m_cpuBuffer
 Buffer object for CPU-side memory.
 
std::unique_ptr< vk::raii::Buffer > m_gpuBuffer
 Buffer object for GPU-side memory.
 
bool m_buffersAreSame
 True if we have only one piece of physical memory accessible from both sides.
 
bool m_cpuPhysMemIsStale
 True if m_cpuPtr contains stale data (m_gpuPhysMem has been modified and they point to different memory)
 
bool m_gpuPhysMemIsStale
 True if m_gpuPhysMem contains stale data (m_cpuPtr has been modified and they point to different memory)
 
int m_tempFileHandle
 File handle used for MEM_TYPE_CPU_PAGED.
 
size_t m_capacity
 Size of the allocated memory space (may be larger than m_size)
 
size_t m_size
 Size of the memory actually being used.
 
UsageHint m_cpuAccessHint
 Hint about how likely future CPU access is.
 
UsageHint m_gpuAccessHint
 Hint about how likely future GPU access is.
 
MemoryType type
 
MemoryType size_t size
 

Detailed Description

template<class T>
class AcceleratorBuffer< T >

A buffer of memory which may be used by GPU acceleration.

At any given point in time the buffer may exist as a single copy on the CPU, a single copy on the GPU, or mirrored buffers on both sides.

Hints can be provided to the buffer about future usage patterns to optimize storage location for best performance.

This buffer generally provides std::vector semantics, but does not initialize memory or call constructors on elements when calling resize() or reserve() unless the element type is not trivially copyable. All locations not explicitly written to have undefined values. Most notably, allocated buffer space between size() and capacity() is undefined and its value may not be coherent between CPU and GPU view of the buffer.

If the element type is not trivially copyable, the data cannot be shared with the GPU. This class still supports non-trivially-copyable types as a convenience for working with waveforms on the CPU.

Member Function Documentation

◆ __attribute__()

template<class T >
AcceleratorBuffer< T >::__attribute__ ( (noinline)  )
protected

Frees a CPU-side buffer.

An explicit type is passed here because if we're reallocating we might change memory type. By this point AllocateCpuBuffer() has been called so m_cpuMemoryType points to the type of the new buffer, not the one we're getting rid of.

◆ CopyToGpuNonblocking()

template<class T >
void AcceleratorBuffer< T >::CopyToGpuNonblocking ( vk::raii::CommandBuffer &  cmdBuf)
inlineprotected

Copy the buffer contents from CPU to GPU without blocking on the CPU.

Inserts a memory barrier to ensure that GPU-side access is synchronized.

◆ FreeGpuBuffer()

template<class T >
void AcceleratorBuffer< T >::FreeGpuBuffer ( bool  dataLossOK = false)
inline

Free the GPU-side buffer and underlying physical memory.

Parameters
dataLossOKTrue if we do not intend to use the contents of this buffer again (and thus it's OK to remove the only copy of the data)

◆ GetBuffer()

template<class T >
vk::Buffer AcceleratorBuffer< T >::GetBuffer ( )
inline

Returns the preferred buffer for GPU-side access.

This is the GPU buffer if we have one, otherwise the CPU buffer.

◆ MarkModifiedFromCpu()

template<class T >
void AcceleratorBuffer< T >::MarkModifiedFromCpu ( )
inline

Marks the CPU-side copy of the buffer as modified.

If the CPU and GPU pointers point to different memory, this makes the GPU-side copy stale.

◆ MarkModifiedFromGpu()

template<class T >
void AcceleratorBuffer< T >::MarkModifiedFromGpu ( )
inline

Marks the GPU-side copy of the buffer as modified.

If the CPU and GPU pointers point to different memory, this makes the CPU-side copy stale.

◆ pop_front()

template<class T >
void AcceleratorBuffer< T >::pop_front ( )
inline

Removes the first item in the container.

TODO: GPU implementation of this?

◆ PrepareForCpuAccess()

template<class T >
void AcceleratorBuffer< T >::PrepareForCpuAccess ( )
inline

Prepares the buffer to be accessed from the CPU.

This MUST be called prior to accessing the CPU-side buffer to ensure that m_cpuPtr is valid and up to date.

◆ PrepareForGpuAccess()

template<class T >
void AcceleratorBuffer< T >::PrepareForGpuAccess ( bool  outputOnly = false)
inline

Prepares the buffer to be accessed from the GPU.

This MUST be called prior to accessing the GPU-side buffer to ensure that m_gpuPhysMem is valid and up to date.

Parameters
outputOnlyTrue if the buffer is output-only for the shader, so there's no need to copy anything to the GPU even if data is stale.

◆ PrepareForGpuAccessNonblocking()

template<class T >
void AcceleratorBuffer< T >::PrepareForGpuAccessNonblocking ( bool  outputOnly,
vk::raii::CommandBuffer &  cmdBuf 
)
inline

Prepares the buffer to be accessed from the GPU.

This MUST be called prior to accessing the GPU-side buffer to ensure that m_gpuPhysMem is valid and up to date.

Parameters
outputOnlyTrue if the buffer is output-only for the shader, so there's no need to copy anything to the GPU even if data is stale.

◆ push_front()

template<class T >
void AcceleratorBuffer< T >::push_front ( const T &  value)
inline

Inserts a new item at the beginning of the container. This is inefficient due to copying.

TODO: GPU implementation of this?

◆ SetCpuAccessHint()

template<class T >
void AcceleratorBuffer< T >::SetCpuAccessHint ( UsageHint  hint,
bool  reallocateImmediately = false 
)
inline

Sets a hint to the buffer on how often we expect to use it on the CPU in the future.

If reallocateImmediately is set, the buffer is reallocated with the specified settings to fit the current buffer size (shrinking to fit if needed)

◆ SetGpuAccessHint()

template<class T >
void AcceleratorBuffer< T >::SetGpuAccessHint ( UsageHint  hint,
bool  reallocateImmediately = false 
)
inline

Sets a hint to the buffer on how often we expect to use it on the GPU in the future.

If reallocateImmediately is set, the buffer is reallocated with the specified settings to fit the current buffer size (shrinking to fit if needed)

◆ SetName()

template<class T >
void AcceleratorBuffer< T >::SetName ( std::string  name)
inline

Sets the debug name for this buffer.

The name can be queried by m_name in a debugger. If VK_EXT_debug_utils is active, the name will also be attached to the Vulkan object handle.

Parameters
nameName of the buffer

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