Create a layout¶
In order to access resources (buffers, images, samplers, etc.) inside a shader/pipeline, the user must create layouts and manipulate them through the hk_layout_t handle and its associated functions in haiku/graphics.h. This object is equivalent to Vulkan descriptor set layouts.
Layouts list the type of resources, their number, the binding point and the shader stage access that can be used later by pipelines:
hk_layout_t my_layout = hkgfx_layout_create(device, &(hk_gfx_layout_desc){
.buffers_count = 2,
.buffers = {
{.slot = 0, .type = HK_BUFFER_BINDING_TYPE_UNIFORM_BUFFER, .stages = HK_SHADER_STAGE_COMPUTE},
{.slot = 1, .type = HK_BUFFER_BINDING_TYPE_STORAGE_BUFFER, .stages = HK_SHADER_STAGE_COMPUTE},
},
.images_count = 2,
.images = {
{.slot = 2, .type = HK_IMAGE_BINDING_TYPE_STORAGE_IMAGE , .stages = HK_SHADER_STAGE_COMPUTE},
{.slot = 3, .type = HK_IMAGE_BINDING_TYPE_COMBINED_IMAGE_SAMPLER, .stages = HK_SHADER_STAGE_COMPUTE},
}
});
In this snippet the user defines a layout that features two buffers (one uniform and one storage) and two images (one storage and a (image,sampler) pair) that can only be accessed from a compute shader.
Layouts are then used when creating a pipeline or a bindgroup.
Create a bindgroup¶
Bindgroups are bringing together resources according to a given layout. This object is equivalent to Vulkan descriptor sets and is provided using the handle hk_bindgroup_t.
We strongly suggest that you define the bindgroups only once you have created all the layouts for your application.
hk_bindgroup_t my_bindgroup = hkgfx_bindgroup_create(device, &(hk_gfx_bindgroup_desc){
.layout = my_layout,
.buffers = {
my_uniform_buffer,
my_storage_buffer,
},
.images = {
{.image_view = my_image_view},
{.image_view = my_texture_view, .sampler = my_texture_sampler},
}
});
Example of bindgroup matching the previous layout example.
These objects are then bound to pipelines during rendering or compute dispatch:
hkgfx_context_set_pipeline(my_command_buffer, my_compute_pipeline);
hkgfx_context_set_bindings(my_command_buffer, my_compute_pipeline, 0, my_bindgroup);
hkgfx_context_dispatch(my_command_buffer, ...);
With example of resources accessed by a GLSL compute shader:
layout(std140, binding = 0) restrict uniform uniformBuffer {
uniform_t parameters;
} ubo;
layout(std430, binding = 1) restrict buffer storageBuffer {
data_t array[];
} ssbo;
layout(binding = 2, rgba8) uniform image2D storage_image;
layout(binding = 3) uniform sampler2D sampled_image;