Skip to content

Commit 444ac8d

Browse files
Handle WebGPUDescriptorSetLayout creation
1 parent aac1e7d commit 444ac8d

File tree

3 files changed

+109
-3
lines changed

3 files changed

+109
-3
lines changed

filament/backend/src/webgpu/WebGPUDriver.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ void WebGPUDriver::destroyTimerQuery(Handle<HwTimerQuery> tqh) {
344344
}
345345

346346
void WebGPUDriver::destroyDescriptorSetLayout(Handle<HwDescriptorSetLayout> tqh) {
347+
if (tqh) {
348+
destructHandle<WebGPUDescriptorSetLayout>(tqh);
349+
}
347350
}
348351

349352
void WebGPUDriver::destroyDescriptorSet(Handle<HwDescriptorSet> tqh) {
@@ -418,8 +421,7 @@ Handle<HwRenderTarget> WebGPUDriver::createDefaultRenderTargetS() noexcept {
418421
}
419422

420423
Handle<HwDescriptorSetLayout> WebGPUDriver::createDescriptorSetLayoutS() noexcept {
421-
return Handle<HwDescriptorSetLayout>(
422-
(Handle<HwDescriptorSetLayout>::HandleId) mNextFakeHandle++);
424+
return allocHandle<WebGPUDescriptorSetLayout>();
423425
}
424426

425427
Handle<HwTexture> WebGPUDriver::createTextureExternalImageS() noexcept {
@@ -520,7 +522,9 @@ void WebGPUDriver::createFenceR(Handle<HwFence> fh, int) {}
520522
void WebGPUDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {}
521523

522524
void WebGPUDriver::createDescriptorSetLayoutR(Handle<HwDescriptorSetLayout> dslh,
523-
backend::DescriptorSetLayout&& info) {}
525+
backend::DescriptorSetLayout&& info) {
526+
constructHandle<WebGPUDescriptorSetLayout>(dslh, std::move(info), &mDevice);
527+
}
524528

525529
void WebGPUDriver::createDescriptorSetR(Handle<HwDescriptorSet> dsh,
526530
Handle<HwDescriptorSetLayout> dslh) {}

filament/backend/src/webgpu/WebGPUHandles.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,94 @@ void WGPUVertexBuffer::setBuffer(WGPUBufferObject* bufferObject, uint32_t index)
6060
WGPUBufferObject::WGPUBufferObject(BufferObjectBinding bindingType, uint32_t byteCount)
6161
: HwBufferObject(byteCount),
6262
bufferObjectBinding(bindingType) {}
63+
64+
wgpu::ShaderStage WebGPUDescriptorSetLayout::filamentStageToWGPUStage(ShaderStageFlags fFlags) {
65+
wgpu::ShaderStage retStages = wgpu::ShaderStage::None;
66+
if (any(ShaderStageFlags::VERTEX & fFlags)) {
67+
retStages |= wgpu::ShaderStage::Vertex;
68+
}
69+
if (any(ShaderStageFlags::FRAGMENT & fFlags)) {
70+
retStages |= wgpu::ShaderStage::Fragment;
71+
}
72+
if (any(ShaderStageFlags::COMPUTE & fFlags)) {
73+
retStages |= wgpu::ShaderStage::Compute;
74+
}
75+
return retStages;
76+
}
77+
78+
WebGPUDescriptorSetLayout::WebGPUDescriptorSetLayout(DescriptorSetLayout const& layout,
79+
wgpu::Device const* device) {
80+
assert_invariant(device->Get());
81+
82+
// TODO: layoutDescriptor has a "Label". Ideally we can get info on what this layout is for
83+
// debugging. For now, hack an incrementing value.
84+
static int layoutNum = 0;
85+
86+
87+
uint samplerCount =
88+
std::count_if(layout.bindings.begin(), layout.bindings.end(), [](auto& fEntry) {
89+
return fEntry.type == DescriptorType::SAMPLER ||
90+
fEntry.type == DescriptorType::SAMPLER_EXTERNAL;
91+
});
92+
93+
94+
std::vector<wgpu::BindGroupLayoutEntry> wEntries;
95+
wEntries.reserve(layout.bindings.size() + samplerCount);
96+
97+
for (auto fEntry: layout.bindings) {
98+
auto& wEntry = wEntries.emplace_back();
99+
wEntry.visibility = filamentStageToWGPUStage(fEntry.stageFlags);
100+
wEntry.binding = fEntry.binding * 2;
101+
102+
switch (fEntry.type) {
103+
// TODO Metal treats these the same. Is this fine?
104+
case DescriptorType::SAMPLER_EXTERNAL:
105+
case DescriptorType::SAMPLER: {
106+
// Sampler binding is 2n+1 due to split.
107+
auto& samplerEntry = wEntries.emplace_back();
108+
samplerEntry.binding = fEntry.binding * 2 + 1;
109+
samplerEntry.visibility = wEntry.visibility;
110+
// We are simply hoping that undefined and defaults suffices here.
111+
samplerEntry.sampler.type = wgpu::SamplerBindingType::Undefined;
112+
wEntry.texture.sampleType = wgpu::TextureSampleType::Undefined;
113+
break;
114+
}
115+
case DescriptorType::UNIFORM_BUFFER: {
116+
wEntry.buffer.hasDynamicOffset =
117+
any(fEntry.flags & DescriptorFlags::DYNAMIC_OFFSET);
118+
wEntry.buffer.type = wgpu::BufferBindingType::Uniform;
119+
// TODO: Ideally we fill minBindingSize
120+
break;
121+
}
122+
123+
case DescriptorType::INPUT_ATTACHMENT: {
124+
// TODO: support INPUT_ATTACHMENT. Metal does not currently.
125+
PANIC_POSTCONDITION("Input Attachment is not supported");
126+
break;
127+
}
128+
129+
case DescriptorType::SHADER_STORAGE_BUFFER: {
130+
// TODO: Vulkan does not support this, can we?
131+
PANIC_POSTCONDITION("Shader storage is not supported");
132+
break;
133+
}
134+
}
135+
136+
// Currently flags are only used to specify dynamic offset.
137+
138+
// UNUSED
139+
// fEntry.count
140+
}
141+
142+
wgpu::BindGroupLayoutDescriptor layoutDescriptor{
143+
// TODO: layoutDescriptor has a "Label". Ideally we can get info on what this layout is for
144+
// debugging. For now, hack an incrementing value.
145+
.label{ "layout_" + std::to_string(++layoutNum) },
146+
.entryCount = wEntries.size(),
147+
.entries = wEntries.data()
148+
};
149+
// TODO Do we need to defer this until we have more info on textures and samplers??
150+
mLayout = device->CreateBindGroupLayout(&layoutDescriptor);
151+
}
152+
WebGPUDescriptorSetLayout::~WebGPUDescriptorSetLayout() {}
63153
}// namespace filament::backend

filament/backend/src/webgpu/WebGPUHandles.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ struct WGPUBufferObject : HwBufferObject {
6767
wgpu::Buffer buffer;
6868
const BufferObjectBinding bufferObjectBinding;
6969
};
70+
class WebGPUDescriptorSetLayout : public HwDescriptorSetLayout {
71+
public:
72+
WebGPUDescriptorSetLayout(DescriptorSetLayout const& layout, wgpu::Device const* device);
73+
~WebGPUDescriptorSetLayout();
74+
75+
private:
76+
// TODO: If this is useful elsewhere, remove it from this class
77+
// Convert Filament Shader Stage Flags bitmask to webgpu equivilant
78+
static wgpu::ShaderStage filamentStageToWGPUStage(ShaderStageFlags fFlags);
79+
80+
wgpu::BindGroupLayout mLayout;
81+
};
7082

7183
// TODO: Currently WGPUTexture is not used by WebGPU for useful task.
7284
// Update the struct when used by WebGPU driver.

0 commit comments

Comments
 (0)