Create a buffer¶
Buffers are the main way to send data to the GPU. haiku provides the hk_buffer_t handle and associated utility functions in haiku/graphics.h allowing to store and transfer data between CPU and GPU.
Buffer creation is achieved using the hkgfx_buffer_create function which requires a hk_device_t and hk_gfx_buffer_desc data structure.
Example:
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
});
In this example, we are asking for a buffer that lives on the CPU side and will later be used as a source of a transfer operation. The size in bytes is also given and its initial data (dataptr field is only used when either flag HK_MEMORY_TYPE_CPU_ONLY or HK_MEMORY_TYPE_CPU_TO_GPU are set).
This function has its corresponding deallocation function hkgfx_buffer_destroy.
Usage flags are given by the hk_buffer_usage_flag_bits_e enumeration:
HK_BUFFER_USAGE_NONE: Invalid flag for completness/default.HK_BUFFER_USAGE_TRANSFER_SRC_BIT: hints that the buffer will be later used as a tranfer source.HK_BUFFER_USAGE_TRANSFER_DST_BIT: hints that the buffer will be later used as a tranfer destination.HK_BUFFER_USAGE_UNIFORM_BUFFER_BIT: hints that the buffer will be later used as a uniform buffer (UBO).HK_BUFFER_USAGE_STORAGE_BUFFER_BIT: hints that the buffer will be later used as a storage buffer (SSBO).HK_BUFFER_USAGE_INDEX_BUFFER_BIT: hints that the buffer will be later used as an index buffer.HK_BUFFER_USAGE_VERTEX_BUFFER_BIT: hints that the buffer will be later used as a vertex buffer (VBO).HK_BUFFER_USAGE_INDIRECT_BUFFER_BIT: hints that the buffer will be later used as an indirect command buffer.
An important point to consider is the type of memory that will 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 choices are decided by hk_memory_type_e enumeration:
HK_MEMORY_TYPE_CPU_ONLY: Host-only memory type. (e.g. CPU mapped staging buffers)HK_MEMORY_TYPE_GPU_ONLY: Device-only memory type. (e.g. GPU-only buffers. )HK_MEMORY_TYPE_CPU_TO_GPU: Host-to-GPU memory type. (e.g. CPU/GPU mapped staging buffers.)HK_MEMORY_TYPE_GPU_TO_CPU: Device-to-GPU buffers. (e.g. mapped GPU buffers)
Mapping¶
If buffers are created with HK_MEMORY_TYPE_CPU_ONLY, HK_MEMORY_TYPE_CPU_TO_GPU or HK_MEMORY_TYPE_GPU_TO_CPU flags, they are persistently mapped and can be accessed using hkgfx_buffer_map:
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);
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 functions.
Resizing¶
haiku allows you to resize/reset the content of a previously created hk_buffer_t using hkgfx_buffer_reset :
hkgfx_buffer_reset(device, my_buffer, &(hk_gfx_buffer_desc){
.usage_flags = HK_BUFFER_USAGE_TRANSFER_DST_BIT,
.memory_type = HK_MEMORY_TYPE_CPU_ONLY,
.bytesize = new_bytesize
});