diff --git a/README.md b/README.md index d159c5c2..ca7a5638 100644 --- a/README.md +++ b/README.md @@ -286,7 +286,7 @@ Note: In this table, `Cocoa GUI` means native macOS AppKit/Cocoa window-based sa |Canvas | | | | | | | |WebGL | |[Link](https://github.com/cx20/hello/tree/master/web/wasm_c/webgl1/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/wasm_cpp/webgl1/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/wasm_rust/webgl1/triangle) |[Link](https://github.com/cx20/hello/tree/master/web/javascript/webgl1/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/typescript/webgl1/triangle)| |WebGL2 | |[Link](https://github.com/cx20/hello/tree/master/web/wasm_c/webgl2/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/wasm_cpp/webgl2/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/wasm_rust/webgl2/triangle) |[Link](https://github.com/cx20/hello/tree/master/web/javascript/webgl2/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/typescript/webgl2/triangle)| -|WebGPU | | |[Link](https://github.com/cx20/hello/tree/master/web/wasm_cpp/webgpu/triangle)|[WIP] [Link](https://github.com/cx20/hello/tree/master/web/wasm_rust/webgpu/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/javascript/webgpu/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/typescript/webgpu/triangle)| +|WebGPU | |[Link](https://github.com/cx20/hello/tree/master/web/wasm_c/webgpu/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/wasm_cpp/webgpu/triangle)|[WIP] [Link](https://github.com/cx20/hello/tree/master/web/wasm_rust/webgpu/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/javascript/webgpu/triangle)|[Link](https://github.com/cx20/hello/tree/master/web/typescript/webgpu/triangle)| |CSS | | | | | | | |SVG | | | | | | | diff --git a/web/wasm_c/webgpu/triangle/build.bat b/web/wasm_c/webgpu/triangle/build.bat new file mode 100644 index 00000000..912eeebf --- /dev/null +++ b/web/wasm_c/webgpu/triangle/build.bat @@ -0,0 +1 @@ +emcc hello.c -std=c11 -s WASM=1 -O3 --use-port=emdawnwebgpu -o index.js diff --git a/web/wasm_c/webgpu/triangle/hello.c b/web/wasm_c/webgpu/triangle/hello.c new file mode 100644 index 00000000..1038d501 --- /dev/null +++ b/web/wasm_c/webgpu/triangle/hello.c @@ -0,0 +1,271 @@ +// File : hello.c +// Compile : emcc hello.c -std=c11 -s WASM=1 -O3 --use-port=emdawnwebgpu -o index.js +// +// forked from https://github.com/cwoffenden/hello-webgpu + +#include +#include +#include +#include +#include +#include +#include + +static WGPUInstance instance; +static WGPUDevice device; +static WGPUQueue queue; +static WGPUSurface surface; + +// On the web the preferred canvas format is typically BGRA8Unorm. +static WGPUTextureFormat surfaceFormat = WGPUTextureFormat_BGRA8Unorm; + +static WGPURenderPipeline pipeline; +static WGPUBuffer vertBuf; // vertex buffer with triangle position and colours +static WGPUBuffer indxBuf; // index buffer + +// Query the current drawing-buffer size (the full browser window). +EM_JS(int, canvas_get_width, (), { return window.innerWidth; }); +EM_JS(int, canvas_get_height, (), { return window.innerHeight; }); + +static uint32_t curW = 0; +static uint32_t curH = 0; + +static const char triangle_vert_wgsl[] = + "struct VertexOut {\n" + " @location(0) vCol : vec3,\n" + " @builtin(position) Position : vec4\n" + "}\n" + "@vertex\n" + "fn main(\n" + " @location(0) aPos : vec3,\n" + " @location(1) aCol : vec3\n" + ") -> VertexOut {\n" + " var output : VertexOut;\n" + " output.Position = vec4(aPos, 1.0);\n" + " output.vCol = aCol;\n" + " return output;\n" + "}\n"; + +static const char triangle_frag_wgsl[] = + "@fragment\n" + "fn main(@location(0) vCol : vec3) -> @location(0) vec4 {\n" + " return vec4(vCol, 1.0);\n" + "}\n"; + +static void configureSurface(uint32_t w, uint32_t h) { + WGPUSurfaceConfiguration config = {0}; + config.device = device; + config.format = surfaceFormat; + config.usage = WGPUTextureUsage_RenderAttachment; + config.width = w; + config.height = h; + config.alphaMode = WGPUCompositeAlphaMode_Auto; + config.presentMode = WGPUPresentMode_Fifo; + wgpuSurfaceConfigure(surface, &config); + curW = w; + curH = h; +} + +static void createSurface(void) { + WGPUEmscriptenSurfaceSourceCanvasHTMLSelector canvasDesc = {0}; + canvasDesc.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector; + canvasDesc.selector = (WGPUStringView){ "canvas", WGPU_STRLEN }; + + WGPUSurfaceDescriptor surfDesc = {0}; + surfDesc.nextInChain = &canvasDesc.chain; + + surface = wgpuInstanceCreateSurface(instance, &surfDesc); + + configureSurface((uint32_t)canvas_get_width(), (uint32_t)canvas_get_height()); +} + +static WGPUShaderModule createShader(const char* code) { + WGPUShaderSourceWGSL wgsl = {0}; + wgsl.chain.sType = WGPUSType_ShaderSourceWGSL; + wgsl.code = (WGPUStringView){ code, WGPU_STRLEN }; + WGPUShaderModuleDescriptor desc = {0}; + desc.nextInChain = &wgsl.chain; + return wgpuDeviceCreateShaderModule(device, &desc); +} + +static WGPUBuffer createBuffer(const void* data, size_t size, WGPUBufferUsage usage) { + WGPUBufferDescriptor desc = {0}; + desc.usage = WGPUBufferUsage_CopyDst | usage; + desc.size = size; + WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &desc); + wgpuQueueWriteBuffer(queue, buffer, 0, data, size); + return buffer; +} + +static void createPipelineAndBuffers(void) { + WGPUShaderModule vertMod = createShader(triangle_vert_wgsl); + WGPUShaderModule fragMod = createShader(triangle_frag_wgsl); + + // Simple pipeline layout without bind group layouts + WGPUPipelineLayoutDescriptor layoutDesc = {0}; + WGPUPipelineLayout pipelineLayout = wgpuDeviceCreatePipelineLayout(device, &layoutDesc); + + // describe buffer layouts + WGPUVertexAttribute vertAttrs[2] = {0}; + vertAttrs[0].format = WGPUVertexFormat_Float32x3; + vertAttrs[0].offset = 0; + vertAttrs[0].shaderLocation = 0; + vertAttrs[1].format = WGPUVertexFormat_Float32x3; + vertAttrs[1].offset = 3 * sizeof(float); + vertAttrs[1].shaderLocation = 1; + WGPUVertexBufferLayout vertexBufferLayout = {0}; + vertexBufferLayout.arrayStride = 6 * sizeof(float); + vertexBufferLayout.attributeCount = 2; + vertexBufferLayout.attributes = vertAttrs; + + // Fragment state + WGPUBlendState blend = {0}; + blend.color.operation = WGPUBlendOperation_Add; + blend.color.srcFactor = WGPUBlendFactor_One; + blend.color.dstFactor = WGPUBlendFactor_Zero; + blend.alpha.operation = WGPUBlendOperation_Add; + blend.alpha.srcFactor = WGPUBlendFactor_One; + blend.alpha.dstFactor = WGPUBlendFactor_Zero; + WGPUColorTargetState colorTarget = {0}; + colorTarget.format = surfaceFormat; + colorTarget.blend = &blend; + colorTarget.writeMask = WGPUColorWriteMask_All; + + WGPUFragmentState fragment = {0}; + fragment.module = fragMod; + fragment.entryPoint = (WGPUStringView){ "main", WGPU_STRLEN }; + fragment.targetCount = 1; + fragment.targets = &colorTarget; + + WGPURenderPipelineDescriptor desc = {0}; + desc.fragment = &fragment; + + // Other state + desc.layout = pipelineLayout; + desc.depthStencil = NULL; + + desc.vertex.module = vertMod; + desc.vertex.entryPoint = (WGPUStringView){ "main", WGPU_STRLEN }; + desc.vertex.bufferCount = 1; + desc.vertex.buffers = &vertexBufferLayout; + + desc.multisample.count = 1; + desc.multisample.mask = 0xFFFFFFFF; + desc.multisample.alphaToCoverageEnabled = false; + + desc.primitive.frontFace = WGPUFrontFace_CCW; + desc.primitive.cullMode = WGPUCullMode_None; + desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined; + + pipeline = wgpuDeviceCreateRenderPipeline(device, &desc); + + wgpuPipelineLayoutRelease(pipelineLayout); + wgpuShaderModuleRelease(fragMod); + wgpuShaderModuleRelease(vertMod); + + // create the buffers (x, y, z, r, g, b) + float const vertData[] = { + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, // v0 + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // v1 + -0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // v2 + }; + uint16_t const indxData[] = { + 0, 1, 2, + 0 // padding (better way of doing this?) + }; + vertBuf = createBuffer(vertData, sizeof(vertData), WGPUBufferUsage_Vertex); + indxBuf = createBuffer(indxData, sizeof(indxData), WGPUBufferUsage_Index); +} + +static EM_BOOL redraw(double time, void* userData) { + (void)time; (void)userData; + // Follow the browser window size (reconfigure the surface on resize). + uint32_t w = (uint32_t)canvas_get_width(); + uint32_t h = (uint32_t)canvas_get_height(); + if (w != curW || h != curH) { + configureSurface(w, h); + } + + WGPUSurfaceTexture surfaceTexture; + wgpuSurfaceGetCurrentTexture(surface, &surfaceTexture); // acquire the current texture + WGPUTextureView backBufView = wgpuTextureCreateView(surfaceTexture.texture, NULL); // create textureView + + WGPURenderPassColorAttachment colorDesc = {0}; + colorDesc.view = backBufView; + colorDesc.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; + colorDesc.loadOp = WGPULoadOp_Clear; + colorDesc.storeOp = WGPUStoreOp_Store; + colorDesc.clearValue.r = 1.0f; + colorDesc.clearValue.g = 1.0f; + colorDesc.clearValue.b = 1.0f; + colorDesc.clearValue.a = 1.0f; + + WGPURenderPassDescriptor renderPass = {0}; + renderPass.colorAttachmentCount = 1; + renderPass.colorAttachments = &colorDesc; + + WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, NULL); // create encoder + WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &renderPass); // create pass + + // draw the triangle (comment these four lines to simply clear the screen) + wgpuRenderPassEncoderSetPipeline(pass, pipeline); + wgpuRenderPassEncoderSetVertexBuffer(pass, 0, vertBuf, 0, WGPU_WHOLE_SIZE); + wgpuRenderPassEncoderSetIndexBuffer(pass, indxBuf, WGPUIndexFormat_Uint16, 0, WGPU_WHOLE_SIZE); + wgpuRenderPassEncoderDrawIndexed(pass, 3, 1, 0, 0, 0); + + wgpuRenderPassEncoderEnd(pass); + wgpuRenderPassEncoderRelease(pass); // release pass + WGPUCommandBuffer commands = wgpuCommandEncoderFinish(encoder, NULL); // create commands + wgpuCommandEncoderRelease(encoder); // release encoder + + wgpuQueueSubmit(queue, 1, &commands); + wgpuCommandBufferRelease(commands); // release commands + wgpuTextureViewRelease(backBufView); // release textureView + wgpuTextureRelease(surfaceTexture.texture); // release surface texture + + return EM_TRUE; // keep the rAF loop running +} + +// Called once the device has been obtained: set up the surface, pipeline and +// start the render loop. +static void start(void) { + queue = wgpuDeviceGetQueue(device); + createSurface(); + createPipelineAndBuffers(); + emscripten_request_animation_frame_loop(redraw, NULL); +} + +static void onDeviceRequestEnded(WGPURequestDeviceStatus status, WGPUDevice dev, WGPUStringView message, void* userdata1, void* userdata2) { + (void)userdata1; (void)userdata2; + if (status != WGPURequestDeviceStatus_Success) { + printf("Failed to get a WebGPU device: %.*s\n", (int)message.length, message.data); + return; + } + device = dev; + start(); +} + +static void onAdapterRequestEnded(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2) { + (void)userdata1; (void)userdata2; + if (status != WGPURequestAdapterStatus_Success) { + printf("Failed to get a WebGPU adapter: %.*s\n", (int)message.length, message.data); + return; + } + WGPUDeviceDescriptor deviceDesc = {0}; + WGPURequestDeviceCallbackInfo callbackInfo = {0}; + callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous; + callbackInfo.callback = onDeviceRequestEnded; + wgpuAdapterRequestDevice(adapter, &deviceDesc, callbackInfo); +} + +int main(void) { + instance = wgpuCreateInstance(NULL); + + WGPURequestAdapterCallbackInfo callbackInfo = {0}; + callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous; + callbackInfo.callback = onAdapterRequestEnded; + wgpuInstanceRequestAdapter(instance, NULL, callbackInfo); + + return 0; +} diff --git a/web/wasm_c/webgpu/triangle/index.html b/web/wasm_c/webgpu/triangle/index.html new file mode 100644 index 00000000..bd776cef --- /dev/null +++ b/web/wasm_c/webgpu/triangle/index.html @@ -0,0 +1,25 @@ + + + + Hello, World! + + + + + + + + + + + +View Source + + diff --git a/web/wasm_c/webgpu/triangle/index.js b/web/wasm_c/webgpu/triangle/index.js new file mode 100644 index 00000000..2d63d96a --- /dev/null +++ b/web/wasm_c/webgpu/triangle/index.js @@ -0,0 +1 @@ +var Module=typeof Module!="undefined"?Module:{};var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";var programArgs=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=globalThis.document?.currentScript?.src;if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}programArgs=process.argv.slice(2);if(typeof module!="undefined"){module["exports"]=Module}quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}var isFileURI=filename=>filename.startsWith("file://");class EmscriptenEH{}class EmscriptenSjLj extends EmscriptenEH{}var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["D"]()}function preMain(){}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what=`Aborted(${what})`;err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("index.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var HEAP16;var HEAP32;var HEAP64;var HEAP8;var HEAPF32;var HEAPF64;var HEAPU16;var HEAPU32;var HEAPU64;var HEAPU8;var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var __abort_js=()=>abort("");var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var _emscripten_request_animation_frame_loop=(cb,userData)=>{function tick(timeStamp){if(getWasmTableEntry(cb)(timeStamp,userData)){requestAnimationFrame(tick)}}return requestAnimationFrame(tick)};var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):"";var writeI53ToI64=(ptr,num)=>{HEAPU32[ptr>>2]=num;var lower=HEAPU32[ptr>>2];HEAPU32[ptr+4>>2]=(num-lower)/4294967296};var stringToNewUTF8=str=>{var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8(str,ret,size);return ret};var readI53FromI64=ptr=>HEAPU32[ptr>>2]+HEAP32[ptr+4>>2]*4294967296;var WebGPU={Internals:{jsObjects:[],jsObjectInsert:(ptr,jsObject)=>{ptr>>>=0;WebGPU.Internals.jsObjects[ptr]=jsObject},bufferOnUnmaps:[],futures:[],futureInsert:(futureId,promise)=>{}},getJsObject:ptr=>{if(!ptr)return undefined;ptr>>>=0;return WebGPU.Internals.jsObjects[ptr]},importJsAdapter:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateAdapter(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsBindGroup:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateBindGroup(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsBindGroupLayout:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateBindGroupLayout(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsBuffer:(buffer,parentPtr=0)=>{assert(buffer.mapState==="unmapped");var bufferPtr=_emwgpuImportBuffer(parentPtr);WebGPU.Internals.jsObjectInsert(bufferPtr,buffer);return bufferPtr},importJsCommandBuffer:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateCommandBuffer(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsCommandEncoder:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateCommandEncoder(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsComputePassEncoder:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateComputePassEncoder(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsComputePipeline:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateComputePipeline(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsDevice:(device,parentPtr=0)=>{var queuePtr=_emwgpuCreateQueue(parentPtr);var devicePtr=_emwgpuCreateDevice(parentPtr,queuePtr);WebGPU.Internals.jsObjectInsert(queuePtr,device.queue);WebGPU.Internals.jsObjectInsert(devicePtr,device);return devicePtr},importJsExternalTexture:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateExternalTexture(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsPipelineLayout:(obj,parentPtr=0)=>{var ptr=_emwgpuCreatePipelineLayout(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsQuerySet:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateQuerySet(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsQueue:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateQueue(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsRenderBundle:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateRenderBundle(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsRenderBundleEncoder:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateRenderBundleEncoder(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsRenderPassEncoder:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateRenderPassEncoder(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsRenderPipeline:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateRenderPipeline(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsSampler:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateSampler(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsShaderModule:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateShaderModule(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsSurface:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateSurface(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsTexture:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateTexture(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},importJsTextureView:(obj,parentPtr=0)=>{var ptr=_emwgpuCreateTextureView(parentPtr);WebGPU.Internals.jsObjects[ptr]=obj;return ptr},errorCallback:(callback,type,message,userdata)=>{var sp=stackSave();var messagePtr=stringToUTF8OnStack(message);getWasmTableEntry(callback)(type,messagePtr,userdata);stackRestore(sp)},iterateExtensions:(root,handlers)=>{for(var ptr=HEAPU32[root>>2];ptr;ptr=HEAPU32[ptr>>2]){var sType=HEAP32[ptr+4>>2];var handler=handlers[sType](ptr)}},setStringView:(ptr,data,length)=>{HEAPU32[ptr>>2]=data;HEAPU32[ptr+4>>2]=length},makeStringFromStringView:stringViewPtr=>{var ptr=HEAPU32[stringViewPtr>>2];var length=HEAPU32[stringViewPtr+4>>2];return UTF8ToString(ptr,length)},makeStringFromOptionalStringView:stringViewPtr=>{var ptr=HEAPU32[stringViewPtr>>2];var length=HEAPU32[stringViewPtr+4>>2];if(!ptr){if(length===0){return""}return undefined}return UTF8ToString(ptr,length)},makeColor:ptr=>({r:HEAPF64[ptr>>3],g:HEAPF64[ptr+8>>3],b:HEAPF64[ptr+16>>3],a:HEAPF64[ptr+24>>3]}),makeExtent3D:ptr=>({width:HEAPU32[ptr>>2],height:HEAPU32[ptr+4>>2],depthOrArrayLayers:HEAPU32[ptr+8>>2]}),makeOrigin3D:ptr=>({x:HEAPU32[ptr>>2],y:HEAPU32[ptr+4>>2],z:HEAPU32[ptr+8>>2]}),makeTexelCopyTextureInfo:ptr=>({texture:WebGPU.getJsObject(HEAPU32[ptr>>2]),mipLevel:HEAPU32[ptr+4>>2],origin:WebGPU.makeOrigin3D(ptr+8),aspect:WebGPU.TextureAspect[HEAP32[ptr+20>>2]]}),makeTexelCopyBufferLayout:ptr=>{var bytesPerRow=HEAPU32[ptr+8>>2];var rowsPerImage=HEAPU32[ptr+12>>2];return{offset:readI53FromI64(ptr),bytesPerRow:bytesPerRow===4294967295?undefined:bytesPerRow,rowsPerImage:rowsPerImage===4294967295?undefined:rowsPerImage}},makeTexelCopyBufferInfo:ptr=>{var layoutPtr=ptr+0;var bufferCopyView=WebGPU.makeTexelCopyBufferLayout(layoutPtr);bufferCopyView["buffer"]=WebGPU.getJsObject(HEAPU32[ptr+16>>2]);return bufferCopyView},makePassTimestampWrites:ptr=>{if(ptr===0)return undefined;return{querySet:WebGPU.getJsObject(HEAPU32[ptr+4>>2]),beginningOfPassWriteIndex:HEAPU32[ptr+8>>2],endOfPassWriteIndex:HEAPU32[ptr+12>>2]}},makePipelineConstants:(constantCount,constantsPtr)=>{if(!constantCount)return;var constants={};for(var i=0;i>3]}return constants},makePipelineLayout:layoutPtr=>{if(!layoutPtr)return"auto";return WebGPU.getJsObject(layoutPtr)},makeComputeState:ptr=>{if(!ptr)return undefined;var desc={module:WebGPU.getJsObject(HEAPU32[ptr+4>>2]),constants:WebGPU.makePipelineConstants(HEAPU32[ptr+16>>2],HEAPU32[ptr+20>>2]),entryPoint:WebGPU.makeStringFromOptionalStringView(ptr+8)};return desc},makeComputePipelineDesc:descriptor=>{var desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4),layout:WebGPU.makePipelineLayout(HEAPU32[descriptor+12>>2]),compute:WebGPU.makeComputeState(descriptor+16)};return desc},makeRenderPipelineDesc:descriptor=>{function makePrimitiveState(psPtr){if(!psPtr)return undefined;return{topology:WebGPU.PrimitiveTopology[HEAP32[psPtr+4>>2]],stripIndexFormat:WebGPU.IndexFormat[HEAP32[psPtr+8>>2]],frontFace:WebGPU.FrontFace[HEAP32[psPtr+12>>2]],cullMode:WebGPU.CullMode[HEAP32[psPtr+16>>2]],unclippedDepth:!!HEAPU32[psPtr+20>>2]}}function makeBlendComponent(bdPtr){if(!bdPtr)return undefined;return{operation:WebGPU.BlendOperation[HEAP32[bdPtr>>2]],srcFactor:WebGPU.BlendFactor[HEAP32[bdPtr+4>>2]],dstFactor:WebGPU.BlendFactor[HEAP32[bdPtr+8>>2]]}}function makeBlendState(bsPtr){if(!bsPtr)return undefined;return{alpha:makeBlendComponent(bsPtr+12),color:makeBlendComponent(bsPtr+0)}}function makeColorState(csPtr){var format=WebGPU.TextureFormat[HEAP32[csPtr+4>>2]];return format?{format,blend:makeBlendState(HEAPU32[csPtr+8>>2]),writeMask:HEAPU32[csPtr+16>>2]}:undefined}function makeColorStates(count,csArrayPtr){var states=[];for(var i=0;i>2]],failOp:WebGPU.StencilOperation[HEAP32[ssfPtr+4>>2]],depthFailOp:WebGPU.StencilOperation[HEAP32[ssfPtr+8>>2]],passOp:WebGPU.StencilOperation[HEAP32[ssfPtr+12>>2]]}}function makeDepthStencilState(dssPtr){if(!dssPtr)return undefined;return{format:WebGPU.TextureFormat[HEAP32[dssPtr+4>>2]],depthWriteEnabled:!!HEAPU32[dssPtr+8>>2],depthCompare:WebGPU.CompareFunction[HEAP32[dssPtr+12>>2]],stencilFront:makeStencilStateFace(dssPtr+16),stencilBack:makeStencilStateFace(dssPtr+32),stencilReadMask:HEAPU32[dssPtr+48>>2],stencilWriteMask:HEAPU32[dssPtr+52>>2],depthBias:HEAP32[dssPtr+56>>2],depthBiasSlopeScale:HEAPF32[dssPtr+60>>2],depthBiasClamp:HEAPF32[dssPtr+64>>2]}}function makeVertexAttribute(vaPtr){return{format:WebGPU.VertexFormat[HEAP32[vaPtr+4>>2]],offset:readI53FromI64(vaPtr+8),shaderLocation:HEAPU32[vaPtr+16>>2]}}function makeVertexAttributes(count,vaArrayPtr){var vas=[];for(var i=0;i>2]];var attributeCount=HEAPU32[vbPtr+16>>2];if(!stepMode&&!attributeCount){return null}return{arrayStride:readI53FromI64(vbPtr+8),stepMode,attributes:makeVertexAttributes(attributeCount,HEAPU32[vbPtr+20>>2])}}function makeVertexBuffers(count,vbArrayPtr){if(!count)return undefined;var vbs=[];for(var i=0;i>2]),constants:WebGPU.makePipelineConstants(HEAPU32[viPtr+16>>2],HEAPU32[viPtr+20>>2]),buffers:makeVertexBuffers(HEAPU32[viPtr+24>>2],HEAPU32[viPtr+28>>2]),entryPoint:WebGPU.makeStringFromOptionalStringView(viPtr+8)};return desc}function makeMultisampleState(msPtr){if(!msPtr)return undefined;return{count:HEAPU32[msPtr+4>>2],mask:HEAPU32[msPtr+8>>2],alphaToCoverageEnabled:!!HEAPU32[msPtr+12>>2]}}function makeFragmentState(fsPtr){if(!fsPtr)return undefined;var desc={module:WebGPU.getJsObject(HEAPU32[fsPtr+4>>2]),constants:WebGPU.makePipelineConstants(HEAPU32[fsPtr+16>>2],HEAPU32[fsPtr+20>>2]),targets:makeColorStates(HEAPU32[fsPtr+24>>2],HEAPU32[fsPtr+28>>2]),entryPoint:WebGPU.makeStringFromOptionalStringView(fsPtr+8)};return desc}var desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4),layout:WebGPU.makePipelineLayout(HEAPU32[descriptor+12>>2]),vertex:makeVertexState(descriptor+16),primitive:makePrimitiveState(descriptor+48),depthStencil:makeDepthStencilState(HEAPU32[descriptor+72>>2]),multisample:makeMultisampleState(descriptor+76),fragment:makeFragmentState(HEAPU32[descriptor+92>>2])};return desc},fillLimitStruct:(limits,limitsOutPtr)=>{var nextInChainPtr=HEAPU32[limitsOutPtr>>2];function setLimitValueU32(name,basePtr,limitOffset,fallbackValue=0){var limitValue=limits[name]??fallbackValue;HEAPU32[basePtr+limitOffset>>2]=limitValue}function setLimitValueU64(name,basePtr,limitOffset,fallbackValue=0){var limitValue=limits[name]??fallbackValue;writeI53ToI64(basePtr+limitOffset,limitValue)}setLimitValueU32("maxTextureDimension1D",limitsOutPtr,4);setLimitValueU32("maxTextureDimension2D",limitsOutPtr,8);setLimitValueU32("maxTextureDimension3D",limitsOutPtr,12);setLimitValueU32("maxTextureArrayLayers",limitsOutPtr,16);setLimitValueU32("maxBindGroups",limitsOutPtr,20);setLimitValueU32("maxBindGroupsPlusVertexBuffers",limitsOutPtr,24);setLimitValueU32("maxBindingsPerBindGroup",limitsOutPtr,28);setLimitValueU32("maxDynamicUniformBuffersPerPipelineLayout",limitsOutPtr,32);setLimitValueU32("maxDynamicStorageBuffersPerPipelineLayout",limitsOutPtr,36);setLimitValueU32("maxSampledTexturesPerShaderStage",limitsOutPtr,40);setLimitValueU32("maxSamplersPerShaderStage",limitsOutPtr,44);setLimitValueU32("maxStorageBuffersPerShaderStage",limitsOutPtr,48);setLimitValueU32("maxStorageTexturesPerShaderStage",limitsOutPtr,52);setLimitValueU32("maxUniformBuffersPerShaderStage",limitsOutPtr,56);setLimitValueU32("minUniformBufferOffsetAlignment",limitsOutPtr,80);setLimitValueU32("minStorageBufferOffsetAlignment",limitsOutPtr,84);setLimitValueU64("maxUniformBufferBindingSize",limitsOutPtr,64);setLimitValueU64("maxStorageBufferBindingSize",limitsOutPtr,72);setLimitValueU32("maxVertexBuffers",limitsOutPtr,88);setLimitValueU64("maxBufferSize",limitsOutPtr,96);setLimitValueU32("maxVertexAttributes",limitsOutPtr,104);setLimitValueU32("maxVertexBufferArrayStride",limitsOutPtr,108);setLimitValueU32("maxInterStageShaderVariables",limitsOutPtr,112);setLimitValueU32("maxColorAttachments",limitsOutPtr,116);setLimitValueU32("maxColorAttachmentBytesPerSample",limitsOutPtr,120);setLimitValueU32("maxComputeWorkgroupStorageSize",limitsOutPtr,124);setLimitValueU32("maxComputeInvocationsPerWorkgroup",limitsOutPtr,128);setLimitValueU32("maxComputeWorkgroupSizeX",limitsOutPtr,132);setLimitValueU32("maxComputeWorkgroupSizeY",limitsOutPtr,136);setLimitValueU32("maxComputeWorkgroupSizeZ",limitsOutPtr,140);setLimitValueU32("maxComputeWorkgroupsPerDimension",limitsOutPtr,144);setLimitValueU32("maxImmediateSize",limitsOutPtr,148);if(nextInChainPtr!==0){var sType=HEAP32[nextInChainPtr+4>>2];var compatibilityModeLimitsPtr=nextInChainPtr;setLimitValueU32("maxStorageBuffersInVertexStage",compatibilityModeLimitsPtr,8,limits.maxStorageBuffersPerShaderStage);setLimitValueU32("maxStorageBuffersInFragmentStage",compatibilityModeLimitsPtr,16,limits.maxStorageBuffersPerShaderStage);setLimitValueU32("maxStorageTexturesInVertexStage",compatibilityModeLimitsPtr,12,limits.maxStorageTexturesPerShaderStage);setLimitValueU32("maxStorageTexturesInFragmentStage",compatibilityModeLimitsPtr,20,limits.maxStorageTexturesPerShaderStage)}},fillAdapterInfoStruct:(info,infoStruct)=>{HEAPU32[infoStruct+52>>2]=info.subgroupMinSize;HEAPU32[infoStruct+56>>2]=info.subgroupMaxSize;var strs=info.vendor+info.architecture+info.device+info.description;var strPtr=stringToNewUTF8(strs);var vendorLen=lengthBytesUTF8(info.vendor);WebGPU.setStringView(infoStruct+4,strPtr,vendorLen);strPtr+=vendorLen;var architectureLen=lengthBytesUTF8(info.architecture);WebGPU.setStringView(infoStruct+12,strPtr,architectureLen);strPtr+=architectureLen;var deviceLen=lengthBytesUTF8(info.device);WebGPU.setStringView(infoStruct+20,strPtr,deviceLen);strPtr+=deviceLen;var descriptionLen=lengthBytesUTF8(info.description);WebGPU.setStringView(infoStruct+28,strPtr,descriptionLen);strPtr+=descriptionLen;HEAP32[infoStruct+36>>2]=2;var adapterType=info.isFallbackAdapter?3:4;HEAP32[infoStruct+40>>2]=adapterType;HEAPU32[infoStruct+44>>2]=0;HEAPU32[infoStruct+48>>2]=0},AddressMode:[,"clamp-to-edge","repeat","mirror-repeat"],BlendFactor:[,"zero","one","src","one-minus-src","src-alpha","one-minus-src-alpha","dst","one-minus-dst","dst-alpha","one-minus-dst-alpha","src-alpha-saturated","constant","one-minus-constant","src1","one-minus-src1","src1-alpha","one-minus-src1-alpha"],BlendOperation:[,"add","subtract","reverse-subtract","min","max"],BufferBindingType:[,,"uniform","storage","read-only-storage"],BufferMapState:[,"unmapped","pending","mapped"],CompareFunction:[,"never","less","equal","less-equal","greater","not-equal","greater-equal","always"],CompilationInfoRequestStatus:[,"success","callback-cancelled"],ComponentSwizzle:[,"0","1","r","g","b","a"],CompositeAlphaMode:[,"opaque","premultiplied","unpremultiplied","inherit"],CullMode:[,"none","front","back"],ErrorFilter:[,"validation","out-of-memory","internal"],FeatureLevel:[,"compatibility","core"],FeatureName:{1:"core-features-and-limits",2:"depth-clip-control",3:"depth32float-stencil8",4:"texture-compression-bc",5:"texture-compression-bc-sliced-3d",6:"texture-compression-etc2",7:"texture-compression-astc",8:"texture-compression-astc-sliced-3d",9:"timestamp-query",10:"indirect-first-instance",11:"shader-f16",12:"rg11b10ufloat-renderable",13:"bgra8unorm-storage",14:"float32-filterable",15:"float32-blendable",16:"clip-distances",17:"dual-source-blending",18:"subgroups",19:"texture-formats-tier1",20:"texture-formats-tier2",21:"primitive-index",22:"texture-component-swizzle",327692:"chromium-experimental-unorm16-texture-formats",327729:"chromium-experimental-multi-draw-indirect"},FilterMode:[,"nearest","linear"],FrontFace:[,"ccw","cw"],IndexFormat:[,"uint16","uint32"],InstanceFeatureName:[,"timed-wait-any","shader-source-spirv","multiple-devices-per-adapter"],LoadOp:[,"load","clear"],MipmapFilterMode:[,"nearest","linear"],OptionalBool:["false","true"],PowerPreference:[,"low-power","high-performance"],PredefinedColorSpace:[,"srgb","display-p3"],PrimitiveTopology:[,"point-list","line-list","line-strip","triangle-list","triangle-strip"],QueryType:[,"occlusion","timestamp"],SamplerBindingType:[,,"filtering","non-filtering","comparison"],Status:[,"success","error"],StencilOperation:[,"keep","zero","replace","invert","increment-clamp","decrement-clamp","increment-wrap","decrement-wrap"],StorageTextureAccess:[,,"write-only","read-only","read-write"],StoreOp:[,"store","discard"],SurfaceGetCurrentTextureStatus:[,"success-optimal","success-suboptimal","timeout","outdated","lost","error"],TextureAspect:[,"all","stencil-only","depth-only"],TextureDimension:[,"1d","2d","3d"],TextureFormat:[,"r8unorm","r8snorm","r8uint","r8sint","r16unorm","r16snorm","r16uint","r16sint","r16float","rg8unorm","rg8snorm","rg8uint","rg8sint","r32float","r32uint","r32sint","rg16unorm","rg16snorm","rg16uint","rg16sint","rg16float","rgba8unorm","rgba8unorm-srgb","rgba8snorm","rgba8uint","rgba8sint","bgra8unorm","bgra8unorm-srgb","rgb10a2uint","rgb10a2unorm","rg11b10ufloat","rgb9e5ufloat","rg32float","rg32uint","rg32sint","rgba16unorm","rgba16snorm","rgba16uint","rgba16sint","rgba16float","rgba32float","rgba32uint","rgba32sint","stencil8","depth16unorm","depth24plus","depth24plus-stencil8","depth32float","depth32float-stencil8","bc1-rgba-unorm","bc1-rgba-unorm-srgb","bc2-rgba-unorm","bc2-rgba-unorm-srgb","bc3-rgba-unorm","bc3-rgba-unorm-srgb","bc4-r-unorm","bc4-r-snorm","bc5-rg-unorm","bc5-rg-snorm","bc6h-rgb-ufloat","bc6h-rgb-float","bc7-rgba-unorm","bc7-rgba-unorm-srgb","etc2-rgb8unorm","etc2-rgb8unorm-srgb","etc2-rgb8a1unorm","etc2-rgb8a1unorm-srgb","etc2-rgba8unorm","etc2-rgba8unorm-srgb","eac-r11unorm","eac-r11snorm","eac-rg11unorm","eac-rg11snorm","astc-4x4-unorm","astc-4x4-unorm-srgb","astc-5x4-unorm","astc-5x4-unorm-srgb","astc-5x5-unorm","astc-5x5-unorm-srgb","astc-6x5-unorm","astc-6x5-unorm-srgb","astc-6x6-unorm","astc-6x6-unorm-srgb","astc-8x5-unorm","astc-8x5-unorm-srgb","astc-8x6-unorm","astc-8x6-unorm-srgb","astc-8x8-unorm","astc-8x8-unorm-srgb","astc-10x5-unorm","astc-10x5-unorm-srgb","astc-10x6-unorm","astc-10x6-unorm-srgb","astc-10x8-unorm","astc-10x8-unorm-srgb","astc-10x10-unorm","astc-10x10-unorm-srgb","astc-12x10-unorm","astc-12x10-unorm-srgb","astc-12x12-unorm","astc-12x12-unorm-srgb"],TextureSampleType:[,,"float","unfilterable-float","depth","sint","uint"],TextureViewDimension:[,"1d","2d","2d-array","cube","cube-array","3d"],ToneMappingMode:[,"standard","extended"],VertexFormat:[,"uint8","uint8x2","uint8x4","sint8","sint8x2","sint8x4","unorm8","unorm8x2","unorm8x4","snorm8","snorm8x2","snorm8x4","uint16","uint16x2","uint16x4","sint16","sint16x2","sint16x4","unorm16","unorm16x2","unorm16x4","snorm16","snorm16x2","snorm16x4","float16","float16x2","float16x4","float32","float32x2","float32x3","float32x4","uint32","uint32x2","uint32x3","uint32x4","sint32","sint32x2","sint32x3","sint32x4","unorm10-10-10-2","unorm8x4-bgra"],VertexStepMode:[,"vertex","instance"],WGSLLanguageFeatureName:[,"readonly_and_readwrite_storage_textures","packed_4x8_integer_dot_product","unrestricted_pointer_parameters","pointer_composite_access","uniform_buffer_standard_layout","subgroup_id","texture_and_sampler_let","subgroup_uniformity","texture_formats_tier1","linear_indexing"]};var emwgpuStringToInt_DeviceLostReason={undefined:1,unknown:1,destroyed:2};var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;var maybeExit=()=>{if(!keepRuntimeAlive()){try{_exit(EXITSTATUS)}catch(e){handleException(e)}}};var callUserCallback=func=>{if(ABORT){return}try{return func()}catch(e){handleException(e)}finally{maybeExit()}};var INT53_MAX=9007199254740992;var INT53_MIN=-9007199254740992;var bigintToI53Checked=num=>numINT53_MAX?NaN:Number(num);function _emwgpuAdapterRequestDevice(adapterPtr,futureId,deviceLostFutureId,devicePtr,queuePtr,descriptor){futureId=bigintToI53Checked(futureId);deviceLostFutureId=bigintToI53Checked(deviceLostFutureId);var adapter=WebGPU.getJsObject(adapterPtr);var desc={};if(descriptor){var requiredFeatureCount=HEAPU32[descriptor+12>>2];if(requiredFeatureCount){var requiredFeaturesPtr=HEAPU32[descriptor+16>>2];desc["requiredFeatures"]=Array.from(HEAPU32.subarray(requiredFeaturesPtr>>2,requiredFeaturesPtr+requiredFeatureCount*4>>2),feature=>WebGPU.FeatureName[feature])}var limitsPtr=HEAPU32[descriptor+20>>2];if(limitsPtr){var nextInChainPtr=HEAPU32[limitsPtr>>2];var requiredLimits={};function setLimitU32IfDefined(name,basePtr,limitOffset,ignoreIfZero=false){var ptr=basePtr+limitOffset;var value=HEAPU32[ptr>>2];if(value!=4294967295&&(!ignoreIfZero||value!=0)){requiredLimits[name]=value}}function setLimitU64IfDefined(name,basePtr,limitOffset){var ptr=basePtr+limitOffset;var limitPart1=HEAPU32[ptr>>2];var limitPart2=HEAPU32[ptr+4>>2];if(limitPart1!=4294967295||limitPart2!=4294967295){requiredLimits[name]=readI53FromI64(ptr)}}setLimitU32IfDefined("maxTextureDimension1D",limitsPtr,4);setLimitU32IfDefined("maxTextureDimension2D",limitsPtr,8);setLimitU32IfDefined("maxTextureDimension3D",limitsPtr,12);setLimitU32IfDefined("maxTextureArrayLayers",limitsPtr,16);setLimitU32IfDefined("maxBindGroups",limitsPtr,20);setLimitU32IfDefined("maxBindGroupsPlusVertexBuffers",limitsPtr,24);setLimitU32IfDefined("maxBindingsPerBindGroup",limitsPtr,28);setLimitU32IfDefined("maxDynamicUniformBuffersPerPipelineLayout",limitsPtr,32);setLimitU32IfDefined("maxDynamicStorageBuffersPerPipelineLayout",limitsPtr,36);setLimitU32IfDefined("maxSampledTexturesPerShaderStage",limitsPtr,40);setLimitU32IfDefined("maxSamplersPerShaderStage",limitsPtr,44);setLimitU32IfDefined("maxStorageBuffersPerShaderStage",limitsPtr,48);setLimitU32IfDefined("maxStorageTexturesPerShaderStage",limitsPtr,52);setLimitU32IfDefined("maxUniformBuffersPerShaderStage",limitsPtr,56);setLimitU32IfDefined("minUniformBufferOffsetAlignment",limitsPtr,80);setLimitU32IfDefined("minStorageBufferOffsetAlignment",limitsPtr,84);setLimitU64IfDefined("maxUniformBufferBindingSize",limitsPtr,64);setLimitU64IfDefined("maxStorageBufferBindingSize",limitsPtr,72);setLimitU32IfDefined("maxVertexBuffers",limitsPtr,88);setLimitU64IfDefined("maxBufferSize",limitsPtr,96);setLimitU32IfDefined("maxVertexAttributes",limitsPtr,104);setLimitU32IfDefined("maxVertexBufferArrayStride",limitsPtr,108);setLimitU32IfDefined("maxInterStageShaderVariables",limitsPtr,112);setLimitU32IfDefined("maxColorAttachments",limitsPtr,116);setLimitU32IfDefined("maxColorAttachmentBytesPerSample",limitsPtr,120);setLimitU32IfDefined("maxComputeWorkgroupStorageSize",limitsPtr,124);setLimitU32IfDefined("maxComputeInvocationsPerWorkgroup",limitsPtr,128);setLimitU32IfDefined("maxComputeWorkgroupSizeX",limitsPtr,132);setLimitU32IfDefined("maxComputeWorkgroupSizeY",limitsPtr,136);setLimitU32IfDefined("maxComputeWorkgroupSizeZ",limitsPtr,140);setLimitU32IfDefined("maxComputeWorkgroupsPerDimension",limitsPtr,144);setLimitU32IfDefined("maxImmediateSize",limitsPtr,148,true);if(nextInChainPtr!==0){var sType=HEAP32[nextInChainPtr+4>>2];var compatibilityModeLimitsPtr=nextInChainPtr;if("maxStorageBuffersInVertexStage"in GPUSupportedLimits.prototype){setLimitU32IfDefined("maxStorageBuffersInVertexStage",compatibilityModeLimitsPtr,8);setLimitU32IfDefined("maxStorageTexturesInVertexStage",compatibilityModeLimitsPtr,12);setLimitU32IfDefined("maxStorageBuffersInFragmentStage",compatibilityModeLimitsPtr,16);setLimitU32IfDefined("maxStorageTexturesInFragmentStage",compatibilityModeLimitsPtr,20)}}desc["requiredLimits"]=requiredLimits}var defaultQueuePtr=HEAPU32[descriptor+24>>2];if(defaultQueuePtr){var defaultQueueDesc={label:WebGPU.makeStringFromOptionalStringView(defaultQueuePtr+4)};desc["defaultQueue"]=defaultQueueDesc}desc["label"]=WebGPU.makeStringFromOptionalStringView(descriptor+4)}WebGPU.Internals.futureInsert(futureId,adapter.requestDevice(desc).then(device=>{callUserCallback(()=>{WebGPU.Internals.jsObjectInsert(queuePtr,device.queue);WebGPU.Internals.jsObjectInsert(devicePtr,device);WebGPU.Internals.futureInsert(deviceLostFutureId,device.lost.then(info=>{callUserCallback(()=>{device.onuncapturederror=ev=>{};var sp=stackSave();var messagePtr=stringToUTF8OnStack(info.message);_emwgpuOnDeviceLostCompleted(deviceLostFutureId,emwgpuStringToInt_DeviceLostReason[info.reason],messagePtr);stackRestore(sp)})}));device.onuncapturederror=ev=>{var type=5;if(ev.error instanceof GPUValidationError)type=2;else if(ev.error instanceof GPUOutOfMemoryError)type=3;else if(ev.error instanceof GPUInternalError)type=4;var sp=stackSave();var messagePtr=stringToUTF8OnStack(ev.error.message);_emwgpuOnUncapturedError(devicePtr,type,messagePtr);stackRestore(sp)};_emwgpuOnRequestDeviceCompleted(futureId,1,devicePtr,0)})},ex=>{callUserCallback(()=>{var sp=stackSave();var messagePtr=stringToUTF8OnStack(ex.message);_emwgpuOnRequestDeviceCompleted(futureId,3,devicePtr,messagePtr);if(deviceLostFutureId){_emwgpuOnDeviceLostCompleted(deviceLostFutureId,4,messagePtr)}stackRestore(sp)})}))}var _emwgpuDelete=ptr=>{delete WebGPU.Internals.jsObjects[ptr]};var _emwgpuDeviceCreateBuffer=(devicePtr,descriptor,bufferPtr)=>{var mappedAtCreation=!!HEAPU32[descriptor+32>>2];var desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4),usage:HEAPU32[descriptor+16>>2],size:readI53FromI64(descriptor+24),mappedAtCreation};var device=WebGPU.getJsObject(devicePtr);var buffer;try{buffer=device.createBuffer(desc)}catch(ex){return false}WebGPU.Internals.jsObjectInsert(bufferPtr,buffer);if(mappedAtCreation){WebGPU.Internals.bufferOnUnmaps[bufferPtr]=[]}return true};var _emwgpuDeviceCreateShaderModule=(devicePtr,descriptor,shaderModulePtr)=>{var nextInChainPtr=HEAPU32[descriptor>>2];var sType=HEAP32[nextInChainPtr+4>>2];var desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4),code:""};switch(sType){case 2:{desc["code"]=WebGPU.makeStringFromStringView(nextInChainPtr+8);break}}var device=WebGPU.getJsObject(devicePtr);WebGPU.Internals.jsObjectInsert(shaderModulePtr,device.createShaderModule(desc))};var _emwgpuDeviceDestroy=devicePtr=>{const device=WebGPU.getJsObject(devicePtr);device.onuncapturederror=null;device.destroy()};function _emwgpuInstanceRequestAdapter(instancePtr,futureId,options,adapterPtr){futureId=bigintToI53Checked(futureId);var opts;if(options){opts={featureLevel:WebGPU.FeatureLevel[HEAP32[options+4>>2]],powerPreference:WebGPU.PowerPreference[HEAP32[options+8>>2]],forceFallbackAdapter:!!HEAPU32[options+12>>2]};var nextInChainPtr=HEAPU32[options>>2];if(nextInChainPtr!==0){var sType=HEAP32[nextInChainPtr+4>>2];var webxrOptions=nextInChainPtr;opts.xrCompatible=!!HEAPU32[webxrOptions+8>>2]}}if(!("gpu"in navigator)){var sp=stackSave();var messagePtr=stringToUTF8OnStack("WebGPU not available on this browser (navigator.gpu is not available)");_emwgpuOnRequestAdapterCompleted(futureId,3,adapterPtr,messagePtr);stackRestore(sp);return}WebGPU.Internals.futureInsert(futureId,navigator.gpu.requestAdapter(opts).then(adapter=>{callUserCallback(()=>{if(adapter){WebGPU.Internals.jsObjectInsert(adapterPtr,adapter);_emwgpuOnRequestAdapterCompleted(futureId,1,adapterPtr,0)}else{var sp=stackSave();var messagePtr=stringToUTF8OnStack("WebGPU not available on this browser (requestAdapter returned null)");_emwgpuOnRequestAdapterCompleted(futureId,3,adapterPtr,messagePtr);stackRestore(sp)}})},ex=>{callUserCallback(()=>{var sp=stackSave();var messagePtr=stringToUTF8OnStack(ex.message);_emwgpuOnRequestAdapterCompleted(futureId,4,adapterPtr,messagePtr);stackRestore(sp)})}))}var printCharBuffers=[null,[],[]];var printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer));buffer.length=0}else{buffer.push(curr)}};var _fd_write=(fd,iov,iovcnt,pnum)=>{var num=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0};var _wgpuCommandEncoderBeginRenderPass=(encoderPtr,descriptor)=>{function makeColorAttachment(caPtr){var viewPtr=HEAPU32[caPtr+4>>2];if(viewPtr===0){return undefined}var depthSlice=HEAPU32[caPtr+8>>2];if(depthSlice==4294967295)depthSlice=undefined;return{view:WebGPU.getJsObject(viewPtr),depthSlice,resolveTarget:WebGPU.getJsObject(HEAPU32[caPtr+12>>2]),clearValue:WebGPU.makeColor(caPtr+24),loadOp:WebGPU.LoadOp[HEAP32[caPtr+16>>2]],storeOp:WebGPU.StoreOp[HEAP32[caPtr+20>>2]]}}function makeColorAttachments(count,caPtr){var attachments=[];for(var i=0;i>2]),depthClearValue:HEAPF32[dsaPtr+16>>2],depthLoadOp:WebGPU.LoadOp[HEAP32[dsaPtr+8>>2]],depthStoreOp:WebGPU.StoreOp[HEAP32[dsaPtr+12>>2]],depthReadOnly:!!HEAPU32[dsaPtr+20>>2],stencilClearValue:HEAPU32[dsaPtr+32>>2],stencilLoadOp:WebGPU.LoadOp[HEAP32[dsaPtr+24>>2]],stencilStoreOp:WebGPU.StoreOp[HEAP32[dsaPtr+28>>2]],stencilReadOnly:!!HEAPU32[dsaPtr+36>>2]}}function makeRenderPassDescriptor(descriptor){var nextInChainPtr=HEAPU32[descriptor>>2];var maxDrawCount=undefined;if(nextInChainPtr!==0){var sType=HEAP32[nextInChainPtr+4>>2];var renderPassMaxDrawCount=nextInChainPtr;maxDrawCount=readI53FromI64(renderPassMaxDrawCount+8)}var desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4),colorAttachments:makeColorAttachments(HEAPU32[descriptor+12>>2],HEAPU32[descriptor+16>>2]),depthStencilAttachment:makeDepthStencilAttachment(HEAPU32[descriptor+20>>2]),occlusionQuerySet:WebGPU.getJsObject(HEAPU32[descriptor+24>>2]),timestampWrites:WebGPU.makePassTimestampWrites(HEAPU32[descriptor+28>>2]),maxDrawCount};return desc}var desc=makeRenderPassDescriptor(descriptor);var commandEncoder=WebGPU.getJsObject(encoderPtr);var ptr=_emwgpuCreateRenderPassEncoder(0);WebGPU.Internals.jsObjectInsert(ptr,commandEncoder.beginRenderPass(desc));return ptr};var _wgpuCommandEncoderFinish=(encoderPtr,descriptor)=>{var commandEncoder=WebGPU.getJsObject(encoderPtr);var ptr=_emwgpuCreateCommandBuffer(0);WebGPU.Internals.jsObjectInsert(ptr,commandEncoder.finish());return ptr};var _wgpuDeviceCreateCommandEncoder=(devicePtr,descriptor)=>{var desc;if(descriptor){desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4)}}var device=WebGPU.getJsObject(devicePtr);var ptr=_emwgpuCreateCommandEncoder(0);WebGPU.Internals.jsObjectInsert(ptr,device.createCommandEncoder(desc));return ptr};var _wgpuDeviceCreatePipelineLayout=(devicePtr,descriptor)=>{var bglCount=HEAPU32[descriptor+12>>2];var bglPtr=HEAPU32[descriptor+16>>2];var bgls=[];for(var i=0;i>2]))}var desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4),bindGroupLayouts:bgls};var device=WebGPU.getJsObject(devicePtr);var ptr=_emwgpuCreatePipelineLayout(0);WebGPU.Internals.jsObjectInsert(ptr,device.createPipelineLayout(desc));return ptr};var _wgpuDeviceCreateRenderPipeline=(devicePtr,descriptor)=>{var desc=WebGPU.makeRenderPipelineDesc(descriptor);var device=WebGPU.getJsObject(devicePtr);var ptr=_emwgpuCreateRenderPipeline(0);WebGPU.Internals.jsObjectInsert(ptr,device.createRenderPipeline(desc));return ptr};var maybeCStringToJsString=cString=>cString>2?UTF8ToString(cString):cString;var specialHTMLTargets=[0,globalThis.document??0,globalThis.window??0];var findEventTarget=target=>{target=maybeCStringToJsString(target);var domElement=specialHTMLTargets[target]||globalThis.document?.querySelector(target);return domElement};var findCanvasEventTarget=findEventTarget;var _wgpuInstanceCreateSurface=(instancePtr,descriptor)=>{var nextInChainPtr=HEAPU32[descriptor>>2];var sourceCanvasHTMLSelector=nextInChainPtr;var selectorPtr=HEAPU32[sourceCanvasHTMLSelector+8>>2];var canvas=findCanvasEventTarget(selectorPtr);var context=canvas.getContext("webgpu");if(!context)return 0;context.surfaceLabelWebGPU=WebGPU.makeStringFromOptionalStringView(descriptor+4);var ptr=_emwgpuCreateSurface(0);WebGPU.Internals.jsObjectInsert(ptr,context);return ptr};var _wgpuQueueSubmit=(queuePtr,commandCount,commands)=>{var queue=WebGPU.getJsObject(queuePtr);var cmds=Array.from(HEAP32.subarray(commands>>2,commands+commandCount*4>>2),id=>WebGPU.getJsObject(id));queue.submit(cmds)};function _wgpuQueueWriteBuffer(queuePtr,bufferPtr,bufferOffset,data,size){bufferOffset=bigintToI53Checked(bufferOffset);var queue=WebGPU.getJsObject(queuePtr);var buffer=WebGPU.getJsObject(bufferPtr);var subarray=HEAPU8.subarray(data,data+size);queue.writeBuffer(buffer,bufferOffset,subarray,0,size)}var _wgpuRenderPassEncoderDrawIndexed=(passPtr,indexCount,instanceCount,firstIndex,baseVertex,firstInstance)=>{firstIndex>>>=0;firstInstance>>>=0;var pass=WebGPU.getJsObject(passPtr);pass.drawIndexed(indexCount,instanceCount,firstIndex,baseVertex,firstInstance)};var _wgpuRenderPassEncoderEnd=encoderPtr=>{var encoder=WebGPU.getJsObject(encoderPtr);encoder.end()};function _wgpuRenderPassEncoderSetIndexBuffer(passPtr,bufferPtr,format,offset,size){offset=bigintToI53Checked(offset);size=bigintToI53Checked(size);var pass=WebGPU.getJsObject(passPtr);var buffer=WebGPU.getJsObject(bufferPtr);if(size==-1)size=undefined;pass.setIndexBuffer(buffer,WebGPU.IndexFormat[format],offset,size)}var _wgpuRenderPassEncoderSetPipeline=(passPtr,pipelinePtr)=>{var pass=WebGPU.getJsObject(passPtr);var pipeline=WebGPU.getJsObject(pipelinePtr);pass.setPipeline(pipeline)};function _wgpuRenderPassEncoderSetVertexBuffer(passPtr,slot,bufferPtr,offset,size){offset=bigintToI53Checked(offset);size=bigintToI53Checked(size);var pass=WebGPU.getJsObject(passPtr);var buffer=WebGPU.getJsObject(bufferPtr);if(size==-1)size=undefined;pass.setVertexBuffer(slot,buffer,offset,size)}var _wgpuSurfaceConfigure=(surfacePtr,config)=>{var context=WebGPU.getJsObject(surfacePtr);var canvasSize=[HEAPU32[config+24>>2],HEAPU32[config+28>>2]];if(canvasSize[0]!==0){context["canvas"]["width"]=canvasSize[0]}if(canvasSize[1]!==0){context["canvas"]["height"]=canvasSize[1]}var configuration={device:WebGPU.getJsObject(HEAPU32[config+4>>2]),format:WebGPU.TextureFormat[HEAP32[config+8>>2]],usage:HEAPU32[config+16>>2],alphaMode:WebGPU.CompositeAlphaMode[HEAP32[config+40>>2]]};var viewFormatCount=HEAPU32[config+32>>2];if(viewFormatCount){var viewFormatsPtr=HEAPU32[config+36>>2];configuration["viewFormats"]=Array.from(HEAP32.subarray(viewFormatsPtr>>2,viewFormatsPtr+viewFormatCount*4>>2),format=>WebGPU.TextureFormat[format])}{var nextInChainPtr=HEAPU32[config>>2];if(nextInChainPtr!==0){var sType=HEAP32[nextInChainPtr+4>>2];var surfaceColorManagement=nextInChainPtr;configuration.colorSpace=WebGPU.PredefinedColorSpace[HEAP32[surfaceColorManagement+8>>2]];configuration.toneMapping={mode:WebGPU.ToneMappingMode[HEAP32[surfaceColorManagement+12>>2]]}}}context.configure(configuration)};var _wgpuSurfaceGetCurrentTexture=(surfacePtr,surfaceTexturePtr)=>{var context=WebGPU.getJsObject(surfacePtr);try{var texturePtr=_emwgpuCreateTexture(0);WebGPU.Internals.jsObjectInsert(texturePtr,context.getCurrentTexture());HEAPU32[surfaceTexturePtr+4>>2]=texturePtr;HEAP32[surfaceTexturePtr+8>>2]=1}catch(ex){HEAPU32[surfaceTexturePtr+4>>2]=0;HEAP32[surfaceTexturePtr+8>>2]=6}};var _wgpuTextureCreateView=(texturePtr,descriptor)=>{var desc;if(descriptor){var swizzle;var nextInChainPtr=HEAPU32[descriptor>>2];if(nextInChainPtr!==0){var sType=HEAP32[nextInChainPtr+4>>2];var swizzleDescriptor=nextInChainPtr;var swizzlePtr=swizzleDescriptor+8;var r=WebGPU.ComponentSwizzle[HEAP32[swizzlePtr>>2]]||"r";var g=WebGPU.ComponentSwizzle[HEAP32[swizzlePtr+4>>2]]||"g";var b=WebGPU.ComponentSwizzle[HEAP32[swizzlePtr+8>>2]]||"b";var a=WebGPU.ComponentSwizzle[HEAP32[swizzlePtr+12>>2]]||"a";swizzle=`${r}${g}${b}${a}`}var mipLevelCount=HEAPU32[descriptor+24>>2];var arrayLayerCount=HEAPU32[descriptor+32>>2];desc={label:WebGPU.makeStringFromOptionalStringView(descriptor+4),format:WebGPU.TextureFormat[HEAP32[descriptor+12>>2]],dimension:WebGPU.TextureViewDimension[HEAP32[descriptor+16>>2]],baseMipLevel:HEAPU32[descriptor+20>>2],mipLevelCount:mipLevelCount===4294967295?undefined:mipLevelCount,baseArrayLayer:HEAPU32[descriptor+28>>2],arrayLayerCount:arrayLayerCount===4294967295?undefined:arrayLayerCount,aspect:WebGPU.TextureAspect[HEAP32[descriptor+36>>2]],usage:HEAPU32[descriptor+40>>2],swizzle}}var texture=WebGPU.getJsObject(texturePtr);var ptr=_emwgpuCreateTextureView(0);WebGPU.Internals.jsObjectInsert(ptr,texture.createView(desc));return ptr};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])programArgs=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}function canvas_get_width(){return window.innerWidth}function canvas_get_height(){return window.innerHeight}var _main,_emwgpuCreateBindGroup,_emwgpuCreateBindGroupLayout,_emwgpuCreateCommandBuffer,_emwgpuCreateCommandEncoder,_emwgpuCreateComputePassEncoder,_emwgpuCreateComputePipeline,_emwgpuCreateExternalTexture,_emwgpuCreatePipelineLayout,_emwgpuCreateQuerySet,_emwgpuCreateRenderBundle,_emwgpuCreateRenderBundleEncoder,_emwgpuCreateRenderPassEncoder,_emwgpuCreateRenderPipeline,_emwgpuCreateSampler,_emwgpuCreateSurface,_emwgpuCreateTexture,_emwgpuCreateTextureView,_emwgpuCreateAdapter,_emwgpuImportBuffer,_emwgpuCreateDevice,_emwgpuCreateQueue,_emwgpuCreateShaderModule,_emwgpuOnDeviceLostCompleted,_emwgpuOnRequestAdapterCompleted,_emwgpuOnRequestDeviceCompleted,_emwgpuOnUncapturedError,_malloc,__emscripten_stack_restore,__emscripten_stack_alloc,_emscripten_stack_get_current,memory,__indirect_function_table,wasmMemory,wasmTable;function assignWasmExports(wasmExports){_main=Module["_main"]=wasmExports["E"];_emwgpuCreateBindGroup=wasmExports["G"];_emwgpuCreateBindGroupLayout=wasmExports["H"];_emwgpuCreateCommandBuffer=wasmExports["I"];_emwgpuCreateCommandEncoder=wasmExports["J"];_emwgpuCreateComputePassEncoder=wasmExports["K"];_emwgpuCreateComputePipeline=wasmExports["L"];_emwgpuCreateExternalTexture=wasmExports["M"];_emwgpuCreatePipelineLayout=wasmExports["N"];_emwgpuCreateQuerySet=wasmExports["O"];_emwgpuCreateRenderBundle=wasmExports["P"];_emwgpuCreateRenderBundleEncoder=wasmExports["Q"];_emwgpuCreateRenderPassEncoder=wasmExports["R"];_emwgpuCreateRenderPipeline=wasmExports["S"];_emwgpuCreateSampler=wasmExports["T"];_emwgpuCreateSurface=wasmExports["U"];_emwgpuCreateTexture=wasmExports["V"];_emwgpuCreateTextureView=wasmExports["W"];_emwgpuCreateAdapter=wasmExports["X"];_emwgpuImportBuffer=wasmExports["Y"];_emwgpuCreateDevice=wasmExports["Z"];_emwgpuCreateQueue=wasmExports["_"];_emwgpuCreateShaderModule=wasmExports["$"];_emwgpuOnDeviceLostCompleted=wasmExports["aa"];_emwgpuOnRequestAdapterCompleted=wasmExports["ba"];_emwgpuOnRequestDeviceCompleted=wasmExports["ca"];_emwgpuOnUncapturedError=wasmExports["da"];_malloc=wasmExports["ea"];__emscripten_stack_restore=wasmExports["fa"];__emscripten_stack_alloc=wasmExports["ga"];_emscripten_stack_get_current=wasmExports["ha"];memory=wasmMemory=wasmExports["C"];__indirect_function_table=wasmTable=wasmExports["F"]}var wasmImports={m:__abort_js,e:canvas_get_height,f:canvas_get_width,i:_emscripten_request_animation_frame_loop,l:_emscripten_resize_heap,q:_emwgpuAdapterRequestDevice,a:_emwgpuDelete,p:_emwgpuDeviceCreateBuffer,o:_emwgpuDeviceCreateShaderModule,r:_emwgpuDeviceDestroy,n:_emwgpuInstanceRequestAdapter,d:_fd_write,z:_wgpuCommandEncoderBeginRenderPass,t:_wgpuCommandEncoderFinish,A:_wgpuDeviceCreateCommandEncoder,k:_wgpuDeviceCreatePipelineLayout,j:_wgpuDeviceCreateRenderPipeline,B:_wgpuInstanceCreateSurface,s:_wgpuQueueSubmit,b:_wgpuQueueWriteBuffer,v:_wgpuRenderPassEncoderDrawIndexed,u:_wgpuRenderPassEncoderEnd,w:_wgpuRenderPassEncoderSetIndexBuffer,y:_wgpuRenderPassEncoderSetPipeline,x:_wgpuRenderPassEncoderSetVertexBuffer,c:_wgpuSurfaceConfigure,h:_wgpuSurfaceGetCurrentTexture,g:_wgpuTextureCreateView};function callMain(){var entryFunction=_main;var argc=0;var argv=0;try{var ret=entryFunction(argc,argv);exitJS(ret,true);return ret}catch(e){return handleException(e)}}async function run(){preRun();var setStatus=Module["setStatus"];if(setStatus){setStatus("Running...");await new Promise(resolve=>setTimeout(resolve,1));setTimeout(setStatus,1,"")}if(ABORT)return;initRuntime();preMain();Module["onRuntimeInitialized"]?.();var noInitialRun=Module["noInitialRun"]||false;if(!noInitialRun)callMain();postRun()}var wasmExports;createWasm().then(()=>run()); diff --git a/web/wasm_c/webgpu/triangle/index.wasm b/web/wasm_c/webgpu/triangle/index.wasm new file mode 100644 index 00000000..66ad020c Binary files /dev/null and b/web/wasm_c/webgpu/triangle/index.wasm differ diff --git a/web/wasm_c/webgpu/triangle/readme.md b/web/wasm_c/webgpu/triangle/readme.md new file mode 100644 index 00000000..1c4290e3 --- /dev/null +++ b/web/wasm_c/webgpu/triangle/readme.md @@ -0,0 +1,33 @@ +compile: +Please compile from `emsdk\emcmdprompt.bat`. +``` +emcc hello.c -std=c11 -s WASM=1 -O3 --use-port=emdawnwebgpu -o index.js + +``` +Result: +``` ++------------------------------------------+ +|Hello, World! [_][~][X]| ++------------------------------------------+ +| | +| / \ | +| / \ | +| / \ | +| / \ | +| / \ | +| / \ | +| / \ | +| / \ | +| - - - - - - - - - - - - - - - - - | ++------------------------------------------+ +``` +[Live Demo](https://cx20.github.io/hello/wasm_c/webgpu/triangle/) + +Caution: + +> Use Emscripten 4.0.10 or higher to compile (the built-in `emdawnwebgpu` port). +> +> This sample uses Dawn's `--use-port=emdawnwebgpu`, which provides the up-to-date +> `webgpu.h` C API (surface-based rendering, `WGPUStringView`, etc.). +> +> It runs in any browser with WebGPU enabled (e.g. recent Chrome / Edge). diff --git a/web/wasm_c/webgpu/triangle/style.css b/web/wasm_c/webgpu/triangle/style.css new file mode 100644 index 00000000..5be0b9c5 --- /dev/null +++ b/web/wasm_c/webgpu/triangle/style.css @@ -0,0 +1,10 @@ +* { + margin: 0; + padding: 0; + border: 0; + overflow: hidden; +} + +body { + background: #fff; +}