Skip to content

KDGpu::BindGroup

Module: Public API

Represents a set of shader resource bindings (descriptor set) More...

#include <KDGpu/bind_group.h>

Public Functions

Name
BindGroup()
~BindGroup()
BindGroup(BindGroup && other)
BindGroup & operator=(BindGroup && other)
BindGroup(const BindGroup & ) =delete
BindGroup & operator=(const BindGroup & ) =delete
const Handle< BindGroup_t > & handle() const
bool isValid() const
operator Handle< BindGroup_t >() const
void update(const BindGroupEntry & entry)

Friends

Name
class Device
KDGPU_EXPORT bool operator==(const BindGroup & a, const BindGroup & b)

Detailed Description

1
class KDGpu::BindGroup;

Represents a set of shader resource bindings (descriptor set)

Vulkan equivalent:VkDescriptorSet

BindGroup (also known as descriptor set in Vulkan) groups together shader resources like buffers, textures, and samplers. Shaders declare what resources they need, and bind groups provide the actual resources.

Key features:

  • Group multiple resources for efficient binding
  • Update individual bindings dynamically
  • Allocate from descriptor pools
  • Match shader layout declarations

Lifetime: BindGroups are allocated from a BindGroupPool and must remain valid while referenced by command buffers. They use RAII and clean up automatically.

Note that KDGpu uses a default internal BindGroupPool if you do not specify one, so you can create bind groups without managing pools directly.

Available BindingResource bindings:

Usage

Creating a simple bind group:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    KDGpu::BindGroup bindGroup = device.createBindGroup(KDGpu::BindGroupOptions{
            .layout = layout,
            .resources = {
                    {
                            // Binding 0: uniform buffer
                            .binding = 0,
                            .resource = KDGpu::UniformBufferBinding{
                                    .buffer = uniformBuffer,
                            },
                    },
                    {
                            // Binding 1: texture + sampler
                            .binding = 1,
                            .resource = KDGpu::TextureViewSamplerBinding{
                                    .textureView = textureView,
                                    .sampler = sampler,
                            },
                    },
            },
    });

Filename: kdgpu_doc_snippets.cpp

Using bind groups in rendering:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    KDGpu::CommandRecorder cmdRecorder = device.createCommandRecorder();

    // In render pass
    KDGpu::RenderPassCommandRecorder renderPass = cmdRecorder.beginRenderPass(KDGpu::RenderPassCommandRecorderOptions{
            /* ... */
    });
    renderPass.setBindGroup(0, bindGroup);
    renderPass.end();

    // In compute pass
    KDGpu::ComputePassCommandRecorder computePass = cmdRecorder.beginComputePass();
    computePass.setBindGroup(0, bindGroup);
    computePass.end();

Filename: kdgpu_doc_snippets.cpp

Updating bind groups:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    // Initial bind group
    KDGpu::BindGroup bgUpdatable = device.createBindGroup(KDGpu::BindGroupOptions{
            .layout = layout,
            .resources = {
                    {
                            .binding = 0,
                            .resource = KDGpu::UniformBufferBinding{
                                    .buffer = uniformBuffer,
                            },
                    },
            },
    });

    // New Uniform Buffer
    KDGpu::Buffer newUniformBuffer = device.createBuffer(KDGpu::BufferOptions{
            /* ... */
    });

    // Update BindGroup to reference new buffer
    bgUpdatable.update(KDGpu::BindGroupEntry{
            .binding = 0,
            .resource = KDGpu::UniformBufferBinding{
                    .buffer = newUniformBuffer,
            },
    });

Filename: kdgpu_doc_snippets.cpp

In some cases, you might need to create the BindGroup without binding it to a resource immediately:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
    KDGpu::BindGroup emptyBindGroup = device.createBindGroup(KDGpu::BindGroupOptions{
            .layout = layout,
    });

    // Later when resource is available (and before bindgroup is used in a draw or compute call)
    emptyBindGroup.update(KDGpu::BindGroupEntry{
            .binding = 0,
            .resource = KDGpu::UniformBufferBinding{
                    .buffer = uniformBuffer,
            },
    });

Filename: kdgpu_doc_snippets.cpp

