Buffers¶
haiku provides a buffer handle hk_buffer_t
and associated utility functions in haiku/graphics.h
allowing to store and transfer data between CPU and GPU :
Warning
doxygenstruct: Cannot find class “hk_buffer_t” in doxygen xml output for project “haiku” from directory: /builds/haiku/haiku/build/docs//xml
Before creation, user must define how it will be used. To do so, we exposed enum flag bits using hk_buffer_usage_flag_bits_e
:
-
enum hk_buffer_usage_flag_bits_e¶
Values:
-
enumerator HK_BUFFER_USAGE_NONE¶
Invalid flag for completness/default.
-
enumerator HK_BUFFER_USAGE_TRANSFER_SRC_BIT¶
Hint that buffer will be later used as a tranfer source.
-
enumerator HK_BUFFER_USAGE_TRANSFER_DST_BIT¶
Hint that buffer will be later used as a tranfer destination.
-
enumerator HK_BUFFER_USAGE_UNIFORM_BUFFER_BIT¶
Hint that buffer will be later used as a uniform buffer (UBO).
-
enumerator HK_BUFFER_USAGE_STORAGE_BUFFER_BIT¶
Hint that buffer will be later used as a storage buffer (SSBO).
-
enumerator HK_BUFFER_USAGE_INDEX_BUFFER_BIT¶
Hint that buffer will be later used as an index buffer.
-
enumerator HK_BUFFER_USAGE_VERTEX_BUFFER_BIT¶
Hint that buffer will be later used as a vertex buffer (VBO).
-
enumerator HK_BUFFER_USAGE_INDIRECT_BUFFER_BIT¶
Hint that buffer will be later used as an indirect buffer.
-
enumerator HK_BUFFER_USAGE_NONE¶
the next point to consider is the type of memory to be used by the buffer. Buffers can be used to transfer data from the CPU to the GPU and vice versa, or to store data only on the GPU. These these choices are decided by hk_memory_type_e
enumeration:
-
enum hk_memory_type_e¶
GPU memory type enum. Hint the memory lifecycle of objects (buffers/images).
Values:
-
enumerator HK_MEMORY_TYPE_NONE¶
Invalid flag for completness/default.
-
enumerator HK_MEMORY_TYPE_CPU_ONLY¶
Host-only memory type. Example: CPU mapped staging buffers.
-
enumerator HK_MEMORY_TYPE_GPU_ONLY¶
Device-only memory type. Example: GPU-only buffers.
-
enumerator HK_MEMORY_TYPE_CPU_TO_GPU¶
Host-to-GPU memory type. Example: CPU/GPU mapped staging buffers.
-
enumerator HK_MEMORY_TYPE_GPU_TO_CPU¶
Device-to-GPU buffers. Example: mapped GPU buffers
-
enumerator HK_MEMORY_TYPE_COUNT¶
Do not use. Internal usage only.
-
enumerator HK_MEMORY_TYPE_NONE¶
Once these two uses have been defined, we can build a buffer by calling the hkgfx_buffer_create
function, which takes a hk_gfx_buffer_desc
description structure as parameter :
-
struct hk_gfx_buffer_desc¶
Graphics buffer configuration data structure.
Public Members
-
char label[HK_MAX_LABEL_SIZE]¶
Optional label/name. Useful when debugging.
-
size_t bytesize¶
The byte size of the buffer object.
-
void *dataptr¶
Raw pointer to data with byte size. Required specific memory type:
HK_MEMORY_TYPE_CPU_ONLY
HK_MEMORY_TYPE_CPU_TO_GPU
-
uint32_t usage_flags¶
Combination of
hk_buffer_usage_flag_bits_e
flag bits to hint the usage of the buffer. Usual examples:Staging buffer:
HK_BUFFER_USAGE_TRANSFER_SRC_BIT
Uniform buffer:
HK_BUFFER_USAGE_TRANSFER_DST_BIT | HK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
Vertex buffer :
HK_BUFFER_USAGE_VERTEX_BUFFER_BIT
-
hk_memory_type_e memory_type¶
Suggets the lifecycle of the buffer object.
HK_MEMORY_TYPE_CPU_ONLY
Host-only memory typeHK_MEMORY_TYPE_GPU_ONLY
Device-only memory typeHK_MEMORY_TYPE_CPU_TO_GPU
Host-to-Device memory typeHK_MEMORY_TYPE_GPU_TO_CPU
Device-to-Host memory type
-
char label[HK_MAX_LABEL_SIZE]¶
Here’s an example of how it’s typically used:
// Creating a staging buffer (moving data from CPU to GPU)
// with HK_MEMORY_TYPE_CPU_ONLY and HK_MEMORY_TYPE_CPU_TO_GPU you can use the dataptr member
hk_buffer_t buffer_staging = hkgfx_buffer_create(device, &(hk_gfx_buffer_desc){
.usage_flags = HK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.memory_type = HK_MEMORY_TYPE_CPU_ONLY,
.bytesize = array_size * sizeof(/* ... */),
.dataptr = array
});
// Creating an uniform buffer (receiving data from CPU)
// with HK_MEMORY_TYPE_GPU_ONLY and HK_MEMORY_TYPE_GPU_TO_CPU dataptr is not used
// you'll need to perform a transfer operation.
hk_buffer_t buffer_ubo = hkgfx_buffer_create(device, &(hk_gfx_buffer_desc){
.usage_flags = HK_BUFFER_USAGE_TRANSFER_DST_BIT | HK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
.memory_type = HK_MEMORY_TYPE_GPU_ONLY,
.bytesize = ubo_size * sizeof(/* ... */)
});
Here’s the full API reference for the hkgfx_buffer_create
and the respective hkgfx_buffer_destroy
functions:
-
hk_buffer_t hkgfx_buffer_create(hk_device_t *device, const hk_gfx_buffer_desc *desc)¶
Creates a gpu buffer object.
-
void hkgfx_buffer_destroy(hk_device_t *device, hk_buffer_t buffer)¶
Destroys a gpu buffer object.
Usually GPU buffers allows to map memory in order to easily access data through a pointer. We provide hkgfx_buffer_memory_map
and hkgfx_buffer_memory_unmap
:
-
void hkgfx_buffer_memory_map(hk_device_t *device, hk_buffer_t buf, void **mapped_pointer)¶
Maps a gpu buffer object to host.
-
void hkgfx_buffer_memory_unmap(hk_device_t *device, hk_buffer_t buf)¶
Unmaps a gpu buffer object to host.
A simpler variant is available for persitently mapped buffer (with memory type HK_MEMORY_TYPE_CPU_ONLY
, HK_MEMORY_TYPE_CPU_TO_GPU
or HK_MEMORY_TYPE_GPU_TO_CPU
):
hk_buffer_t buffer_result = hkgfx_buffer_create(device, &(hk_gfx_buffer_desc){
.usage_flags = HK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
.memory_type = HK_MEMORY_TYPE_GPU_TO_CPU,
.bytesize = buffer_bytesize
});
/* [...] */
void* bufdata = hkgfx_buffer_map(buffer_result);
Here’s the API reference for the hkgfx_buffer_map
function:
-
void *hkgfx_buffer_map(hk_buffer_t buffer)¶
Retrieves a pointer to a persistant gpu buffer object to host.
Another needed feature, is the ability to reset the buffer content (e.g. atomic counters, etc.):
-
void hkgfx_buffer_reset(hk_device_t *device, hk_buffer_t buf, const hk_gfx_buffer_desc *desc)¶
Resets a previously created gpu buffer object.
How to transition between buffer states¶
-
enum hk_buffer_state_e¶
Buffer state enumeration.
Values:
-
enumerator HK_BUFFER_STATE_DEFAULT¶
Default buffer state.
-
enumerator HK_BUFFER_STATE_UNDEFINED¶
Undefined state. Used as an initial state for a buffer.
-
enumerator HK_BUFFER_STATE_INDEX¶
Index buffer state. The buffer will be used as an index buffer.
-
enumerator HK_BUFFER_STATE_VERTEX¶
Vertex buffer state. The buffer will be used as a vertex buffer.
-
enumerator HK_BUFFER_STATE_UNIFORM¶
Uniform buffer state. The buffer will be used a an uniform buffer.
-
enumerator HK_BUFFER_STATE_INDIRECT¶
Indirect buffer state. The buffer will be used a an indirect command buffer.
-
enumerator HK_BUFFER_STATE_SHADER_ACCESS¶
Unordered access state. The buffer will be read and written by a shader.
-
enumerator HK_BUFFER_STATE_SHADER_READ¶
Read-only access state. The buffer will be read by a shader.
-
enumerator HK_BUFFER_STATE_SHADER_WRITE¶
Write-only access state. The buffer will be modified by a shader.
-
enumerator HK_BUFFER_STATE_TRANSFER_SRC¶
Transfer source state. The buffer will be the source of a transfer command.
-
enumerator HK_BUFFER_STATE_TRANSFER_DST¶
Transfer destination state. The buffer will be the destination of a transfer command.
-
enumerator HK_BUFFER_STATE_COUNT¶
Do not use. Internal usage only.
-
enumerator HK_BUFFER_STATE_DEFAULT¶
-
struct hk_gfx_barrier_buffer_params¶
Buffer barrier description.
Public Members
-
hk_buffer_t buffer¶
Buffer to transition between states
-
hk_buffer_state_e prev_state¶
Previous/Current state flag
-
hk_buffer_state_e next_state¶
Next state flag
-
hk_buffer_t buffer¶
-
void hkgfx_context_buffer_barrier(hk_context_t ctx, const hk_gfx_barrier_buffer_params *params)¶
Apply a buffer memory barrier command.