summaryrefslogtreecommitdiff
path: root/src/gpu/bind_group_builder.h
blob: abce9dce9bfdba043f7e2c195b86fa667d982b58 (plain)
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// WGPU bind group builder - reduces boilerplate for bind group creation
#pragma once
#include <vector>

// Forward declarations (users must include gpu.h)
struct WGPUBindGroupLayoutEntry;
struct WGPUBindGroupEntry;
struct WGPUDeviceImpl;
typedef struct WGPUDeviceImpl* WGPUDevice;
struct WGPUBindGroupLayoutImpl;
typedef struct WGPUBindGroupLayoutImpl* WGPUBindGroupLayout;
struct WGPUBindGroupImpl;
typedef struct WGPUBindGroupImpl* WGPUBindGroup;
struct WGPUBufferImpl;
typedef struct WGPUBufferImpl* WGPUBuffer;
struct WGPUTextureViewImpl;
typedef struct WGPUTextureViewImpl* WGPUTextureView;
struct WGPUSamplerImpl;
typedef struct WGPUSamplerImpl* WGPUSampler;
typedef uint32_t WGPUShaderStageFlags;

#include "platform/platform.h"

class BindGroupLayoutBuilder {
  std::vector<WGPUBindGroupLayoutEntry> entries_;

public:
  BindGroupLayoutBuilder& uniform(uint32_t binding, WGPUShaderStageFlags vis, size_t min_size = 0) {
    WGPUBindGroupLayoutEntry e{};
    e.binding = binding;
    e.visibility = vis;
    e.buffer.type = WGPUBufferBindingType_Uniform;
    if (min_size) e.buffer.minBindingSize = min_size;
    entries_.push_back(e);
    return *this;
  }

  BindGroupLayoutBuilder& storage(uint32_t binding, WGPUShaderStageFlags vis, size_t min_size = 0) {
    WGPUBindGroupLayoutEntry e{};
    e.binding = binding;
    e.visibility = vis;
    e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage;
    if (min_size) e.buffer.minBindingSize = min_size;
    entries_.push_back(e);
    return *this;
  }

  BindGroupLayoutBuilder& texture(uint32_t binding, WGPUShaderStageFlags vis) {
    WGPUBindGroupLayoutEntry e{};
    e.binding = binding;
    e.visibility = vis;
    e.texture.sampleType = WGPUTextureSampleType_Float;
    e.texture.viewDimension = WGPUTextureViewDimension_2D;
    entries_.push_back(e);
    return *this;
  }

  BindGroupLayoutBuilder& uint_texture(uint32_t binding, WGPUShaderStageFlags vis) {
    WGPUBindGroupLayoutEntry e{};
    e.binding = binding;
    e.visibility = vis;
    e.texture.sampleType = WGPUTextureSampleType_Uint;
    e.texture.viewDimension = WGPUTextureViewDimension_2D;
    entries_.push_back(e);
    return *this;
  }

  BindGroupLayoutBuilder& storage_texture(uint32_t binding, WGPUShaderStageFlags vis,
                                          WGPUTextureFormat format) {
    WGPUBindGroupLayoutEntry e{};
    e.binding = binding;
    e.visibility = vis;
    e.storageTexture.access = WGPUStorageTextureAccess_WriteOnly;
    e.storageTexture.format = format;
    e.storageTexture.viewDimension = WGPUTextureViewDimension_2D;
    entries_.push_back(e);
    return *this;
  }

  BindGroupLayoutBuilder& sampler(uint32_t binding, WGPUShaderStageFlags vis) {
    WGPUBindGroupLayoutEntry e{};
    e.binding = binding;
    e.visibility = vis;
    e.sampler.type = WGPUSamplerBindingType_Filtering;
    entries_.push_back(e);
    return *this;
  }

  WGPUBindGroupLayout build(WGPUDevice device) {
    WGPUBindGroupLayoutDescriptor desc{};
    desc.entryCount = entries_.size();
    desc.entries = entries_.data();
    return wgpuDeviceCreateBindGroupLayout(device, &desc);
  }
};

class BindGroupBuilder {
  std::vector<WGPUBindGroupEntry> entries_;

public:
  BindGroupBuilder& buffer(uint32_t binding, WGPUBuffer buf, size_t size) {
    WGPUBindGroupEntry e{};
    e.binding = binding;
    e.buffer = buf;
    e.size = size;
    entries_.push_back(e);
    return *this;
  }

  BindGroupBuilder& texture(uint32_t binding, WGPUTextureView view) {
    WGPUBindGroupEntry e{};
    e.binding = binding;
    e.textureView = view;
    entries_.push_back(e);
    return *this;
  }

  BindGroupBuilder& sampler(uint32_t binding, WGPUSampler samp) {
    WGPUBindGroupEntry e{};
    e.binding = binding;
    e.sampler = samp;
    entries_.push_back(e);
    return *this;
  }

  WGPUBindGroup build(WGPUDevice device, WGPUBindGroupLayout layout) {
    WGPUBindGroupDescriptor desc{};
    desc.layout = layout;
    desc.entryCount = entries_.size();
    desc.entries = entries_.data();
    return wgpuDeviceCreateBindGroup(device, &desc);
  }
};