The Vish Visualization Shell 0.3
Vish
Public Member Functions | List of all members
Wizt::VertexBuffer Struct Reference

Explanation of buffer residency and upload strategy on drivers where persistent/coherent mappings are backed by host-visible system memory. More...

#include <ocean/GLvish/VertexArrayObject.hpp>

Inheritance diagram for Wizt::VertexBuffer:
Wizt::RenderBasin::VertexAttribute Wizt::GLBuffer Wizt::Anemone::SpecializedTentacle< Anemone::Arraybuffer > Wizt::RenderBasin::Buffer Wizt::Anemone::Tentacle MemCore::ReferenceBase< Tentacle >

Public Member Functions

bool activate (const Anemone &) override
 Activate this tentacle.
 
bool deactivate (const Anemone &) override
 Deactivate this tentacle.
 
size_t memsize () const override
 Return the memory occupied by this buffer if it occupies memory at all. Otherwise, returns 0 (default).
 
size_t NumberOfElements () const override
 Returns the number of elements provided and used by this object, if it refers to countable elements.
 
bool updateValue (VRenderContext &Context) override
 Possibly update a tentacle from settings in a context.
 
- Public Member Functions inherited from Wizt::Anemone::Tentacle
virtual const char * getSamplerType () const
 If this tentacle refers to some texture sampler in a shader, then hereby return the type of this sampler is it occurs in the code.
 
virtual int getTextureUnit () const
 Get the texture unit number which was specified during construction, if positive then it refers to some texture unit that is used in an associated shader.
 
- Public Member Functions inherited from MemCore::ReferenceBase< Tentacle >
auto getObjectCountID () const noexcept
 Get a unique ID for this object in the given domain.
 
bool isIdentical (const WeakPtr< Tentacle, Tentacle > &PossibleSelf) const noexcept
 Check if this object is identical to the one used by the given pointer.
 
void mkAutoDestructive ()
 Marks this object as being automatically destructed, e.g.
 
refcount_t refcount () const noexcept
 The strong reference count.
 
 ReferenceBase (Tentacle *that) noexcept
 Constructor, initializes reference counter to zero.
 
const auto & self () const
 Return weak pointer to the object self.
 
refcount_t wrefcount () const noexcept
 The weak reference count.
 
- Public Member Functions inherited from Wizt::GLBuffer
void * map_wo (size_t offset=0, size_t length=0) const override
 Recommended creation and usage pattern for a short-lived CPU staging buffer.
 

Additional Inherited Members

- Public Types inherited from MemCore::ReferenceBase< Tentacle >
using reference_domain_t = Tentacle
 The type of the base class.
 
using SelfPtr_t = WeakPtr< Tentacle, Tentacle >
 Type for a pointer to this object itself.
 
- Public Attributes inherited from Wizt::RenderBasin::VertexAttribute
unsigned DoublePrecision:1
 Load data in double precision.
 
unsigned Integer:1
 Hint whether the attribute is an integer data type in the shader, in which case it will be loaded differently.
 
unsigned Normalized:1
 Indicate whether this buffer will be normalized to the range [0,1] if it is an integer type loaded to a floating point attribute.
 
unsigned Signed:1
 Indicate if this integer type is signed.
 
- Public Attributes inherited from Wizt::Anemone::Tentacle
Activity_t Activity
 A bit mask telling whether this tentacle should participate in the waving of an Anemone.
 
- Protected Member Functions inherited from MemCore::ReferenceBase< Tentacle >
virtual void extremeUnction ()
 A virtual function that will be called just before the object is destroyed.
 
ReferenceBaseoperator= (const ReferenceBase &R)
 Protected assignment operator (should not be called).
 
void suicide ()
 Delete this.
 
virtual ~ReferenceBase ()
 Virtual destructor.
 

Detailed Description

Explanation of buffer residency and upload strategy on drivers where persistent/coherent mappings are backed by host-visible system memory.

This document describes the observed behavior of buffer allocations created with glNamedBufferStorage() using the flags GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT, and the resulting requirement to use a staging buffer followed by an explicit GPU-side copy operation to obtain device-local (VRAM) storage.

Persistent Mapped Buffers

Buffers created with:

glNamedBufferStorage(id, size, nullptr,
GL_MAP_WRITE_BIT |
GL_MAP_PERSISTENT_BIT |
GL_MAP_COHERENT_BIT);

and subsequently mapped via:

glMapNamedBufferRange(id, offset, size,
GL_MAP_WRITE_BIT |
GL_MAP_PERSISTENT_BIT |
GL_MAP_COHERENT_BIT);

are allocated in host-visible memory on the tested driver. This memory region is CPU-accessible and suitable for direct writes, but it is not device-local VRAM. GPU access to this memory is significantly slower than access to device-local storage.

This behavior is compliant with the OpenGL specification. The specification does not mandate that persistent/coherent mappings must refer to device-local memory; the driver may place such buffers in any memory region that satisfies the required mapping properties.

Device-Local Buffers

Buffers created without any mapping-related flags:

glNamedBufferStorage(id, size, nullptr, 0);

are allocated in device-local VRAM on the tested driver. These buffers are not mappable by the CPU and provide optimal access performance for GPU read operations (e.g., vertex fetch).

Required Upload Path

Because persistent mapped buffers reside in host-visible memory and not in device-local VRAM, rendering directly from such buffers results in reduced GPU performance. To obtain device-local storage, a two-step upload process is required:

  1. Allocate a host-visible staging buffer using persistent/coherent mapping flags and write data into it via the mapped pointer.
  2. Allocate a device-local buffer without mapping flags.
  3. Transfer the data from the staging buffer to the device-local buffer using:
    glCopyNamedBufferSubData(stagingBuffer, deviceLocalBuffer, srcOffset,
    dstOffset, size);

The resulting device-local buffer can then be used for rendering with optimal performance.

Synchronization

The completion of the GPU-side copy operation must be synchronized before the device-local buffer is used for rendering. This is typically achieved using glFenceSync() and glClientWaitSync() or equivalent synchronization mechanisms. However, fences are not resource-aware and cannot be used to check the status of a VertexArrayObject .

Summary

Member Function Documentation

◆ NumberOfElements()

size_t Wizt::VertexBuffer::NumberOfElements ( ) const
overridevirtual

Returns the number of elements provided and used by this object, if it refers to countable elements.

Otherwise, returns 0 (default).

Reimplemented from Wizt::Anemone::Tentacle.

◆ updateValue()

bool Wizt::VertexBuffer::updateValue ( VRenderContext Context)
overridevirtual

Possibly update a tentacle from settings in a context.

Returns
true if it was successful, false if it could not be done and the tentacle might need to be re-created.

Reimplemented from Wizt::Anemone::Tentacle.