custom shader webgpu
This commit is contained in:
parent
dedf6b0467
commit
64116cd980
12 changed files with 445 additions and 36 deletions
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ void UIRenderer::DispatchText(GraphicsCommandBuffer cmd, std::uint32_t bufferSlo
|
|||
|
||||
// ─── generic Dispatch (with barrier) ────────────────────────────────────
|
||||
|
||||
void UIRenderer::Dispatch(GraphicsCommandBuffer cmd, const ComputeShader& shader,
|
||||
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) {
|
||||
if (!firstDispatchThisFrame_) {
|
||||
|
|
|
|||
41
implementations/Crafter.Graphics-WebGPUComputeShader.cpp
Normal file
41
implementations/Crafter.Graphics-WebGPUComputeShader.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Crafter®.Graphics
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
catcrafts.net
|
||||
*/
|
||||
|
||||
module Crafter.Graphics:WebGPUComputeShader_impl;
|
||||
import :WebGPUComputeShader;
|
||||
import :WebGPU;
|
||||
import std;
|
||||
|
||||
using namespace Crafter;
|
||||
|
||||
void WebGPUComputeShader::Load(std::string_view wgsl,
|
||||
std::span<const UICustomBinding> bindings) {
|
||||
customBindings.assign(bindings.begin(), bindings.end());
|
||||
pipelineHandle = WebGPU::wgpuLoadCustomShader(
|
||||
wgsl.data(),
|
||||
static_cast<std::int32_t>(wgsl.size()),
|
||||
customBindings.data(),
|
||||
static_cast<std::int32_t>(customBindings.size())
|
||||
);
|
||||
}
|
||||
|
||||
void WebGPUComputeShader::Load(const std::filesystem::path& wgslPath,
|
||||
std::span<const UICustomBinding> bindings) {
|
||||
std::ifstream f(wgslPath, std::ios::binary | std::ios::ate);
|
||||
if (!f.is_open()) {
|
||||
std::println("WebGPUComputeShader::Load: cannot open {}", wgslPath.string());
|
||||
return;
|
||||
}
|
||||
auto size = f.tellg();
|
||||
if (size <= 0) {
|
||||
std::println("WebGPUComputeShader::Load: empty file {}", wgslPath.string());
|
||||
return;
|
||||
}
|
||||
f.seekg(0, std::ios::beg);
|
||||
std::string src(static_cast<std::size_t>(size), '\0');
|
||||
f.read(src.data(), size);
|
||||
Load(std::string_view{src}, bindings);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue