/* Crafter®.Graphics Copyright (C) 2026 Catcrafts® catcrafts.net */ // JS bridge declarations for the DOM-mode WebGPU backend. Each function // corresponds to one entry in `additional/dom-webgpu.js`. Handles are // opaque uint32 cookies into the JS-side handle tables. export module Crafter.Graphics:WebGPU; #ifdef CRAFTER_GRAPHICS_WINDOW_DOM import std; export namespace Crafter { using WebGPUBufferRef = std::uint32_t; using WebGPUTextureRef = std::uint32_t; using WebGPUSamplerRef = std::uint32_t; using WebGPUCommandEncoderRef = std::uint32_t; // unused as a real handle; just a marker type for portability } namespace Crafter::WebGPU { __attribute__((import_module("env"), import_name("wgpuGetCanvasWidth"))) extern "C" std::int32_t wgpuGetCanvasWidth(); __attribute__((import_module("env"), import_name("wgpuGetCanvasHeight"))) extern "C" std::int32_t wgpuGetCanvasHeight(); __attribute__((import_module("env"), import_name("wgpuSurfaceWidth"))) extern "C" std::int32_t wgpuSurfaceWidth(); __attribute__((import_module("env"), import_name("wgpuSurfaceHeight"))) extern "C" std::int32_t wgpuSurfaceHeight(); __attribute__((import_module("env"), import_name("wgpuInit"))) extern "C" void wgpuInit(); __attribute__((import_module("env"), import_name("wgpuCreateBuffer"))) extern "C" std::uint32_t wgpuCreateBuffer(std::int32_t byteSize); __attribute__((import_module("env"), import_name("wgpuWriteBuffer"))) extern "C" void wgpuWriteBuffer(std::uint32_t handle, const void* srcPtr, std::int32_t byteSize); __attribute__((import_module("env"), import_name("wgpuDestroyBuffer"))) extern "C" void wgpuDestroyBuffer(std::uint32_t handle); __attribute__((import_module("env"), import_name("wgpuCreateAtlasTexture"))) extern "C" std::uint32_t wgpuCreateAtlasTexture(std::int32_t w, std::int32_t h); __attribute__((import_module("env"), import_name("wgpuWriteAtlasRegion"))) extern "C" void wgpuWriteAtlasRegion(std::uint32_t handle, const void* srcPtr, std::int32_t srcW, std::int32_t srcH, std::int32_t srcBytesPerRow, std::int32_t dstX, std::int32_t dstY, std::int32_t copyW, std::int32_t copyH); __attribute__((import_module("env"), import_name("wgpuDestroyTexture"))) extern "C" void wgpuDestroyTexture(std::uint32_t handle); // General-purpose rgba8unorm 2D texture for material albedo etc. // Separate from the atlas path because atlas uses r8unorm + sub-region // writes; this one takes the whole image in one shot. __attribute__((import_module("env"), import_name("wgpuCreateImage2D"))) extern "C" std::uint32_t wgpuCreateImage2D(std::int32_t w, std::int32_t h); __attribute__((import_module("env"), import_name("wgpuWriteImage2D"))) extern "C" void wgpuWriteImage2D(std::uint32_t handle, const void* srcPtr, std::int32_t byteSize, std::int32_t w, std::int32_t h); // 2D texture array — `layerCount` rgba8unorm layers of identical (w × h). // Sampled via `texture_2d_array` in WGSL (UICustomBindingKind 3). // Used by Image2DArray to stack per-material albedos for one // multi-material scene. __attribute__((import_module("env"), import_name("wgpuCreateImage2DArray"))) extern "C" std::uint32_t wgpuCreateImage2DArray(std::int32_t w, std::int32_t h, std::int32_t layerCount); __attribute__((import_module("env"), import_name("wgpuWriteImage2DLayer"))) extern "C" void wgpuWriteImage2DLayer(std::uint32_t handle, std::int32_t layer, const void* srcPtr, std::int32_t byteSize, std::int32_t w, std::int32_t h); __attribute__((import_module("env"), import_name("wgpuCreateLinearClampSampler"))) extern "C" std::uint32_t wgpuCreateLinearClampSampler(); __attribute__((import_module("env"), import_name("wgpuFrameBegin"))) extern "C" void wgpuFrameBegin(); __attribute__((import_module("env"), import_name("wgpuFrameEnd"))) extern "C" void wgpuFrameEnd(); __attribute__((import_module("env"), import_name("wgpuDispatchQuads"))) extern "C" void wgpuDispatchQuads(std::uint32_t itemsHandle, const void* headerPtr, std::int32_t gx, std::int32_t gy); __attribute__((import_module("env"), import_name("wgpuDispatchCircles"))) extern "C" void wgpuDispatchCircles(std::uint32_t itemsHandle, const void* headerPtr, std::int32_t gx, std::int32_t gy); __attribute__((import_module("env"), import_name("wgpuDispatchImages"))) extern "C" void wgpuDispatchImages(std::uint32_t itemsHandle, const void* headerPtr, std::int32_t gx, std::int32_t gy, std::uint32_t texHandle, std::uint32_t sampHandle); __attribute__((import_module("env"), import_name("wgpuDispatchText"))) extern "C" void wgpuDispatchText(std::uint32_t itemsHandle, const void* headerPtr, std::int32_t gx, std::int32_t gy, std::uint32_t atlasHandle, std::uint32_t sampHandle); // ─── custom user-authored compute shaders ─────────────────────────── // rayQueryFlag = 1 swaps group(1) from the UI ping-pong pair to the RT // data heaps (TLAS, BVH, meshRecs, verts, idx, primRemap, outImage) and // prepends a WGSL prelude exposing the rayQuery* API. Shaders that set // this MUST NOT declare their own @group(1) bindings. __attribute__((import_module("env"), import_name("wgpuLoadCustomShader"))) extern "C" std::uint32_t wgpuLoadCustomShader(const void* wgslPtr, std::int32_t wgslLen, const void* bindingsPtr, std::int32_t bindingsCount, std::int32_t rayQueryFlag); __attribute__((import_module("env"), import_name("wgpuDispatchCustom"))) extern "C" void wgpuDispatchCustom(std::uint32_t pipelineHandle, const void* pushPtr, std::int32_t pushBytes, const void* handlesPtr, std::int32_t handlesCount, std::int32_t gx, std::int32_t gy, std::int32_t gz); // ─── software raytracing ─────────────────────────────────────────── // // Mesh::Build forwards vertex / index / BVH-node / primRemap arrays // to the JS bridge, which queue.writeBuffers them into the global // RT mesh heaps (growing if needed) and records the per-mesh offsets // under a freshly-allocated u32 handle. The handle is what user code // stores in RTInstance::accelerationStructureReference; the WebGPU // TLAS-build compute shader resolves it back to root AABB + heap // offsets at dispatch time. Returns 0 on failure. // The optional `attribsPtr` / `attribsByteCount` carry per-vertex // attribute payload (normals, UVs, etc. — layout is example-defined) // that gets appended to a global attribs heap and exposed to RT // closest-hit shaders as `vertexAttribs : array` at // @group(1) @binding(7). Pass (nullptr, 0) for positions-only meshes. __attribute__((import_module("env"), import_name("wgpuRegisterMeshBLAS"))) extern "C" std::uint32_t wgpuRegisterMeshBLAS( float minX, float minY, float minZ, float maxX, float maxY, float maxZ, const void* verticesPtr, std::int32_t vertexCount, const void* indicesPtr, std::int32_t indexCount, const void* bvhNodesPtr, std::int32_t bvhNodeCount, const void* primRemapPtr, std::int32_t primRemapCount, const void* attribsPtr, std::int32_t attribsByteCount); // RT pipeline build. The library composes WGSL by concatenating the // traversal library, generated hit-group switches, and the user- // supplied raygen / miss / closesthit / anyhit bodies. `bindings` is // UICustomBinding-shaped (8 bytes each) declaring extra @group(2)+ // resources the user's closest-hit / miss / raygen WGSL references. // Pass (nullptr, 0) for a pipeline with no user-declared bindings. // Returns an opaque pipeline handle. __attribute__((import_module("env"), import_name("wgpuLoadRTPipeline"))) extern "C" std::uint32_t wgpuLoadRTPipeline(const void* wgslPtr, std::int32_t wgslLen, const void* bindingsPtr, std::int32_t bindingsCount); // Dispatch a TraceRays-equivalent pass: the RT pipeline is dispatched // over a (gx, gy) tile grid; the library writes the push data (camera, // payload, etc. — opaque) into a uniform ring buffer, attaches the TLAS // + global mesh heap, and runs one workgroup per 8x8 screen tile. // `handles[]` carries resolved WebGPU resource handles for every user // binding declared at pipeline-load time, in the same order. Pass // (nullptr, 0) for a pipeline with no user bindings. __attribute__((import_module("env"), import_name("wgpuDispatchRT"))) extern "C" void wgpuDispatchRT(std::uint32_t pipelineHandle, const void* pushPtr, std::int32_t pushBytes, std::uint32_t tlasBufHandle, std::int32_t instanceCount, std::int32_t gx, std::int32_t gy, const void* handlesPtr, std::int32_t handlesCount); // GPU TLAS-build dispatch. Reads the instance buffer (host-uploaded or // GPU-written), produces per-instance world-space AABBs + per-instance // transform matrices in a flat tlasBuf SSBO consumed by traceRay / rayQuery. __attribute__((import_module("env"), import_name("wgpuBuildTLAS"))) extern "C" void wgpuBuildTLAS(std::uint32_t instanceBufHandle, std::int32_t instanceCount, std::uint32_t tlasOutBufHandle); } #endif // CRAFTER_GRAPHICS_WINDOW_DOM