Multiple uniform buffers:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    KDGpu::BindGroup multipleUBOBindGroup = device.createBindGroup(KDGpu::BindGroupOptions{
            .layout = layout,
            .resources = {
                    {
                            .binding = 0,
                            .resource = KDGpu::UniformBufferBinding{
                                    .buffer = uniformBuffer,
                            },
                    },
                    {
                            .binding = 1,
                            .resource = KDGpu::UniformBufferBinding{
                                    .buffer = uniformBuffer,
                                    .offset = 256,
                                    .size = 64,
                            },
                    },
            },
    });

Filename: kdgpu_doc_snippets.cpp

Multiple bind groups (different sets):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    KDGpu::PipelineLayout pipelineLayoutMultiBindGroups = device.createPipelineLayout(KDGpu::PipelineLayoutOptions{
            .bindGroupLayouts = {
                    bindGroupLayout0,
                    bindGroupLayout1,
                    bindGroupLayout2,
            },
    });

    // At render time, bind to set 0, 1, 2
    renderPass.setBindGroup(0, bindGroup0);
    renderPass.setBindGroup(1, bindGroup1);
    renderPass.setBindGroup(2, bindGroup2);

Filename: kdgpu_doc_snippets.cpp

Dynamic offset binding:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    const uint32_t dynamicUBOStride = 16 * sizeof(float);
    // Create bind group with dynamic uniform buffer
    KDGpu::BindGroup dynamicBindGroup = device.createBindGroup(KDGpu::BindGroupOptions{
            .layout = layout,
            .resources = {
                    {
                            .binding = 0,
                            .resource = KDGpu::DynamicUniformBufferBinding{
                                    .buffer = uniformBuffer,
                                    .size = dynamicUBOStride,
                            },
                    },
            },
    });

    // Use with different offsets for different draws
    const std::array<uint32_t, 1> offset0 = { 0 };
    renderPass.setBindGroup(0, dynamicBindGroup, {}, offset0); // Offset 0
    /* Issue some draw calls */

    const std::array<uint32_t, 1> offset1 = { dynamicUBOStride };
    renderPass.setBindGroup(0, dynamicBindGroup, {}, offset1); // Offset 1
    /* Issue some more draw calls */

Filename: kdgpu_doc_snippets.cpp

Storage buffer binding:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
    KDGpu::BindGroup computeBindGroup = device.createBindGroup(KDGpu::BindGroupOptions{
            .layout = layout,
            .resources = {
                    {
                            .binding = 0,
                            .resource = KDGpu::StorageBufferBinding{
                                    .buffer = storageBuffer,
                            },
                    },
            },
    });

Filename: kdgpu_doc_snippets.cpp

Separate TextureView and Sampler binding:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    KDGpu::BindGroup textureAndSamplerBindGroup = device.createBindGroup(KDGpu::BindGroupOptions{
            .layout = layout,
            .resources = {
                    {
                            .binding = 0,
                            .resource = KDGpu::TextureViewBinding{
                                    .textureView = textureView,
                            },
                    },
                    {
                            .binding = 1,
                            .resource = KDGpu::SamplerBinding{
                                    .sampler = sampler,
                            },
                    },
            },
    });

Filename: kdgpu_doc_snippets.cpp

Vulkan mapping:

See also:

BindGroupLayout, BindGroupOptions, BindGroupPool, Device, PipelineLayout, BindingResource, BindGroupEntry

KDGpu API Overview

KDGpu to Vulkan API Mapping

Public Functions Documentation

function BindGroup

1
BindGroup()

function ~BindGroup

1
~BindGroup()

function BindGroup

1
2
3
BindGroup(
    BindGroup && other
)

function operator=

1
2
3
BindGroup & operator=(
    BindGroup && other
)

function BindGroup

1
2
3
BindGroup(
    const BindGroup & 
) =delete

function operator=

1
2
3
BindGroup & operator=(
    const BindGroup & 
) =delete

function handle

1
inline const Handle< BindGroup_t > & handle() const

function isValid

1
bool isValid() const

function operator Handle< BindGroup_t >

1
inline operator Handle< BindGroup_t >() const

function update

1
2
3
void update(
    const BindGroupEntry & entry
)

Friends

friend Device

1
2
3
friend class Device(
    Device 
);

friend operator==

1
2
3
4
5
friend KDGPU_EXPORT bool operator==(
    const BindGroup & a,

    const BindGroup & b
);

Updated on 2026-03-31 at 00:02:07 +0000