custom shader webgpu

This commit is contained in:
Jorijn van der Graaf 2026-05-18 05:39:17 +02:00
commit 64116cd980
12 changed files with 445 additions and 36 deletions

View file

@ -138,3 +138,43 @@ SamplerSlot UIRenderer::RegisterLinearClampSampler() {
heap_->samplerTable[range.firstElement] = WebGPU::wgpuCreateLinearClampSampler();
return SamplerSlot{heap_, range.firstElement};
}
void UIRenderer::Dispatch(GraphicsCommandBuffer /*cmd*/, const GraphicsComputeShader& shader,
const void* push, std::uint32_t pushBytes,
std::uint32_t gx, std::uint32_t gy, std::uint32_t gz) {
// For each user-declared binding, read the slot uint32 out of push
// data at the recorded offset, look up the GPU handle in the heap,
// and assemble a list of handles in the same order the JS bridge
// expects (matching shader.customBindings).
std::vector<std::uint32_t> handles;
handles.reserve(shader.customBindings.size());
const std::uint8_t* p = static_cast<const std::uint8_t*>(push);
for (const auto& b : shader.customBindings) {
if (b.pushOffset + sizeof(std::uint32_t) > pushBytes) {
std::println("UIRenderer::Dispatch: binding pushOffset {} out of bounds (push={})",
b.pushOffset, pushBytes);
return;
}
std::uint32_t slot;
std::memcpy(&slot, p + b.pushOffset, sizeof(slot));
std::uint32_t handle = 0;
switch (b.kind) {
case UICustomBindingKind::Buffer:
if (slot < heap_->bufferTable.size()) handle = heap_->bufferTable[slot];
break;
case UICustomBindingKind::SampledTexture:
if (slot < heap_->imageTable.size()) handle = heap_->imageTable[slot];
break;
case UICustomBindingKind::Sampler:
if (slot < heap_->samplerTable.size()) handle = heap_->samplerTable[slot];
break;
}
handles.push_back(handle);
}
WebGPU::wgpuDispatchCustom(shader.pipelineHandle,
push, static_cast<std::int32_t>(pushBytes),
handles.data(), static_cast<std::int32_t>(handles.size()),
static_cast<std::int32_t>(gx),
static_cast<std::int32_t>(gy),
static_cast<std::int32_t>(gz));
}