From 81c81f446cd26aaa828337e8a058287908e5103c Mon Sep 17 00:00:00 2001 From: kaizhangNV Date: Wed, 30 Oct 2024 20:52:21 -0700 Subject: [PATCH 1/4] add printf support --- build.mk | 4 + build/README.md | 43 +++ build/compiler.js | 478 ++++++++++++++++++++++++ build/compute.js | 203 ++++++++++ build/index.html | 235 ++++++++++++ build/language-server.js | 722 ++++++++++++++++++++++++++++++++++++ build/pass_through.js | 141 +++++++ build/playgoundShader.js | 83 +++++ build/playgroundShader.js | 83 +++++ build/spirv-tools.js | 19 + build/spirv-tools.wasm | Bin 0 -> 383130 bytes build/static/slang-logo.png | Bin 0 -> 32070 bytes build/styles/styles.css | 449 ++++++++++++++++++++++ build/try-slang.js | 520 ++++++++++++++++++++++++++ build/ui.js | 287 ++++++++++++++ build/util.js | 27 ++ build/utility_module.slang | 4 + build/water_demo.js | 235 ++++++++++++ compiler.js | 27 +- compute.js | 84 ++++- index.html | 1 + playgroundShader.js | 83 +++++ try-slang.js | 24 +- 23 files changed, 3725 insertions(+), 27 deletions(-) create mode 100644 build/README.md create mode 100644 build/compiler.js create mode 100644 build/compute.js create mode 100644 build/index.html create mode 100644 build/language-server.js create mode 100644 build/pass_through.js create mode 100644 build/playgoundShader.js create mode 100644 build/playgroundShader.js create mode 100644 build/spirv-tools.js create mode 100755 build/spirv-tools.wasm create mode 100644 build/static/slang-logo.png create mode 100644 build/styles/styles.css create mode 100644 build/try-slang.js create mode 100644 build/ui.js create mode 100644 build/util.js create mode 100644 build/utility_module.slang create mode 100644 build/water_demo.js create mode 100644 playgroundShader.js diff --git a/build.mk b/build.mk index 4ce3352..d05a683 100644 --- a/build.mk +++ b/build.mk @@ -48,6 +48,7 @@ website_runtime: $(TRY_SLANG_TARGET_DIRECTORY_PATH)/ui.js website_runtime: $(TRY_SLANG_TARGET_DIRECTORY_PATH)/styles website_runtime: $(TRY_SLANG_TARGET_DIRECTORY_PATH)/compiler.js website_runtime: $(TRY_SLANG_TARGET_DIRECTORY_PATH)/language-server.js +website_runtime: $(TRY_SLANG_TARGET_DIRECTORY_PATH)/playgroundShader.js .PHONY: $(TRY_SLANG_SLANG_SOURCE_DIRECTORY_PATH)/build.em/Release/bin/slang-wasm.js $(TRY_SLANG_SLANG_SOURCE_DIRECTORY_PATH)/build.em/Release/bin/slang-wasm.js $(TRY_SLANG_SLANG_SOURCE_DIRECTORY_PATH)/build.em/Release/bin/slang-wasm.wasm &: @@ -94,3 +95,6 @@ $(TRY_SLANG_TARGET_DIRECTORY_PATH)/compiler.js: $(TRY_SLANG_SOURCE_DIRECTORY_PAT $(TRY_SLANG_TARGET_DIRECTORY_PATH)/language-server.js: $(TRY_SLANG_SOURCE_DIRECTORY_PATH)/language-server.js $(COPY) $^ $@ + +$(TRY_SLANG_TARGET_DIRECTORY_PATH)/playgroundShader.js: $(TRY_SLANG_SOURCE_DIRECTORY_PATH)/playgroundShader.js + $(COPY) $^ $@ diff --git a/build/README.md b/build/README.md new file mode 100644 index 0000000..aca0f70 --- /dev/null +++ b/build/README.md @@ -0,0 +1,43 @@ +# SPIRV-Tools + +Wasm (WebAssembly) build of https://github.com/KhronosGroup/SPIRV-Tools + +## Usage + +```js +const spirvTools = require("spirv-tools"); + +const test = async () => { + // Load the library + const spv = await spirvTools(); + + // assemble + const source = ` + OpCapability Linkage + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpSource GLSL 450 + OpDecorate %spec SpecId 1 + %int = OpTypeInt 32 1 + %spec = OpSpecConstant %int 0 + %const = OpConstant %int 42`; + const asResult = spv.as( + source, + spv.SPV_ENV_UNIVERSAL_1_3, + spv.SPV_TEXT_TO_BINARY_OPTION_NONE + ); + console.log(`as returned ${asResult.byteLength} bytes`); + + // re-disassemble + const disResult = spv.dis( + asResult, + spv.SPV_ENV_UNIVERSAL_1_3, + spv.SPV_BINARY_TO_TEXT_OPTION_INDENT | + spv.SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | + spv.SPV_BINARY_TO_TEXT_OPTION_COLOR + ); + console.log("dis:\n", disResult); +}; + +test(); +``` diff --git a/build/compiler.js b/build/compiler.js new file mode 100644 index 0000000..9af2769 --- /dev/null +++ b/build/compiler.js @@ -0,0 +1,478 @@ +function isWholeProgramTarget(compileTarget) +{ + return compileTarget == "METAL" || compileTarget == "SPIRV"; +} + +const imageMainSource = ` +import user; +import playground; + +RWStructuredBuffer outputBuffer; +[format("r32f")] RWTexture2D texture; + +inline float encodeColor(float4 color) +{ + uint4 colorInt = { uint(color.x * 255.0f), + uint(color.y * 255.0f), + uint(color.z * 255.0f), + uint(color.w * 255.0f) }; + + float encodedColor = float(colorInt.x << 24 | colorInt.y << 16 | colorInt.z << 8 | colorInt.w); + return encodedColor; +} + +[shader("compute")] +[numthreads(16, 16, 1)] +void imageMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint width = 0; + uint height = 0; + texture.GetDimensions(width, height); + + if (dispatchThreadID.x >= width || dispatchThreadID.y >= height) + return; + + float4 color = imageMain(dispatchThreadID.xy, int2(width, height)); + float encodedColor = encodeColor(color); + + texture[dispatchThreadID.xy] = encodedColor; +} +`; + + +const printMainSource = ` +import user; +import playground; + +RWStructuredBuffer outputBuffer; +[format("r32f")] RWTexture2D texture; + +[shader("compute")] +[numthreads(1, 1, 1)] +void printMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int res = printMain(); + outputBuffer[0] = res; +} +`; + +const emptyImageShader = ` +import playground; + +float4 imageMain(uint2 dispatchThreadID, int2 screenSize) +{ + return float4(0); +} +`; + +const emptyPrintShader = ` +import playground; + +int printMain() +{ + print("%d\\n", 0); + return 0; +} +`; + + +class SlangCompiler +{ + static SLANG_STAGE_VERTEX = 1; + static SLANG_STAGE_FRAGMENT = 5; + static SLANG_STAGE_COMPUTE = 6; + + static RENDER_SHADER = 0; + static PRINT_SHADER = 1; + static NON_RUNNABLE_SHADER = 2; + + globalSlangSession = null; + slangSession = null; + + compileTargetMap = null; + + slangWasmModule; + diagnosticsMsg; + shaderType; + + spirvToolsModule = null; + + mainModules = new Map(); + + // store the string hash if appears in the shader code + hashedString = null; + + constructor(module) + { + this.slangWasmModule = module; + this.diagnosticsMsg = ""; + this.shaderType = SlangCompiler.NON_RUNNABLE_SHADER; + this.mainModules['imageMain'] = {source: imageMainSource}; + this.mainModules['printMain'] = {source: printMainSource}; + FS.createDataFile("/", "user.slang", "", true, true); + FS.createDataFile("/", "playground.slang", "", true, true); + } + + init() + { + try { + this.globalSlangSession = this.slangWasmModule.createGlobalSession(); + this.compileTargetMap = this.slangWasmModule.getCompileTargets(); + + if(!this.globalSlangSession || !this.compileTargetMap) + { + var error = this.slangWasmModule.getLastError(); + return {ret: false, msg: (error.type + " error: " + error.message)}; + } + else + { + return {ret: true, msg: ""}; + } + } catch (e) { + console.log(e); + return {ret: false, msg: '' + e}; + } + } + + // In our playground, we only allow to run shaders with two entry points: renderMain and printMain + findRunnableEntryPoint(module) + { + const runnableEntryPointNames = ['imageMain', 'printMain']; + for (var i = 0; i < runnableEntryPointNames.length; i++) + { + var entryPointName = runnableEntryPointNames[i]; + var entryPoint = module.findAndCheckEntryPoint(entryPointName, SlangCompiler.SLANG_STAGE_COMPUTE); + if(entryPoint) + { + if (i == 0) + this.shaderType = SlangCompiler.RENDER_SHADER; + else + this.shaderType = SlangCompiler.PRINT_SHADER; + return entryPoint; + } + } + + return null; + } + + findEntryPoint(module, entryPointName, stage) + { + if (entryPointName == null || entryPointName == "") + { + var entryPoint = this.findRunnableEntryPoint(module); + if (!entryPoint) + { + this.diagnosticsMsg += "Warning: The current shader code is not runnable because 'imageMain' or 'printMain' functions are not found.\n"; + this.diagnosticsMsg += "Use the 'Compile' button to compile it to different targets.\n"; + } + return entryPoint; + } + else + { + var entryPoint = module.findAndCheckEntryPoint(entryPointName, stage); + if(!entryPoint) { + var error = this.slangWasmModule.getLastError(); + console.error(error.type + " error: " + error.message); + this.diagnosticsMsg += (error.type + " error: " + error.message); + return null; + } + return entryPoint; + } + } + + async initSpirvTools() + { + if (!this.spirvToolsModule) + { + const spirvTools = BrowserCJS.require("./spirv-tools.js"); + this.spirvToolsModule = await spirvTools(); + } + } + + spirvDisassembly(spirvBinary) + { + const disAsmCode = this.spirvToolsModule.dis( + spirvBinary, + this.spirvToolsModule.SPV_ENV_UNIVERSAL_1_3, + this.spirvToolsModule.SPV_BINARY_TO_TEXT_OPTION_INDENT | + this.spirvToolsModule.SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES + ); + + + if (disAsmCode == "Error") + { + this.diagnosticsMsg += ("SPIRV disassembly error"); + disAsmCode = ""; + } + + return disAsmCode; + } + + // If user code defines imageMain or printMain, we will know the entry point name because they're + // already defined in our pre-built module. So we will add those one of those entry points to the + // dropdown list. Then, we will find whether user code also defines other entry points, if it has + // we will also add them to the dropdown list. + findDefinedEntryPoints(shaderSource) + { + var result = []; + try { + var slangSession = this.globalSlangSession.createSession( + this.compileTargetMap.findCompileTarget("SPIRV")); + if(!slangSession) { + return []; + } + + if (shaderSource.match("imageMain")) + result.push("imageMain") + + if (shaderSource.match("printMain")) + result.push("printMain") + + var module = slangSession.loadModuleFromSource(shaderSource, "user", "/user.slang"); + if(!module) { + return result; + } + + var count = module.getDefinedEntryPointCount(); + for (var i = 0; i < count; i++) + { + var entryPoint = module.getDefinedEntryPoint(i); + const entryPointName = entryPoint.getName(); + + result.push(entryPoint.getName()); + entryPoint.delete(); + } + } catch (e) { + return []; + } + finally { + if(module) { + module.delete(); + } + if (slangSession) { + slangSession.delete(); + } + } + return result; + } + + // If user entrypoint name imageMain or printMain, we will load the pre-built main modules because they + // are defined in those modules. Otherwise, we will only need to load the user module and find the entry + // point in the user module. + shouldLoadMainModule(entryPointName) + { + return entryPointName == "imageMain" || entryPointName == "printMain"; + } + + // Since we will not let user to change the entry point code, we can precompile the entry point module + // and reuse it for every compilation. + + compileEntryPointModule(slangSession, moduleName) + { + var module = slangSession.loadModuleFromSource(this.mainModules[moduleName].source, moduleName, '/' + moduleName + '.slang'); + + if (!module) { + var error = this.slangWasmModule.getLastError(); + console.error(error.type + " error: " + error.message); + this.diagnosticsMsg+=(error.type + " error: " + error.message); + return null; + } + + // we use the same entry point name as module name + var entryPoint = this.findEntryPoint(module, moduleName, SlangCompiler.SLANG_STAGE_COMPUTE); + if (!entryPoint) + return null; + + return {module: module, entryPoint: entryPoint}; + + } + + getPrecompiledProgram(slangSession, moduleName) + { + if (moduleName != "printMain" && moduleName != "imageMain") + return null; + + let mainModule = this.compileEntryPointModule(slangSession, moduleName); + + this.shaderType = SlangCompiler.RENDER_SHADER; + return mainModule; + } + + addActiveEntryPoints(slangSession, shaderSource, entryPointName, isWholeProgram, userModule, componentList) + { + if (entryPointName == "" && !isWholeProgram) + { + this.diagnosticsMsg+=("error: No entry point specified"); + return false; + } + + // For now, we just don't allow user to define imageMain or printMain as entry point name for simplicity + var count = userModule.getDefinedEntryPointCount(); + for (var i = 0; i < count; i++) + { + var entryPointName = userModule.getDefinedEntryPoint(i).getName(); + if (entryPointName == "imageMain" || entryPointName == "printMain") + { + this.diagnosticsMsg+=("error: Entry point name 'imageMain' or 'printMain' is reserved"); + return false; + } + } + + // If entry point is provided, we know for sure this is not a whole program compilation, + // so we will just go to find the correct module to include in the compilation. + if (entryPointName != "") + { + if (this.shouldLoadMainModule(entryPointName)) + { + // we use the same entry point name as module name + var mainProgram = this.getPrecompiledProgram(slangSession, entryPointName); + if (!mainProgram) + return false; + + this.shaderType = entryPointName == "imageMain" ? + SlangCompiler.RENDER_SHADER : SlangCompiler.PRINT_SHADER; + + componentList.push_back(mainProgram.module); + componentList.push_back(mainProgram.entryPoint); + } + else + { + // we know the entry point is from user module + var entryPoint = this.findEntryPoint(userModule, entryPointName, SlangCompiler.SLANG_STAGE_COMPUTE); + if (!entryPoint) + return false; + + componentList.push_back(entryPoint); + } + } + // otherwise, it's a whole program compilation, we will find all active entry points in the user code + // and pre-built modules. + else + { + const results = this.findDefinedEntryPoints(shaderSource); + for (let i = 0; i < results.length; i++) + { + if (results[i] == "imageMain" || results[i] == "printMain") + { + var mainProgram = this.getPrecompiledProgram(slangSession, results[i]); + componentList.push_back(mainProgram.module); + componentList.push_back(mainProgram.entryPoint); + } + else + { + var entryPoint = this.findEntryPoint(userModule, results[i], SlangCompiler.SLANG_STAGE_COMPUTE); + if (!entryPoint) + return false; + + componentList.push_back(entryPoint); + } + } + } + } + + loadModule(slangSession, moduleName, source, componentTypeList) + { + var module = slangSession.loadModuleFromSource(source, moduleName, "/"+ moduleName + ".slang"); + if(!module) { + var error = this.slangWasmModule.getLastError(); + console.error(error.type + " error: " + error.message); + this.diagnosticsMsg+=(error.type + " error: " + error.message); + return false; + } + componentTypeList.push_back(module); + return true; + } + + compile(shaderSource, entryPointName, compileTargetStr, stage) + { + this.diagnosticsMsg = ""; + if (this.hashedString) + { + this.hashedString.delete(); + this.hashedString = null; + } + + const compileTarget = this.compileTargetMap.findCompileTarget(compileTargetStr); + let isWholeProgram = isWholeProgramTarget(compileTargetStr); + + if(!compileTarget) { + this.diagnosticsMsg = "unknown compile target: " + compileTargetStr; + return null; + } + + try { + var slangSession = this.globalSlangSession.createSession(compileTarget); + if(!slangSession) { + var error = this.slangWasmModule.getLastError(); + console.error(error.type + " error: " + error.message); + this.diagnosticsMsg += (error.type + " error: " + error.message); + return null; + } + + var components = new this.slangWasmModule.ComponentTypeList(); + + if (!this.loadModule(slangSession, "playground", playgroundSource, components)) + return null; + + if (!this.loadModule(slangSession, "user", shaderSource, components)) + return null; + + if (this.addActiveEntryPoints(slangSession, shaderSource, entryPointName, isWholeProgram, components.get(1), components) == false) + return null; + + var program = slangSession.createCompositeComponentType(components); + var linkedProgram = program.link(); + this.hashedString = linkedProgram.loadStrings(); + + var outCode; + if (compileTargetStr == "SPIRV") + { + const spirvCode = linkedProgram.getTargetCodeBlob( + 0 /* targetIndex */ + ); + outCode = this.spirvDisassembly(spirvCode); + } + else + { + if (isWholeProgram) + outCode = linkedProgram.getTargetCode(0); + else + outCode = linkedProgram.getEntryPointCode( + 0 /* entryPointIndex */, 0 /* targetIndex */); + } + + if (outCode == "") + { + var error = this.slangWasmModule.getLastError(); + console.error(error.type + " error: " + error.message); + this.diagnosticsMsg += (error.type + " error: " + error.message); + return null; + } + } catch (e) { + console.log(e); + return null; + } + finally { + if(linkedProgram) { + linkedProgram.delete(); + } + if(program) { + program.delete(); + } + + if (components) + { + for (let i = 0; i < components.size(); i++) + { + components.get(i).delete(); + } + components.delete(); + } + + if (slangSession) { + slangSession.delete(); + } + return outCode; + } + } +}; diff --git a/build/compute.js b/build/compute.js new file mode 100644 index 0000000..59cefae --- /dev/null +++ b/build/compute.js @@ -0,0 +1,203 @@ + +class ComputePipeline +{ + pipeline; + pipelineLayout; + + // TODO: We should make this field optional, and only when user select a "Debug" mode will this option be available, + // and we will output this buffer to the output area. + + uniformBuffer; + uniformBufferHost = new Float32Array(4); + + + printfBufferElementSize = 12; + printfBufferSize = this.printfBufferElementSize * 100; // 16 bytes per printf struct + printfBuffer; + printfBufferRead; + + outputBuffer; + outputBufferRead; + outputTexture; + device; + bindGroup; + + constructor(device) + { + this.device = device; + } + + createComputePipelineLayout() + { + // We fill fix our bind group layout to have 2 entries in our playground. + const bindGroupLayoutDescriptor = { + lable: 'compute pipeline bind group layout', + entries: [ + {binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'uniform'}}, + {binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, + {binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, + {binding: 3, visibility: GPUShaderStage.COMPUTE, storageTexture: {access: "read-write", format: this.outputTexture.format}}, + ], + }; + + const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); + const layout = device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout]}); + + this.pipelineLayout = layout; + } + + createPipeline(shaderModule) + { + const pipeline = device.createComputePipeline({ + label: 'compute pipeline', + layout: this.pipelineLayout, + compute: {module: shaderModule}, + }); + + this.pipeline = pipeline; + this.createBindGroup(); + } + + createBindGroup() + { + const bindGroup = device.createBindGroup({ + layout: this.pipeline.getBindGroupLayout(0), + entries: [ + { binding: 0, resource: { buffer: this.uniformBuffer }}, + { binding: 1, resource: { buffer: this.printfBuffer }}, + { binding: 2, resource: { buffer: this.outputBuffer }}, + { binding: 3, resource: this.outputTexture.createView() }, + ], + }); + + this.bindGroup = bindGroup; + } + + destroyResources() + { + if (this.outputBuffer) + { + this.outputBuffer.destroy(); + this.outputBuffer = null; + } + + if (this.outputBufferRead) + { + this.outputBufferRead.destroy(); + this.outputBufferRead = null; + } + + if (this.printfBuffer) + { + this.printfBuffer.destroy(); + this.printfBuffer = null; + } + + if (this.printfBufferRead) + { + this.printfBufferRead.destroy(); + this.printfBufferRead = null; + } + + if (this.outputTexture) + { + this.outputTexture.destroy(); + this.outputTexture = null; + } + } + // All out compute pipeline will have 2 outputs: + // 1. A buffer that will be used to read the result back to the CPU + // 2. A texture that will be used to display the result on the screen + createOutput(invalid, windowSize) + { + if (invalid) + { + this.destroyResources(); + let usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC; + + // we will fix the size of the workgroup to be 2 x 2 for printMain. + const numberElements = 1; + const size = numberElements * 4; // int type + this.outputBuffer = this.device.createBuffer({lable: 'outputBuffer', size, usage}); + + this.printfBuffer = this.device.createBuffer({lable: 'outputBuffer', size: this.printfBufferSize, usage}); + + usage = GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST; + this.outputBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size, usage}); + this.printfBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size: this.printfBufferSize, usage}); + + const storageTexture = createOutputTexture(device, windowSize[0], windowSize[1], 'r32float'); + this.outputTexture = storageTexture; + + } + } + + createUniformBuffer() + { + this.uniformBuffer = this.device.createBuffer({size: this.uniformBufferHost.byteLength, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST}); + } + + updateUniformBuffer(data) + { + this.uniformBufferHost[0] = data; + this.device.queue.writeBuffer(this.uniformBuffer, 0, this.uniformBufferHost); + } + + setupComputePipeline(windowSize) + { + this.createOutput(true, windowSize); + this.createComputePipelineLayout(); + } + + + // This is the definition of the printf buffer. + // struct FormatedStruct + // { + // uint32_t type = 0xFFFFFFFF; + // uint32_t low = 0; + // uint32_t high = 0; + // }; + parsePrintfBuffer(hashedString) + { + const printfBufferArray = new Uint32Array(computePipeline.printfBufferRead.getMappedRange()) + var elementIndex = 0; + var numberElements = printfBufferArray.byteLength / this.printfBufferElementSize; + + var formatString; + if (printfBufferArray[0] == 1) // type field + { + formatString = hashedString.getString(printfBufferArray[1]); // low field + } + + // TODO: We currently doesn't support 64-bit data type (e.g. uint64_t, int64_t, double, etc.) + // so 32-bit array should be able to contain everything we need. + var dataArray = new Uint32Array(numberElements); + var stringArray = []; + const elementSizeInWords = this.printfBufferElementSize / 4; + for (elementIndex = 1; elementIndex < numberElements; elementIndex++) + { + var offset = elementIndex * elementSizeInWords; + const type = printfBufferArray[offset]; + + if (type == 1) // type field, this is a string + { + stringArray.push(hashedString.getString(printfBufferArray[offset + 1])); // low field + } + else if (type == 2) // type field + { + dataArray[elementIndex - 1] = printfBufferArray[offset + 1]; // low field + } + else if (type == 0xFFFFFFFF) + { + break; + } + } + + return {formatString: formatString, dataArray: dataArray.slice(0, elementIndex - 1), stringArray: stringArray}; + } + + // TODO: construct the final formatted result + formatToString(formatString, dataArray, stringArray) + { + } +} diff --git a/build/index.html b/build/index.html new file mode 100644 index 0000000..ebd7317 --- /dev/null +++ b/build/index.html @@ -0,0 +1,235 @@ + + + + Slang Playground + + + + + + + + + + + + + + + + + + + + +
+ Slang Logo +
+
+

Loading Playground...

+
+
+
+ + + + + + + diff --git a/build/language-server.js b/build/language-server.js new file mode 100644 index 0000000..c1d329a --- /dev/null +++ b/build/language-server.js @@ -0,0 +1,722 @@ +const userCodeURI = "file:///user.slang"; +const playgroundCodeURI = "file:///playground.slang"; +var languageRegistered = false; +function initMonaco() { + if (languageRegistered) + return; + languageRegistered = true; + monaco.languages.register({ id: "slang" }); + monaco.languages.setMonarchTokensProvider("slang", { + keywords: [ + "if", "else", "switch", "case", "default", "return", + "try", "throw", "throws", "catch", "while", "for", + "do", "static", "const", "in", "out", "inout", + "ref", "__subscript", "__init", "property", "get", "set", + "class", "struct", "interface", "public", "private", "internal", + "protected", "typedef", "typealias", "uniform", "export", "groupshared", + "extension", "associatedtype", "this", "namespace", "This", "using", + "__generic", "__exported", "import", "enum", "break", "continue", + "discard", "defer", "cbuffer", "tbuffer", "func", "is", + "as", "nullptr", "none", "true", "false", "functype", + "sizeof", "alignof", "__target_switch", "__intrinsic_asm", + "typename", "each", "expand", "where", "register", "packoffset", + ], + brackets: [ + { open: '{', close: '}', token: 'delimiter.curly' }, + { open: '[', close: ']', token: 'delimiter.square' }, + { open: '(', close: ')', token: 'delimiter.parenthesis' }, + { open: '<', close: '>', token: 'delimiter.angle' } + ], + namespaceFollows: [ + 'namespace', 'using', + ], + typeKeywords: [ + 'bool', 'double', 'uint', 'int', 'short', 'char', 'void', 'float' + ], + + operators: [ + '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', + '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%', + '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=', + '%=', '<<=', '>>=', '>>>=' + ], + + // we include these common regular expressions + symbols: /[=>](?!@symbols)/, '@brackets'], + [/@symbols/, { + cases: { + '@operators': 'operator', + '@default': '' + } + }], + + // numbers + [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'], + [/0[xX][0-9a-fA-F]+/, 'number.hex'], + [/\d+/, 'number'], + + // delimiter: after number because of .\d floats + [/[;,.]/, 'delimiter'], + + // strings + [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string + [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }], + + // characters + [/'[^\\']'/, 'string'], + [/(')(@escapes)(')/, ['string', 'string.escape', 'string']], + [/'/, 'string.invalid'] + ], + + comment: [ + [/[^\/*]+/, 'comment'], + [/\/\*/, 'comment', '@push'], // nested comment + ["\\*/", 'comment', '@pop'], + [/[\/*]/, 'comment'] + ], + + string: [ + [/[^\\"]+/, 'string'], + [/@escapes/, 'string.escape'], + [/\\./, 'string.escape.invalid'], + [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] + ], + + rawstring: [ + // Closing of raw string literal with matching delimiter + [/\)([a-zA-Z0-9_]*?)"/, { + cases: { + '$1==$S2': { token: 'string.raw.quote', next: '@pop' }, // Match delimiter with initial delimiter + '@default': 'string.raw' // Otherwise, continue within raw string + } + }], + [/./, 'string.raw'] // Match any character within the raw string + ], + + whitespace: [ + [/[ \t\r\n]+/, 'white'], + [/\/\*/, 'comment', '@comment'], + [/\/\/.*$/, 'comment'], + ], + qualified: [ + [/[a-zA-Z_][\w]*/, { + cases: { + '@keywords': { token: 'keyword.$0' }, + '@default': 'identifier' + } + }], + [/\./, 'delimiter'], + ['', '', '@pop'], + ], + namespace: [ + { include: '@whitespace' }, + [/[A-Z]\w*/, 'namespace'], + [/[\.=]/, 'delimiter'], + ['', '', '@pop'], + ], + }, + }); + + // A general highlighting rule for all shading languages we care about. + monaco.languages.register({ id: "generic-shader" }); + monaco.languages.setMonarchTokensProvider("generic-shader", { + keywords: [ + "if", "else", "switch", "case", "default", "return", + "while", "for", "do", "static", "const", "in", "out", "inout", + "ref", "class", "struct", "interface", "public", "private", "internal", + "protected", "typedef", "uniform", "export", "groupshared", + "this", "namespace", "using", "enum", "break", "continue", + "discard", "cbuffer", "tbuffer", "true", "false", + "sizeof", "alignof", "layout", "buffer", "register", + "packoffset", "nointerpolation" + ], + brackets: [ + { open: '{', close: '}', token: 'delimiter.curly' }, + { open: '[', close: ']', token: 'delimiter.square' }, + { open: '(', close: ')', token: 'delimiter.parenthesis' }, + { open: '<', close: '>', token: 'delimiter.angle' } + ], + namespaceFollows: [ + 'namespace', 'using', + ], + typeKeywords: [ + 'bool', 'double', 'uint', 'int', 'short', 'char', 'void', 'float' + ], + operators: [ + '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', + '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%', + '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=', + '%=', '<<=', '>>=', '>>>=' + ], + + // we include these common regular expressions + symbols: /[=>](?!@symbols)/, '@brackets'], + [/@symbols/, { + cases: { + '@operators': 'operator', + '@default': '' + } + }], + + // numbers + [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'], + [/0[xX][0-9a-fA-F]+/, 'number.hex'], + [/\d+/, 'number'], + + // delimiter: after number because of .\d floats + [/[;,.]/, 'delimiter'], + + // strings + [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string + [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }], + + // characters + [/'[^\\']'/, 'string'], + [/(')(@escapes)(')/, ['string', 'string.escape', 'string']], + [/'/, 'string.invalid'] + ], + + comment: [ + [/[^\/*]+/, 'comment'], + [/\/\*/, 'comment', '@push'], // nested comment + ["\\*/", 'comment', '@pop'], + [/[\/*]/, 'comment'] + ], + + string: [ + [/[^\\"]+/, 'string'], + [/@escapes/, 'string.escape'], + [/\\./, 'string.escape.invalid'], + [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] + ], + + whitespace: [ + [/[ \t\r\n]+/, 'white'], + [/\/\*/, 'comment', '@comment'], + [/\/\/.*$/, 'comment'], + ], + qualified: [ + [/[a-zA-Z_][\w]*/, { + cases: { + '@keywords': { token: 'keyword.$0' }, + '@default': 'identifier' + } + }], + [/\./, 'delimiter'], + ['', '', '@pop'], + ], + namespace: [ + { include: '@whitespace' }, + [/[A-Z]\w*/, 'namespace'], + [/[\.=]/, 'delimiter'], + ['', '', '@pop'], + ], + }, + }); + + monaco.languages.register({ id: "spirv" }); + monaco.languages.setMonarchTokensProvider("spirv", { + brackets: [ + { open: '{', close: '}', token: 'delimiter.curly' }, + { open: '[', close: ']', token: 'delimiter.square' }, + { open: '(', close: ')', token: 'delimiter.parenthesis' }, + ], + operators: [ + '=', + ], + + symbols: /[=>](?!@symbols)/, '@brackets'], + [/@symbols/, { + cases: { + '@operators': 'operator', + '@default': '' + } + }], + + // numbers + [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'], + [/0[xX][0-9a-fA-F]+/, 'number.hex'], + [/\d+/, 'number'], + + // delimiter: after number because of .\d floats + [/[;,.]/, 'delimiter'], + + // strings + [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string + [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }], + + // characters + [/'[^\\']'/, 'string'], + [/(')(@escapes)(')/, ['string', 'string.escape', 'string']], + [/'/, 'string.invalid'] + ], + + string: [ + [/[^\\"]+/, 'string'], + [/@escapes/, 'string.escape'], + [/\\./, 'string.escape.invalid'], + [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] + ], + + whitespace: [ + [/[ \t\r\n]+/, 'white'], + ], + }, + }); + + monaco.languages.registerDefinitionProvider("spirv", { + provideDefinition: function (model, position) { + const word = model.getWordAtPosition(position); + if (!word) return null; + + const wordRange = new monaco.Range( + position.lineNumber, + word.startColumn, + position.lineNumber, + word.endColumn + ); + + // Extract the identifier under the cursor + const identifier = word.word; + + // Find the definition of the identifier (either a register or function) + for (let i = 1; i <= model.getLineCount(); i++) { + const lineContent = model.getLineContent(i); + + // Check for register definitions (%register) + if (lineContent.includes(`${identifier} =`)) { + return { + range: new monaco.Range(i, 1, i, lineContent.length + 1), + uri: model.uri + }; + } + + // Check for function definitions (OpFunction) + if (lineContent.includes(`OpFunction ${identifier}`)) { + return { + range: new monaco.Range(i, 1, i, lineContent.length + 1), + uri: model.uri + }; + } + } + + // Return null if no definition was found + return null; + } + }); + + monaco.languages.registerHoverProvider('spirv', { + provideHover: function(model, position) { + const word = model.getWordAtPosition(position); + if (!word) return null; + + const identifier = word.word; + let currentFunction = null; + + // Check for %register or OpFunction definitions + for (let i = 1; i <= model.getLineCount(); i++) { + const lineContent = model.getLineContent(i); + + // Detect function definitions + if (lineContent.includes(`OpFunction`)) { + const funcMatch = lineContent.match(/%?(\w+)\s+=\s+OpFunction\s+/); + if (funcMatch) { + currentFunction = funcMatch[1]; // Store the current function name + } + } + + // Detect function end to reset the current function + if (lineContent.includes(`OpFunctionEnd`)) { + currentFunction = null; + } + + // Hover text for register + if (lineContent.includes(`${identifier} =`)) { + var hoverContents = [ + { value: `**Register:** \`${identifier}\`` }, + { value: '---' }, + { value: `**Definition:** \n\n\`${lineContent.trim()}\`` } + ]; + // Add function context if inside a function + if (currentFunction) { + hoverContents.push({ value: `**In Function:** \`${currentFunction}\`` }); + } + return { + range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn), + contents: hoverContents + }; + } + + // Hover text for function + if (lineContent.includes(`OpFunction ${identifier}`)) { + return { + range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn), + contents: [ + { value: `**Function:** \`${identifier}\`` }, + { value: '---' }, + { value: `**Definition:** \n\n\`${lineContent.trim()}\`` } + ] + }; + } + } + + // If no match is found, return null + return null; + } + }); + + monaco.editor.defineTheme("slang-dark", { + base: "vs-dark", + inherit: true, + rules: [ + { token: "function", foreground: "DCDCAA" }, + { token: "parameter", foreground: "B0B0B0" }, + { token: "variable", foreground: "8CDCFE" }, + { token: "enumMember", foreground: "98AD1C" }, + ], + colors: { + "editor.foreground": "#F0F0F0", + }, + }); + + monaco.languages.registerHoverProvider("slang", { + provideHover: function (model, position) { + if (slangd == null) { + return null; + } + let result = slangd.hover(userCodeURI, { line: position.lineNumber - 1, character: position.column - 1 }); + if (result == null) { + return null; + } + return { + contents: [{ value: result.contents.value }], + range: { + startLineNumber: result.range.start.line + 1, + startColumn: result.range.start.character + 1, + endLineNumber: result.range.end.line + 1, + endColumn: result.range.end.character + 1 + } + }; + } + }); + monaco.languages.registerDefinitionProvider("slang", { + provideDefinition: function (model, position) { + if (slangd == null) { + return null; + } + let result = slangd.gotoDefinition(userCodeURI, { line: position.lineNumber - 1, character: position.column - 1 }); + if (result == null) { + return null; + } + var resultArray = []; + for (var i = 0; i < result.size(); i++) { + let lspResult = result.get(i); + resultArray.push({ + uri: monaco.Uri.parse(lspResult.uri), + range: { + startLineNumber: lspResult.range.start.line + 1, + startColumn: lspResult.range.start.character + 1, + endLineNumber: lspResult.range.end.line + 1, + endColumn: lspResult.range.end.character + 1 + } + }); + } + return resultArray; + } + }); + monaco.languages.registerCompletionItemProvider("slang", { + triggerCharacters: [".", ":", ">", "(", "<", " ", "["], + provideCompletionItems: function (model, position, context) { + if (slangd == null) { + return null; + } + let lspContext = { + triggerKind: context.triggerKind, + triggerCharacter: context.hasOwnProperty("triggerCharacter") ? context.triggerCharacter : "" + }; + let result = slangd.completion( + userCodeURI, + { line: position.lineNumber - 1, character: position.column - 1 }, + lspContext + ); + if (result == null) { + return null; + } + let items = []; + let word = model.getWordAtPosition(position); + if (word == null) + word = model.getWordUntilPosition(position); + var curRange = { + startLineNumber: position.lineNumber, + endLineNumber: position.lineNumber, + startColumn: word.startColumn, + endColumn: word.endColumn, + }; + for (var i = 0; i < result.size(); i++) { + let lspItem = result.get(i); + var item = { + label: lspItem.label, + kind: lspItem.kind, + detail: lspItem.detail, + documentation: lspItem.documentation.value, + insertText: lspItem.label, + range: curRange + }; + items.push(item) + } + return { suggestions: items }; + } + }); + + monaco.languages.registerSignatureHelpProvider("slang", { + signatureHelpTriggerCharacters: ["(", ","], + signatureHelpRetriggerCharacters: [","], + provideSignatureHelp: function (model, position) { + if (slangd == null) { + return null; + } + let result = slangd.signatureHelp(userCodeURI, { line: position.lineNumber - 1, character: position.column - 1 }); + if (result == null) { + return null; + } + let sigs = []; + for (var i = 0; i < result.signatures.size(); i++) { + let lspSignature = result.signatures.get(i); + let params = []; + for (var j = 0; j < lspSignature.parameters.size(); j++) { + let lspParameter = lspSignature.parameters.get(j); + params.push({ + label: [lspParameter.label[0], lspParameter.label[1]], + documentation: lspParameter.documentation.value + }); + } + let signature = { + label: lspSignature.label, + documentation: lspSignature.documentation.value, + parameters: params + }; + sigs.push(signature); + } + return { + value: { + signatures: sigs, + activeSignature: result.activeSignature, + activeParameter: result.activeParameter + }, + dispose: function () { } + }; + } + }); + + monaco.languages.registerDocumentRangeSemanticTokensProvider("slang", { + getLegend: function () { + return { + tokenTypes: [ + "type", + "enumMember", + "variable", + "parameter", + "function", + "property", + "namespace", + "keyword", + "macro", + "string", + ], + tokenModifiers: [] + }; + }, + provideDocumentRangeSemanticTokens: function (model, range, token) { + if (slangd == null) { + return null; + } + let result = slangd.semanticTokens(userCodeURI); + if (result == null) { + return null; + } + let rawData = new Uint32Array(result.size()); + for (var i = 0; i < result.size(); i++) { + rawData[i] = result.get(i); + } + return { + data: rawData + }; + } + }); +} + +function initLanguageServer() { + var text = ""; + if (monacoEditor) + { + text = monacoEditor.getValue(); + } + slangd.didOpenTextDocument(userCodeURI, text); + slangd.didOpenTextDocument(playgroundCodeURI, playgroundSource); +} + +var diagnosticTimeout = null; + +function translateSeverity(severity) { + switch(severity) + { + case 1: + return monaco.MarkerSeverity.Error; + case 2: + return monaco.MarkerSeverity.Warning; + case 3: + return monaco.MarkerSeverity.Information; + case 4: + return monaco.MarkerSeverity.Hint; + default: + return monaco.MarkerSeverity.Error; + } +} + +function codeEditorChangeContent(e) { + if (slangd == null) + return; + let lspChanges = new compiler.slangWasmModule.TextEditList(); + + e.changes.forEach(change => + lspChanges.push_back( + { + range: { + start: { line: change.range.startLineNumber - 1, character: change.range.startColumn - 1 }, + end: { line: change.range.endLineNumber - 1, character: change.range.endColumn - 1 } + }, + text: change.text + } + )); + try { + slangd.didChangeTextDocument(userCodeURI, lspChanges); + if (diagnosticTimeout != null) { + clearTimeout(diagnosticTimeout); + } + diagnosticTimeout = setTimeout(() => { + let diagnostics = slangd.getDiagnostics(userCodeURI); + if (diagnostics == null) { + monaco.editor.setModelMarkers(monacoEditor.getModel(), "slang", []); + return; + } + var markers = []; + for (var i = 0; i < diagnostics.size(); i++) { + let lspDiagnostic = diagnostics.get(i); + markers.push({ + startLineNumber: lspDiagnostic.range.start.line + 1, + startColumn: lspDiagnostic.range.start.character + 1, + endLineNumber: lspDiagnostic.range.end.line + 1, + endColumn: lspDiagnostic.range.end.character + 1, + message: lspDiagnostic.message, + severity: translateSeverity(lspDiagnostic.severity), + code: lspDiagnostic.code + }); + } + monaco.editor.setModelMarkers(monacoEditor.getModel(), "slang", markers); + diagnosticTimeout = null; + }, 500); + + } + finally { + lspChanges.delete(); + } + +} diff --git a/build/pass_through.js b/build/pass_through.js new file mode 100644 index 0000000..d1374c6 --- /dev/null +++ b/build/pass_through.js @@ -0,0 +1,141 @@ + +var passThroughshaderCode = ` + + struct VertexShaderOutput { + @builtin(position) position: vec4f, + @location(0) texcoord: vec2f, + }; + + @vertex fn vs( + @builtin(vertex_index) vertexIndex : u32 + ) -> VertexShaderOutput { + let uv = array( + // 1st triangle + vec2f( 0.0, 0.0), // center + vec2f( 1.0, 0.0), // right, center + vec2f( 0.0, 1.0), // center, top + + // 2st triangle + vec2f( 0.0, 1.0), // center, top + vec2f( 1.0, 0.0), // right, center + vec2f( 1.0, 1.0), // right, top + ); + + let pos = array( + // 1st triangle + vec2f( -1.0, -1.0), // center + vec2f( 1.0, -1.0), // right, center + vec2f( -1.0, 1.0), // center, top + + // 2st triangle + vec2f( -1.0, 1.0), // center, top + vec2f( 1.0, -1.0), // right, center + vec2f( 1.0, 1.0), // right, top + ); + + var vsOutput: VertexShaderOutput; + let xy = pos[vertexIndex]; + vsOutput.position = vec4f(xy, 0.0, 1.0); + vsOutput.texcoord = uv[vertexIndex]; + return vsOutput; + } + + @group(0) @binding(0) var ourSampler: sampler; + @group(0) @binding(1) var ourTexture: texture_2d; + + @fragment fn fs(fsInput: VertexShaderOutput) -> @location(0) vec4f { + let color = textureSample(ourTexture, ourSampler, fsInput.texcoord); + let value = u32(color.x); + let r = ((value & 0xFF000000) >> 24); + let g = ((value & 0x00FF0000) >> 16); + let b = ((value & 0x0000FF00) >> 8); + + return vec4f(f32(r)/255.0f, f32(g)/255.0f, f32(b)/255.0f, 1.0f); + } +`; + +class GraphicsPipeline +{ + vertShader; + fragShader; + device; + pipeline; + sampler; + pipelineLayout; + + constructor(device) + { + this.device = device; + } + + createGraphicsPipelineLayout() + { + // Passthrough shader will need an input texture to be displayed on the screen + const bindGroupLayoutDescriptor = { + lable: 'pass through pipeline bind group layout', + entries: [ + {binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: {}}, + {binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: {sampleType: 'float'}}, + ], + }; + + const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); + const layout = device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout]}); + this.pipelineLayout = layout; + } + + createPipeline(shaderModule, inputTexture) + { + this.createGraphicsPipelineLayout(); + + const pipeline = device.createRenderPipeline({ + label: 'pass through pipeline', + layout: this.pipelineLayout, + vertex: + { + module: shaderModule + }, + fragment: + { + module: shaderModule, + targets: [{format: navigator.gpu.getPreferredCanvasFormat()}] + }, + }); + this.pipeline = pipeline; + + this.sampler = device.createSampler(); + this.inputTexture = inputTexture; + this.createBindGroup(); + } + + createBindGroup() + { + const bindGroup = device.createBindGroup({ + label: 'pass through pipeline bind group', + layout: this.pipeline.getBindGroupLayout(0), + entries: [ + { binding: 0, resource: this.sampler }, + { binding: 1, resource: this.inputTexture.createView() }, + ], + }); + + this.bindGroup = bindGroup; + } + + createRenderPassDesc() + { + const renderPassDescriptor = { + label: 'pass through renderPass', + colorAttachments: [ + { + // view: <- to be filled out when we render + clearValue: [0.3, 0.3, 0.3, 1], + loadOp: 'clear', + storeOp: 'store', + }, + ], + }; + + return renderPassDescriptor; + } +}; diff --git a/build/playgoundShader.js b/build/playgoundShader.js new file mode 100644 index 0000000..2eb90b2 --- /dev/null +++ b/build/playgoundShader.js @@ -0,0 +1,83 @@ + +const playgroundSource = ` +internal uniform float time; + +// Return the current time in milliseconds +public float getTime() +{ + return time; +} + +struct FormatedStruct +{ + uint32_t type = 0xFFFFFFFF; + uint32_t low = 0; + uint32_t high = 0; +}; + +internal RWStructuredBuffer g_printedBuffer; + +interface IPrintf +{ + uint32_t typeFlag(); + uint32_t writePrintfWords(); +}; + +extension uint : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return (uint32_t)this; } +} + +extension int : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return (uint32_t)this; } +} + +// extension int64_t : IPrintf +// { +// uint64_t writePrintfWords() { return (uint64_t)this; } +// } + +// extension uint64_t : IPrintf +// { +// uint64_t writePrintfWords() { return (uint64_t)this; } +// } + +extension float : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return bit_cast(this); } +} + +// extension double : IPrintf +// { +// uint64_t writePrintfWords() { return bit_cast(this); } +// } + +extension String : IPrintf +{ + uint32_t typeFlag() { return 1;} + uint32_t writePrintfWords() { return getStringHash(this); } +} + +void handleEach(T value, int index) where T : IPrintf +{ + g_printedBuffer[index].type = value.typeFlag(); + g_printedBuffer[index].low = value.writePrintfWords(); +} + +public void print(String format, expand each T values) where T : IPrintf +{ + //if (format.length != 0) + { + g_printedBuffer[0].type = 1; + g_printedBuffer[0].low = getStringHash(format); + int index = 1; + expand(handleEach(each values, index++)); + + g_printedBuffer[index] = {}; + } +} +`; diff --git a/build/playgroundShader.js b/build/playgroundShader.js new file mode 100644 index 0000000..2eb90b2 --- /dev/null +++ b/build/playgroundShader.js @@ -0,0 +1,83 @@ + +const playgroundSource = ` +internal uniform float time; + +// Return the current time in milliseconds +public float getTime() +{ + return time; +} + +struct FormatedStruct +{ + uint32_t type = 0xFFFFFFFF; + uint32_t low = 0; + uint32_t high = 0; +}; + +internal RWStructuredBuffer g_printedBuffer; + +interface IPrintf +{ + uint32_t typeFlag(); + uint32_t writePrintfWords(); +}; + +extension uint : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return (uint32_t)this; } +} + +extension int : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return (uint32_t)this; } +} + +// extension int64_t : IPrintf +// { +// uint64_t writePrintfWords() { return (uint64_t)this; } +// } + +// extension uint64_t : IPrintf +// { +// uint64_t writePrintfWords() { return (uint64_t)this; } +// } + +extension float : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return bit_cast(this); } +} + +// extension double : IPrintf +// { +// uint64_t writePrintfWords() { return bit_cast(this); } +// } + +extension String : IPrintf +{ + uint32_t typeFlag() { return 1;} + uint32_t writePrintfWords() { return getStringHash(this); } +} + +void handleEach(T value, int index) where T : IPrintf +{ + g_printedBuffer[index].type = value.typeFlag(); + g_printedBuffer[index].low = value.writePrintfWords(); +} + +public void print(String format, expand each T values) where T : IPrintf +{ + //if (format.length != 0) + { + g_printedBuffer[0].type = 1; + g_printedBuffer[0].low = getStringHash(format); + int index = 1; + expand(handleEach(each values, index++)); + + g_printedBuffer[index] = {}; + } +} +`; diff --git a/build/spirv-tools.js b/build/spirv-tools.js new file mode 100644 index 0000000..f2928ea --- /dev/null +++ b/build/spirv-tools.js @@ -0,0 +1,19 @@ + +var Module = (() => { + var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined; + if (typeof __filename != 'undefined') _scriptName = _scriptName || __filename; + return ( +function(moduleArg = {}) { + var moduleRtn; + +var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";if(ENVIRONMENT_IS_NODE){}var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};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("fs");var nodePath=require("path");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);var ret=fs.readFileSync(filename);return ret};readAsync=(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return new Promise((resolve,reject)=>{fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)reject(err);else resolve(binary?data.buffer:data)})})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptName){scriptDirectory=_scriptName}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{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=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)})}return fetch(url,{credentials:"same-origin"}).then(response=>{if(response.ok){return response.arrayBuffer()}return Promise.reject(new Error(response.status+" : "+response.url))})}}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){var preRuns=Module["preRun"];if(preRuns){if(typeof preRuns=="function")preRuns=[preRuns];preRuns.forEach(addOnPreRun)}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){var postRuns=Module["postRun"];if(postRuns){if(typeof postRuns=="function")postRuns=[postRuns];postRuns.forEach(addOnPostRun)}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}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);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");function findWasmBinary(){var f="spirv-tools.wasm";if(!isDataURI(f)){return locateFile(f)}return f}var wasmBinaryFile;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"}function getBinaryPromise(binaryFile){if(!wasmBinary){return readAsync(binaryFile).then(response=>new Uint8Array(response),()=>getBinarySync(binaryFile))}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function getWasmImports(){return{a:wasmImports}}function createWasm(){var info=getWasmImports();function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["x"];updateMemoryViews();wasmTable=wasmExports["A"];addOnInit(wasmExports["y"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}wasmBinaryFile??=findWasmBinary();instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var callRuntimeCallbacks=callbacks=>{callbacks.forEach(f=>f(Module))};var noExitRuntime=Module["noExitRuntime"]||true;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>{abort("")};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{};var embind_init_charCodes=()=>{var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes};var embind_charCodes;var readLatin1String=ptr=>{var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret};var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var BindingError;var throwBindingError=message=>{throw new BindingError(message)};var InternalError;var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(type=>typeDependencies[type]=dependentTypes);function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){return sharedRegisterType(rawType,registeredInstance,options)}var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=readLatin1String(name);registerType(rawType,{name,fromWireType:function(wt){return!!wt},toWireType:function(destructors,o){return o?trueValue:falseValue},argPackAdvance:GenericWireTypeSize,readValueFromPointer:function(pointer){return this["fromWireType"](HEAPU8[pointer])},destructorFunction:null})};var __embind_register_constant=(name,type,value)=>{name=readLatin1String(name);whenDependentTypesAreResolved([],[type],type=>{type=type[0];Module[name]=type["fromWireType"](value);return[]})};var emval_freelist=[];var emval_handles=[];var __emval_decref=handle=>{if(handle>9&&0===--emval_handles[handle+1]){emval_handles[handle]=undefined;emval_freelist.push(handle)}};var count_emval_handles=()=>emval_handles.length/2-5-emval_freelist.length;var init_emval=()=>{emval_handles.push(0,1,undefined,1,null,1,true,1,false,1);Module["count_emval_handles"]=count_emval_handles};var Emval={toValue:handle=>{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles[handle]},toHandle:value=>{switch(value){case undefined:return 2;case null:return 4;case true:return 6;case false:return 8;default:{const handle=emval_freelist.pop()||emval_handles.length;emval_handles[handle]=value;emval_handles[handle+1]=1;return handle}}}};function readPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var EmValType={name:"emscripten::val",fromWireType:handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},toWireType:(destructors,value)=>Emval.toHandle(value),argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction:null};var __embind_register_emval=rawType=>registerType(rawType,EmValType);var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=readLatin1String(name);registerType(rawType,{name,fromWireType:value=>value,toWireType:(destructors,value)=>value,argPackAdvance:GenericWireTypeSize,readValueFromPointer:floatReadValueFromPointer(name,size),destructorFunction:null})};var createNamedFunction=(name,body)=>Object.defineProperty(body,"name",{value:name});var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function usesDestructorStack(argTypes){for(var i=1;i{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(...args){if(!proto[methodName].overloadTable.hasOwnProperty(args.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[args.length].apply(this,args)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i>2])}return array};var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistent public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var dynCallLegacy=(sig,ptr,args)=>{sig=sig.replace(/p/g,"i");var f=Module["dynCall_"+sig];return f(ptr,...args)};var wasmTable;var getWasmTableEntry=funcPtr=>wasmTable.get(funcPtr);var dynCall=(sig,ptr,args=[])=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr)(...args);return rtn};var getDynCaller=(sig,ptr)=>(...args)=>dynCall(sig,ptr,args);var embind__requireFunction=(signature,rawFunction)=>{signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};var extendError=(baseErrorType,errorName)=>{var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass};var UnboundTypeError;var getTypeName=type=>{var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var getFunctionName=signature=>{signature=signature.trim();const argsIndex=signature.indexOf("(");if(argsIndex!==-1){return signature.substr(0,argsIndex)}else{return signature}};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync,isNonnullReturn)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);name=getFunctionName(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,argTypes=>{var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer]:pointer=>HEAPU8[pointer];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name,fromWireType,toWireType,argPackAdvance:GenericWireTypeSize,readValueFromPointer:integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name,fromWireType:decodeMemoryView,argPackAdvance:GenericWireTypeSize,readValueFromPointer:decodeMemoryView},{ignoreDuplicateRegistrations:true})};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=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}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;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)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var __embind_register_std_string=(rawType,name)=>{name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name,fromWireType(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=readLatin1String(name);var decodeString,encodeString,readCharAt,lengthBytesUTF;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;readCharAt=pointer=>HEAPU16[pointer>>1]}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;readCharAt=pointer=>HEAPU32[pointer>>2]}registerType(rawType,{name,fromWireType:value=>{var length=HEAPU32[value>>2];var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||readCharAt(currentBytePtr)==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},toWireType:(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length/charSize;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var __embind_register_void=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{isVoid:true,name,argPackAdvance:0,fromWireType:()=>undefined,toWireType:(destructors,o)=>undefined})};var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`)}return impl};var __emval_take_value=(type,arg)=>{type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)};var __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffset{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i{var bufSize=0;getEnvStrings().forEach((string,i)=>{var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1});return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(string=>bufSize+=string.length+1);HEAPU32[penviron_buf_size>>2]=bufSize;return 0};var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("initRandomDevice")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key of Object.keys(node.contents)){entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url).then(arrayBuffer=>{onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)},err=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}});if(dep)addRunDependency(dep)};var FS_createDataFile=(parent,name,fileData,canRead,canWrite,canOwn)=>{FS.createDataFile(parent,name,fileData,canRead,canWrite,canOwn)};var preloadPlugins=Module["preloadPlugins"]||[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:class{constructor(errno){this.name="ErrnoError";this.errno=errno}},genericErrors:{},filesystems:null,syncFSRequests:0,readFiles:{},FSStream:class{constructor(){this.shared={}}get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev;this.readMode=292|73;this.writeMode=146}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var i=0;iFS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""});FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat(func,path,buf){var stat=func(path);HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];return 0},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var convertI32PairToI53Checked=(lo,hi)=>hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN;function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};init_emval();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();var wasmImports={h:___cxa_throw,t:__abort_js,l:__embind_register_bigint,j:__embind_register_bool,v:__embind_register_constant,i:__embind_register_emval,e:__embind_register_float,g:__embind_register_function,b:__embind_register_integer,a:__embind_register_memory_view,d:__embind_register_std_string,c:__embind_register_std_wstring,n:__embind_register_void,u:__emval_decref,w:__emval_take_value,m:__tzset_js,s:_emscripten_resize_heap,o:_environ_get,p:_environ_sizes_get,q:_fd_close,r:_fd_read,k:_fd_seek,f:_fd_write};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["y"])();var ___getTypeName=a0=>(___getTypeName=wasmExports["z"])(a0);var _malloc=a0=>(_malloc=wasmExports["B"])(a0);var _free=a0=>(_free=wasmExports["C"])(a0);var dynCall_viijii=Module["dynCall_viijii"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_viijii=Module["dynCall_viijii"]=wasmExports["D"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_jiji=Module["dynCall_jiji"]=(a0,a1,a2,a3,a4)=>(dynCall_jiji=Module["dynCall_jiji"]=wasmExports["E"])(a0,a1,a2,a3,a4);var dynCall_iiiiij=Module["dynCall_iiiiij"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_iiiiij=Module["dynCall_iiiiij"]=wasmExports["F"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8)=>(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=wasmExports["G"])(a0,a1,a2,a3,a4,a5,a6,a7,a8);var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9)=>(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=wasmExports["H"])(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9);var calledRun;var calledPrerun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}if(!calledPrerun){calledPrerun=1;preRun();if(runDependencies>0){return}}function doRun(){if(calledRun)return;calledRun=1;Module["calledRun"]=1;if(ABORT)return;initRuntime();readyPromiseResolve(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();moduleRtn=readyPromise; + + + return moduleRtn; +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = Module; +else if (typeof define === 'function' && define['amd']) + define([], () => Module); diff --git a/build/spirv-tools.wasm b/build/spirv-tools.wasm new file mode 100755 index 0000000000000000000000000000000000000000..36463c20e156b338ffbfbe1477b5b186eb8c9260 GIT binary patch literal 383130 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%0AeN85a)2PI~CaSZqs6s3}b{L-r#X;ZFI7F#c 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�>S0 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 { resizeCanvasHandler(entries); }); + observer.observe(canvas); +} + +function resizeCanvas(entries) +{ + const canvas = entries[0].target; + + if (canvas.style.display == "none") + { + var parentDiv = document.getElementById("output"); + currentWindowSize = [parentDiv.clientWidth, parentDiv.clientHeight]; + return true; + } + + const width = canvas.clientWidth; + const height = canvas.clientHeight; + + if (width != currentWindowSize[0] || height != currentWindowSize[1]) + { + // ensure the size won't be 0 nor exceed the limit, otherwise WebGPU will throw an errors + canvas.width = Math.max(1, Math.min(width, device.limits.maxTextureDimension2D)); + canvas.height = Math.max(1, Math.min(height, device.limits.maxTextureDimension2D)); + + currentWindowSize = [canvas.width, canvas.height]; + return true; + } + + return false; +} + +var renderDelayTimer = null; + +function startRendering() { + if (renderDelayTimer) + clearTimeout(renderDelayTimer); + + renderDelayTimer = setTimeout(() => { + if (computePipeline && passThroughPipeline && + currentWindowSize[0] > 1 && currentWindowSize[1] > 1) { + computePipeline.createOutput(true, currentWindowSize); + computePipeline.createBindGroup(); + passThroughPipeline.inputTexture = computePipeline.outputTexture; + passThroughPipeline.createBindGroup(); + if (canvas.style.display != "none") { + requestAnimationFrame(render); + } + } + }, 100); +} + +// We use the timer in the resize handler debounce the resize event, otherwise we could end of rendering +// multiple useless frames. +function resizeCanvasHandler(entries) +{ + var needResize = resizeCanvas(entries); + if (needResize) { + startRendering(); + } +} + +function toggleDisplayMode(displayMode) +{ + if (currentMode == displayMode) + return; + if (currentMode == HIDDEN_MODE && displayMode != HIDDEN_MODE) + { + document.getElementById("resultSplitContainer").style.gridTemplateRows="50% 14px 1fr"; + } + if (displayMode == RENDER_MODE) + { + var printResult = document.getElementById("printResult") + printResult.style.display = "none"; + canvas.style.display="grid"; + canvas.style.width = "100%"; + canvas.style.height = "100%"; + currentMode = RENDER_MODE; + } + else if (displayMode == PRINT_MODE) + { + canvas.style.display="none"; + var printResult = document.getElementById("printResult") + printResult.style.display = "grid"; + + currentMode = PRINT_MODE; + } + else if (displayMode == HIDDEN_MODE) + { + canvas.style.display="none"; + document.getElementById("printResult").style.display = "none"; + document.getElementById("resultSplitContainer").style.gridTemplateRows="0px 14px 1fr"; + currentMode = HIDDEN_MODE; + } + else + { + console.log("Invalid display mode " + displayMode); + } +} + +async function render(timeMS) +{ + if (currentMode == HIDDEN_MODE) + return; + if (currentWindowSize[0] < 2 || currentWindowSize[1] < 2) + return; + + computePipeline.updateUniformBuffer(timeMS * 0.01); + // Encode commands to do the computation + const encoder = device.createCommandEncoder({ label: 'compute builtin encoder' }); + const pass = encoder.beginComputePass({ label: 'compute builtin pass' }); + + pass.setBindGroup(0, computePipeline.bindGroup); + pass.setPipeline(computePipeline.pipeline); + const workGroupSizeX = (currentWindowSize[0] + 15) / 16; + const workGroupSizeY = (currentWindowSize[1] + 15) / 16; + pass.dispatchWorkgroups(workGroupSizeX, workGroupSizeY); + pass.end(); + + if (currentMode == RENDER_MODE) + { + var renderPassDescriptor = passThroughPipeline.createRenderPassDesc(); + renderPassDescriptor.colorAttachments[0].view = context.getCurrentTexture().createView(); + const renderPass = encoder.beginRenderPass(renderPassDescriptor); + + renderPass.setBindGroup(0, passThroughPipeline.bindGroup); + renderPass.setPipeline(passThroughPipeline.pipeline); + renderPass.draw(6); // call our vertex shader 6 times. + renderPass.end(); + } + + // copy output buffer back in print mode + if (currentMode == PRINT_MODE) + encoder.copyBufferToBuffer(computePipeline.outputBuffer, 0, computePipeline.outputBufferRead, 0, computePipeline.outputBuffer.size); + + // Finish encoding and submit the commands + const commandBuffer = encoder.finish(); + device.queue.submit([commandBuffer]); + + // Only request the next frame if we are in the render mode + if (currentMode == RENDER_MODE) + requestAnimationFrame(render); +} + +async function printResult() +{ + // Encode commands to do the computation + const encoder = device.createCommandEncoder({ label: 'compute builtin encoder' }); + const pass = encoder.beginComputePass({ label: 'compute builtin pass' }); + + pass.setBindGroup(0, computePipeline.bindGroup); + pass.setPipeline(computePipeline.pipeline); + pass.dispatchWorkgroups(1, 1); + pass.end(); + + // copy output buffer back in print mode + encoder.copyBufferToBuffer(computePipeline.outputBuffer, 0, computePipeline.outputBufferRead, 0, computePipeline.outputBuffer.size); + encoder.copyBufferToBuffer(computePipeline.printfBuffer, 0, computePipeline.printfBufferRead, 0, computePipeline.printfBuffer.size); + + // Finish encoding and submit the commands + const commandBuffer = encoder.finish(); + device.queue.submit([commandBuffer]); + + await device.queue.onSubmittedWorkDone(); + // Read the results once the job is done + await Promise.all([ + computePipeline.outputBufferRead.mapAsync(GPUMapMode.READ), + computePipeline.printfBufferRead.mapAsync(GPUMapMode.READ)]); + + const output = new Int32Array(computePipeline.outputBufferRead.getMappedRange()); + + // debug testing: + let textResult = output.toString() + "\n"; + if (compiler.hashedString) + { + const result = computePipeline.parsePrintfBuffer(compiler.hashedString) + textResult += "Format string: " + result.formatString + "\n"; + textResult += "Data view: " + result.dataArray.toString() + "\n"; + textResult += "String view: " + result.stringArray.toString() + "\n"; + } + + computePipeline.outputBufferRead.unmap(); + computePipeline.printfBufferRead.unmap(); + + document.getElementById("printResult").value = textResult; +} + +function parsePrintfBuffer(buffer) +{ + +} + +function checkShaderType(userSource) +{ + // we did a pre-filter on the user input source code. + const isImageMain = userSource.match("imageMain"); + const isPrintMain = userSource.match("printMain"); + + // Only one of the main function should be defined. + // In this case, we will know that the shader is not runnable, so we can only compile it. + if (isImageMain == isPrintMain) + return SlangCompiler.NON_RUNNABLE_SHADER; + + if (isImageMain) + return SlangCompiler.RENDER_SHADER; + else + return SlangCompiler.PRINT_SHADER; +} + +var onRun = () => { + if (!device) + return; + if (!monacoEditor) + return; + if (!compiler) + return; + if (!computePipeline) + { + computePipeline = new ComputePipeline(device); + computePipeline.setupComputePipeline(currentWindowSize); + computePipeline.createUniformBuffer(4); // 4 bytes for float number + } + + if (!passThroughPipeline) + { + passThroughPipeline = new GraphicsPipeline(device); + const shaderModule = device.createShaderModule({code: passThroughshaderCode}); + const inputTexture = computePipeline.outputTexture; + passThroughPipeline.createPipeline(shaderModule, inputTexture); + } + + // We will have some restrictions on runnable shader, the user code has to define imageMain or printMain function. + // We will do a pre-filter on the user input source code, if it's not runnable, we will not run it. + const userSource = monacoEditor.getValue(); + const shaderType = checkShaderType(userSource); + if (shaderType == SlangCompiler.NON_RUNNABLE_SHADER) + { + diagnosticsArea.setValue("Error: In order to run the shader, please define either imageMain or printMain function in the shader code."); + // clear content in render area and code-gen area + toggleDisplayMode(HIDDEN_MODE); + codeGenArea.setValue(""); + return; + } + + const entryPointName = shaderType == SlangCompiler.RENDER_SHADER? "imageMain" : "printMain"; + const ret = compileShader(userSource, entryPointName, "WGSL"); + + // Recompile the pipeline. + if (ret.succ) + { + const module = device.createShaderModule({code:ret.code}); + computePipeline.createPipeline(module); + } + + toggleDisplayMode(compiler.shaderType); + if (compiler.shaderType == SlangCompiler.PRINT_SHADER) + { + printResult(); + } + else if (compiler.shaderType == SlangCompiler.RENDER_SHADER) + { + startRendering(); + } +} + +function compileShader(userSource, entryPoint, compileTarget) +{ + var compiledCode = compiler.compile(userSource, entryPoint, compileTarget, SlangCompiler.SLANG_STAGE_COMPUTE); + diagnosticsArea.setValue(compiler.diagnosticsMsg); + + // If compile is failed, we just clear the codeGenArea + if (!compiledCode) + { + codeGenArea.setValue('Compilation returned empty result.'); + return {succ: false, code: compiledCode}; + } + + codeGenArea.setValue(compiledCode); + if (compileTarget == "WGSL") + codeGenArea.getModel().setLanguage("wgsl"); + else if (compileTarget == "SPIRV") + codeGenArea.getModel().setLanguage("spirv"); + else + codeGenArea.getModel().setLanguage("generic-shader"); + return {succ: true, code: compiledCode}; +} + +// For the compile button action, we don't have restriction on user code that it has to define imageMain or printMain function. +// But if it doesn't define any of them, then user code has to define a entry point function name. Because our built-in shader +// have no way to call the user defined function, and compile engine cannot compile the source code. +var onCompile = async () => { + + toggleDisplayMode(HIDDEN_MODE); + const compileTarget = document.getElementById("target-select").value; + + const entryPoint = document.getElementById("entrypoint-select").value; + if (entryPoint == "" && !isWholeProgramTarget(compileTarget)) + { + diagnosticsArea.setValue("Please select the entry point name"); + return; + } + + if (compileTarget == "SPIRV") + await compiler.initSpirvTools(); + + // compile the compute shader code from input text area + const userSource = monacoEditor.getValue(); + compileShader(userSource, entryPoint, compileTarget); + + if (compiler.diagnosticsMsg.length > 0) + { + diagnosticsArea.setValue(compiler.diagnosticsMsg); + return; + } +} + +function onSourceCodeChange() +{ + sourceCodeChange = true; +} + + +function loadEditor(readOnlyMode = false, containerId, preloadCode) { + + require(["vs/editor/editor.main"], function () { + var container = document.getElementById(containerId); + initMonaco(); + var model = readOnlyMode + ? monaco.editor.createModel(preloadCode) + : monaco.editor.createModel("", "slang", monaco.Uri.parse(userCodeURI)); + var editor = monaco.editor.create(container, { + model: model, + language: readOnlyMode?'csharp':'slang', + theme: 'slang-dark', + readOnly: readOnlyMode, + lineNumbers: readOnlyMode?"off":"on", + automaticLayout: true, + "semanticHighlighting.enabled": true, + renderValidationDecorations: "on", + minimap: { + enabled: false + }, + }); + if (!readOnlyMode) + { + model.onDidChangeContent(codeEditorChangeContent); + model.setValue(preloadCode); + } + + if (containerId == "codeEditor") + monacoEditor = editor; + else if (containerId == "diagnostics") + { + var model = editor.getModel(); + monaco.editor.setModelLanguage(model, "text") + diagnosticsArea = editor; + } + else if (containerId == "codeGen") + { + codeGenArea = editor; + codeGenArea.onDidChangeModelContent(function (e) { + onSourceCodeChange(); + }); + } + }); + } + + +// Event when loading the WebAssembly module +var moduleLoadingMessage = ""; + +// Define the Module object with a callback for initialization +var Module = { + onRuntimeInitialized: function () { + var label = document.getElementById("loadingStatusLabel"); + if (label) + label.innerText = "Initializing Slang Compiler..."; + compiler = new SlangCompiler(Module); + slangd = Module.createLanguageServer(); + initLanguageServer(); + var result = compiler.init(); + if (result.ret) { + document.getElementById("compile-btn").disabled = false; + moduleLoadingMessage = "Slang compiler initialized successfully.\n"; + runIfFullyInitialized(); + } + else { + console.log(result.msg); + moduleLoadingMessage = "Failed to initialize Slang Compiler, Run and Compile features are disabled.\n"; + } + } +}; + +function loadSlangWasm() { + var label = document.getElementById("loadingStatusLabel"); + if (label) + label.innerText = "Loading Slang Compiler..."; + const script = document.createElement("script"); + script.src = "slang-wasm.js"; + document.head.appendChild(script); +} + +var pageLoaded = false; +// event when loading the page +window.onload = async function () +{ + loadSlangWasm(); + pageLoaded = true; + + await webgpuInit(); + if (device) + { + document.getElementById("run-btn").disabled = false; + } + else + { + diagnosticsArea.setValue(moduleLoadingMessage + "Browser does not support WebGPU, Run shader feature is disabled."); + document.getElementById("run-btn").title = "Run shader feature is disabled because the current browser does not support WebGPU."; + } + runIfFullyInitialized(); +} + +function runIfFullyInitialized() +{ + if (compiler && slangd && pageLoaded) + { + const loadingScreen = document.getElementById('loading-screen'); + // Start fade-out by setting opacity to 0 + loadingScreen.style.opacity = '0'; + // Wait for the transition to finish before hiding completely + loadingScreen.addEventListener('transitionend', () => { + loadingScreen.style.display = 'none'; + }); + document.getElementById('contentDiv').style=""; + + restoreSelectedTargetFromURL(); + + if (device) + { + onRun(); + } + } +} diff --git a/build/ui.js b/build/ui.js new file mode 100644 index 0000000..09e1589 --- /dev/null +++ b/build/ui.js @@ -0,0 +1,287 @@ +// target -> profile mappings +const targetProfileMap = { + // TODO: uncomment when we support specifying profiles. + //"SPIRV": {default:"1.5", options:["1.3", "1.4", "1.5", "1.6"]}, +}; + +var entrypointSelect = null; + +// Function to update the profile dropdown based on the selected target +function updateProfileOptions(targetSelect, profileSelect) { + const selectedTarget = targetSelect.value; + // Clear the existing options in profile dropdown + profileSelect.innerHTML = ""; + + // If the selected target does not have any profiles, hide the profile dropdown. + const profiles = targetProfileMap[selectedTarget] || null; + if (!profiles) { + document.getElementById("profile-dropdown").style.display = "none"; + } + else{ + document.getElementById("profile-dropdown").style = ""; + + // Populate the profile dropdown with new options + profiles.options.forEach((profile) => { + const option = document.createElement("option"); + option.value = profile; + option.textContent = profile; + profileSelect.appendChild(option); + }); + profileSelect.value = profiles.default; + } + + // If the target can be compiled as a whole program without entrypoint selection, hide the entrypoint dropdown. + if (isWholeProgramTarget(targetSelect.value)) { + document.getElementById("entrypoint-dropdown").style.display = "none"; + document.getElementById("entrypoint-select").value = ""; + } else { + document.getElementById("entrypoint-dropdown").style = ""; + updateEntryPointOptions(); + } +} + +function updateEntryPointOptions() +{ + if (!compiler) + return; + if (!entrypointSelect) + return; + const prevValue = entrypointSelect.value; + entrypointSelect.innerHTML = ""; + var defaultOption = document.createElement("option"); + defaultOption.value = ""; + defaultOption.textContent = "Entrypoint"; + defaultOption.disabled = true; + entrypointSelect.appendChild(defaultOption); + + const entryPoints = compiler.findDefinedEntryPoints(monacoEditor.getValue()); + var prevValueExists = false; + entryPoints.forEach((entryPoint) => { + const option = document.createElement("option"); + option.value = entryPoint; + option.textContent = entryPoint; + entrypointSelect.appendChild(option); + if (entryPoint === prevValue) + { + option.selected = true; + prevValueExists = true; + } + }); + if (prevValue == "" && entryPoints.length > 0) + entrypointSelect.value = entryPoints[0]; + else if (prevValueExists) + entrypointSelect.value = prevValue; + else + { + entrypointSelect.value = ""; + defaultOption.selected = true; + } +} + +// Set all containers to overflow:hidden before resizing so they can properly shrink. +function prepareForResize() { + var codeEditors = document.getElementsByClassName("editorContainer"); + + for (var i = 0; i < codeEditors.length; i++) { + codeEditors[i].style.overflow = "hidden"; + } + document.getElementById("workSpaceDiv").style.overflow = "hidden"; + document.getElementById("leftContainerDiv").style.overflow = "hidden"; +} +// Restore the containers to overflow:visible after resizing. +function finishResizing() { + var codeEditors = document.getElementsByClassName("editorContainer"); + document.getElementById("workSpaceDiv").style.overflow = "visible"; + document.getElementById("leftContainerDiv").style.overflow = "visible"; + for (var i = 0; i < codeEditors.length; i++) { + codeEditors[i].style.overflow = "visible"; + } +} + +var finishResizingTimeout = null; +window.onresize = function () { + prepareForResize(); + if (finishResizingTimeout) + clearTimeout(finishResizingTimeout); + finishResizingTimeout = setTimeout(() => { + finishResizing(); + finishResizingTimeout = null; + }, 50); +}; + +function initializeModal() { + const modal = document.getElementById("helpModal"); + const btn = document.getElementById("helpButton"); + const closeBtn = document.querySelector(".close"); + + btn.onclick = () => { + modal.style.display = "block"; + }; + + closeBtn.onclick = () => { + modal.style.display = "none"; + }; + + window.onclick = (event) => { + if (event.target === modal) { + modal.style.display = "none"; + } + }; +} + +function handleDemoDropdown() { + const demoDropdown = document.getElementById("demo-dropdown"); + const selectInput = demoDropdown.querySelector(".dropdown-select"); + + selectInput.addEventListener("change", function () { + const selectedDemo = this.value; + switch (selectedDemo) { + case "Circle": + monacoEditor.setValue(defaultShaderCode); + break; + case "Ocean": + monacoEditor.setValue(oceanDemoCode); + break; + case "Empty Image Shader": + monacoEditor.setValue(emptyImageShader); + break; + case "Empty Print Shader": + monacoEditor.setValue(emptyPrintShader); + break; + } + sourceCodeChange = true; + }); +} + +function restoreSelectedTargetFromURL() +{ + const urlParams = new URLSearchParams(window.location.search); + const target = urlParams.get('target'); + if (target) { + const targetSelect = document.getElementById("target-select"); + const profileSelect = document.getElementById("profile-select"); + targetSelect.value = target; + updateProfileOptions(targetSelect, profileSelect); + } +} + +document.addEventListener("DOMContentLoaded", function () { + var initShaderCode = defaultShaderCode; + const urlParams = new URLSearchParams(window.location.search); + const code = urlParams.get('code'); + if (code) { + decompressFromBase64URL(code).then((decompressed) => { + initShaderCode = decompressed; + loadEditor(false, "codeEditor", initShaderCode); + }); + } + else { + loadEditor(false, "codeEditor", defaultShaderCode); + } + loadEditor(true, "diagnostics", "Diagnostic Output"); + loadEditor(true, "codeGen", "Generated Target Code"); + + Split({ + columnGutters: [ + { + track: 1, + element: document.querySelector(".mainContainer > .gutter-horizontal"), + }, + ], + rowGutters: [ + { + track: 1, + element: document.querySelector(".workSpace > .gutter-vertical"), + }, + { + track: 1, + element: document.querySelector(".resultSpace > .gutter-vertical"), + }, + ], + onDragStart: ()=>prepareForResize(), + onDragEnd: ()=>finishResizing(), + }); + handleDemoDropdown(); + + // Target -> Profile handling + const targetSelect = document.getElementById("target-select"); + const profileSelect = document.getElementById("profile-select"); + entrypointSelect = document.getElementById("entrypoint-select"); + entrypointSelect.addEventListener('focus', updateEntryPointOptions); // for keyboard access + entrypointSelect.addEventListener('mousedown', updateEntryPointOptions); // for mouse access + + updateProfileOptions(targetSelect, profileSelect); + + targetSelect.addEventListener("change", () => { + updateProfileOptions(targetSelect, profileSelect); + }); + + // modal functionality + initializeModal(); +}); + + +let pakoLoaded = false; +var pako = null; +// Lazy load function that loads pako on the first call +function loadPako() { + if (pako == null) + pako = BrowserCJS.require("https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.4/pako.min.js"); + return pako; +} + +// Function to compress and decompress text, loading pako if necessary +async function compressToBase64URL(text) { + const pako = loadPako(); // Ensure pako is loaded + + // Compress the text + const compressed = pako.deflate(text, { to: 'string' }); + const base64 = btoa(String.fromCharCode(...new Uint8Array(compressed))); + + return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); +} + +async function decompressFromBase64URL(base64) { + const pako = loadPako(); // Ensure pako is loaded + // Decode the base64 URL + base64 = base64.replace(/-/g, '+').replace(/_/g, '/'); + const compressed = Uint8Array.from(atob(base64), c => c.charCodeAt(0)); + // Decompress the data + const decompressed = pako.inflate(compressed, { to: 'string' }); + + return decompressed; +} + +function showTooltip(button, text) { + document.getElementById("tooltip").textContent = text; + // Position the tooltip near the button + const rect = button.getBoundingClientRect(); + tooltip.style.top = `${rect.bottom + window.scrollY + 15}px`; + tooltip.style.left = `${rect.left + window.scrollX}px`; + + // Show the tooltip + tooltip.classList.add('show'); + + // Hide the tooltip after 3 seconds + setTimeout(() => { + tooltip.classList.remove('show'); + }, 3000); +} + +var btnShareLink = document.getElementById("shareButton"); +btnShareLink.onclick = async function () { + if (!monacoEditor) return; + try{ + const code = monacoEditor.getValue(); + const compressed = await compressToBase64URL(code); + let url = new URL(window.location.href.split('?')[0]); + const compileTarget = document.getElementById("target-select").value; + url.searchParams.set("target", compileTarget) + url.searchParams.set("code", compressed); + navigator.clipboard.writeText(url.href); + showTooltip(btnShareLink, "Link copied to clipboard."); + } + catch(e){ + showTooltip(btnShareLink, "Failed to copy link to clipboard."); + } +}; diff --git a/build/util.js b/build/util.js new file mode 100644 index 0000000..7aa5dcc --- /dev/null +++ b/build/util.js @@ -0,0 +1,27 @@ +function configContext(device, canvas) { + let context = canvas.getContext('webgpu'); + + const canvasConfig = { + device: device, + format: navigator.gpu.getPreferredCanvasFormat(), + usage: + GPUTextureUsage.RENDER_ATTACHMENT, + }; + + context.configure(canvasConfig); + return context; +} + +function createOutputTexture(device, width, height, format) { + const textureDesc = { + label: 'output storage texture', + size: {width: width, height: height}, + format: format, + usage: GPUTextureUsage.COPY_SRC | + GPUTextureUsage.STORAGE_BINDING | + GPUTextureUsage.TEXTURE_BINDING, + }; + + let storageTexture = device.createTexture(textureDesc); + return storageTexture; +} diff --git a/build/utility_module.slang b/build/utility_module.slang new file mode 100644 index 0000000..b429f4c --- /dev/null +++ b/build/utility_module.slang @@ -0,0 +1,4 @@ +export int testFunc(int a) +{ + return a + 1; +} diff --git a/build/water_demo.js b/build/water_demo.js new file mode 100644 index 0000000..7c069bb --- /dev/null +++ b/build/water_demo.js @@ -0,0 +1,235 @@ +const oceanDemoCode = +` +// afl_ext 2017-2024 +// MIT License +import playground; + +#define DRAG_MULT 0.38 // changes how much waves pull on the water +#define WATER_DEPTH 1.0 // how deep is the water +#define CAMERA_HEIGHT 1.5 // how high the camera should be +#define ITERATIONS_RAYMARCH 12 // waves iterations of raymarching +#define ITERATIONS_NORMAL 37 // waves iterations when calculating normals + + +// Calculates wave value and its derivative, +// for the wave direction, position in space, wave frequency and time +float2 wavedx(float2 position, float2 direction, float frequency, float timeshift) { + float x = dot(direction, position) * frequency + timeshift; + float wave = exp(sin(x) - 1.0); + float dx = wave * cos(x); + return float2(wave, -dx); +} + +// Calculates waves by summing octaves of various waves with various parameters +float getwaves(float2 position, int iterations) { + float wavePhaseShift = length(position) * 0.1; // this is to avoid every octave having exactly the same phase everywhere + float iter = 0.0; // this will help generating well distributed wave directions + float frequency = 1.0; // frequency of the wave, this will change every iteration + float timeMultiplier = 0.5; // time multiplier for the wave, this will change every iteration + float weight = 1.0;// weight in final sum for the wave, this will change every iteration + float sumOfValues = 0.0; // will store final sum of values + float sumOfWeights = 0.0; // will store final sum of weights + for(int i=0; i < iterations; i++) { + // generate some wave direction that looks kind of random + float2 p = float2(sin(iter), cos(iter)); + + // calculate wave data + float2 res = wavedx(position, p, frequency, getTime() * timeMultiplier + wavePhaseShift); + + // shift position around according to wave drag and derivative of the wave + position += p * res.y * weight * DRAG_MULT; + + // add the results to sums + sumOfValues += res.x * weight; + sumOfWeights += weight; + + // modify next octave ; + weight = lerp(weight, 0.0, 0.2); + frequency *= 1.18; + timeMultiplier *= 1.07; + + // add some kind of random value to make next wave look random too + iter += 1232.399963; + } + // calculate and return + return sumOfValues / sumOfWeights; +} + +float3 interpolation(float3 x, float3 y, float factor) +{ + return x + (y - x) * factor; +} + +// Raymarches the ray from top water layer boundary to low water layer boundary +float raymarchwater(float3 camera, float3 start, float3 end, float depth) { + float3 pos = start; + float3 dir = normalize(end - start); + for(int i=0; i < 64; i++) { + // the height is from 0 to -depth + float height = getwaves(pos.xz, ITERATIONS_RAYMARCH) * depth - depth; + // if the waves height almost nearly matches the ray height, assume its a hit and return the hit distance + if(height + 0.01 > pos.y) { + return distance(pos, camera); + } + // iterate forwards according to the height mismatch + pos += dir * (pos.y - height); + } + // if hit was not registered, just assume hit the top layer, + // this makes the raymarching faster and looks better at higher distances + return distance(start, camera); +} + +// Calculate normal at point by calculating the height at the pos and 2 additional points very close to pos +float3 normal(float2 pos, float e, float depth) { + float2 ex = float2(e, 0); + float H = getwaves(pos.xy, ITERATIONS_NORMAL) * depth; + float3 a = float3(pos.x, H, pos.y); + return normalize( + cross( + a - float3(pos.x - e, getwaves(pos.xy - ex.xy, ITERATIONS_NORMAL) * depth, pos.y), + a - float3(pos.x, getwaves(pos.xy + ex.yx, ITERATIONS_NORMAL) * depth, pos.y + e) + ) + ); +} + +// Helper function generating a rotation matrix around the axis by the angle +float3x3 createRotationMatrixAxisAngle(float3 axis, float angle) { + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; + return float3x3( + oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c + ); +} + +// Helper function that generates camera ray based on UV and mouse +float3 getRay(float2 fragCoord, float2 resolution) { + float2 uv = ((fragCoord.xy / resolution.xy) * 2.0 - 1.0) * float2(resolution.x / resolution.y, 1.0); + // for fisheye, uncomment following line and comment the next one + //float3 proj = normalize(float3(uv.x, uv.y, 1.0) + float3(uv.x, uv.y, -1.0) * pow(length(uv), 2.0) * 0.05); + float3 proj = normalize(float3(uv.x, uv.y, 1.5)); + if(resolution.x < 600.0) { + return proj; + } + float3x3 mat = mul(createRotationMatrixAxisAngle(float3(0.0, -1.0, 0.0), 0.0), + createRotationMatrixAxisAngle(float3(1.0, 0.0, 0.0), 0.0) + ); + return mul(mat, proj); +} + +// Ray-Plane intersection checker +float intersectPlane(float3 origin, float3 direction, float3 point, float3 normal) { + return clamp(dot(point - origin, normal) / dot(direction, normal), -1.0, 9991999.0); +} + +// Some very barebones but fast atmosphere approximation +float3 extra_cheap_atmosphere(float3 raydir, float3 sundir) { + sundir.y = max(sundir.y, -0.07); + float special_trick = 1.0 / (raydir.y * 1.0 + 0.1); + float special_trick2 = 1.0 / (sundir.y * 11.0 + 1.0); + float raysundt = pow(abs(dot(sundir, raydir)), 2.0); + float sundt = pow(max(0.0, dot(sundir, raydir)), 8.0); + float mymie = sundt * special_trick * 0.2; + float3 suncolor = lerp(float3(1.0), max(float3(0.0), float3(1.0) - float3(5.5, 13.0, 22.4) / 22.4), special_trick2); + float3 bluesky= float3(5.5, 13.0, 22.4) / 22.4 * suncolor; + float3 bluesky2 = max(float3(0.0), bluesky - float3(5.5, 13.0, 22.4) * 0.002 * (special_trick + -6.0 * sundir.y * sundir.y)); + bluesky2 *= special_trick * (0.24 + raysundt * 0.24); + return bluesky2 * (1.0 + 1.0 * pow(1.0 - raydir.y, 3.0)); +} + +// Calculate where the sun should be, it will be moving around the sky +float3 getSunDirection() { + float time = getTime(); + return normalize(float3(sin(time * 0.1), 1.0, cos(time * 0.1))); +} + +// Get atmosphere color for given direction +float3 getAtmosphere(float3 dir) { + float time = getTime(); + return extra_cheap_atmosphere(dir, getSunDirection()) * 0.5; +} + +// Get sun color for given direction +float getSun(float3 dir) { + float time = getTime(); + return pow(max(0.0, dot(dir, getSunDirection())), 720.0) * 210.0; +} + +// Great tonemapping function from my other shader: https://www.shadertoy.com/view/XsGfWV +float3 aces_tonemap(float3 color) { + float3x3 m1 = float3x3( + 0.59719, 0.07600, 0.02840, + 0.35458, 0.90834, 0.13383, + 0.04823, 0.01566, 0.83777 + ); + + float3x3 m2 = float3x3( + 1.60475, -0.10208, -0.00327, + -0.53108, 1.10813, -0.07276, + -0.07367, -0.00605, 1.07602 + ); + + float3 v = mul(m1, color); + float3 a = v * (v + 0.0245786) - 0.000090537; + float3 b = v * (0.983729 * v + 0.4329510) + 0.238081; + return pow(clamp(mul(m2, (a / b)), 0.0, 1.0), float3(1.0 / 2.2)); +} + +float4 imageMain(uint2 dispatchThreadID, int2 screenSize) +{ + float2 size = float2(screenSize.x, screenSize.y); + + // get the ray + float3 ray = getRay(dispatchThreadID.xy, size); + if(ray.y >= 0.0) { + // if ray.y is positive, render the sky + float3 C = getAtmosphere(ray) + getSun(ray); + float4 color = float4(aces_tonemap(C * 2.0),1.0); + return color; + } + + // now ray.y must be negative, water must be hit + // define water planes + float3 waterPlaneHigh = float3(0.0, 0.0, 0.0); + float3 waterPlaneLow = float3(0.0, -WATER_DEPTH, 0.0); + + // define ray origin, moving around + float3 origin = float3(getTime() * 0.2, CAMERA_HEIGHT, 1); + + // calculate intersections and reconstruct positions + float highPlaneHit = intersectPlane(origin, ray, waterPlaneHigh, float3(0.0, 1.0, 0.0)); + float lowPlaneHit = intersectPlane(origin, ray, waterPlaneLow, float3(0.0, 1.0, 0.0)); + float3 highHitPos = origin + ray * highPlaneHit; + float3 lowHitPos = origin + ray * lowPlaneHit; + + // raymatch water and reconstruct the hit pos + float dist = raymarchwater(origin, highHitPos, lowHitPos, WATER_DEPTH); + float3 waterHitPos = origin + ray * dist; + + // calculate normal at the hit position + float3 N = normal(waterHitPos.xz, 0.01, WATER_DEPTH); + + // smooth the normal with distance to avoid disturbing high frequency noise + float interpFactor = 0.8 * min(1.0, sqrt(dist*0.01) * 1.1); + // N = lerp(N, float3(0.0, 1.0, 0.0), interpFactor); + N = interpolation(N, float3(0.0, 1.0, 0.0), interpFactor); + + // calculate fresnel coefficient + float fresnel = (0.04 + (1.0-0.04)*(pow(1.0 - max(0.0, dot(-N, ray)), 5.0))); + + // reflect the ray and make sure it bounces up + float3 R = normalize(reflect(ray, N)); + R.y = abs(R.y); + + // calculate the reflection and approximate subsurface scattering + float3 reflection = getAtmosphere(R) + getSun(R); + float3 scattering = float3(0.0293, 0.0698, 0.1717) * 0.1 * (0.2 + (waterHitPos.y + WATER_DEPTH) / WATER_DEPTH); + + // return the combined result + float3 C = fresnel * reflection + scattering; + float4 color = float4(aces_tonemap(C * 2.0), 1.0); + return color; +} +`; diff --git a/compiler.js b/compiler.js index 308ec18..9af2769 100644 --- a/compiler.js +++ b/compiler.js @@ -39,16 +39,6 @@ void imageMain(uint3 dispatchThreadID : SV_DispatchThreadID) } `; -const playgroundSource = ` -internal uniform float time; - -// Return the current time in milliseconds -public float getTime() -{ - return time; -} - -`; const printMainSource = ` import user; @@ -80,7 +70,8 @@ import playground; int printMain() { - return 1; + print("%d\\n", 0); + return 0; } `; @@ -108,6 +99,9 @@ class SlangCompiler mainModules = new Map(); + // store the string hash if appears in the shader code + hashedString = null; + constructor(module) { this.slangWasmModule = module; @@ -197,7 +191,6 @@ class SlangCompiler spirvDisassembly(spirvBinary) { - const disAsmCode = this.spirvToolsModule.dis( spirvBinary, this.spirvToolsModule.SPV_ENV_UNIVERSAL_1_3, @@ -393,6 +386,12 @@ class SlangCompiler compile(shaderSource, entryPointName, compileTargetStr, stage) { this.diagnosticsMsg = ""; + if (this.hashedString) + { + this.hashedString.delete(); + this.hashedString = null; + } + const compileTarget = this.compileTargetMap.findCompileTarget(compileTargetStr); let isWholeProgram = isWholeProgramTarget(compileTargetStr); @@ -423,6 +422,7 @@ class SlangCompiler var program = slangSession.createCompositeComponentType(components); var linkedProgram = program.link(); + this.hashedString = linkedProgram.loadStrings(); var outCode; if (compileTargetStr == "SPIRV") @@ -441,7 +441,8 @@ class SlangCompiler 0 /* entryPointIndex */, 0 /* targetIndex */); } - if(outCode == "") { + if (outCode == "") + { var error = this.slangWasmModule.getLastError(); console.error(error.type + " error: " + error.message); this.diagnosticsMsg += (error.type + " error: " + error.message); diff --git a/compute.js b/compute.js index 794ccdc..59cefae 100644 --- a/compute.js +++ b/compute.js @@ -10,6 +10,12 @@ class ComputePipeline uniformBuffer; uniformBufferHost = new Float32Array(4); + + printfBufferElementSize = 12; + printfBufferSize = this.printfBufferElementSize * 100; // 16 bytes per printf struct + printfBuffer; + printfBufferRead; + outputBuffer; outputBufferRead; outputTexture; @@ -29,7 +35,8 @@ class ComputePipeline entries: [ {binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'uniform'}}, {binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, - {binding: 2, visibility: GPUShaderStage.COMPUTE, storageTexture: {access: "read-write", format: this.outputTexture.format}}, + {binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, + {binding: 3, visibility: GPUShaderStage.COMPUTE, storageTexture: {access: "read-write", format: this.outputTexture.format}}, ], }; @@ -57,8 +64,9 @@ class ComputePipeline layout: this.pipeline.getBindGroupLayout(0), entries: [ { binding: 0, resource: { buffer: this.uniformBuffer }}, - { binding: 1, resource: { buffer: this.outputBuffer }}, - { binding: 2, resource: this.outputTexture.createView() }, + { binding: 1, resource: { buffer: this.printfBuffer }}, + { binding: 2, resource: { buffer: this.outputBuffer }}, + { binding: 3, resource: this.outputTexture.createView() }, ], }); @@ -79,6 +87,18 @@ class ComputePipeline this.outputBufferRead = null; } + if (this.printfBuffer) + { + this.printfBuffer.destroy(); + this.printfBuffer = null; + } + + if (this.printfBufferRead) + { + this.printfBufferRead.destroy(); + this.printfBufferRead = null; + } + if (this.outputTexture) { this.outputTexture.destroy(); @@ -100,9 +120,11 @@ class ComputePipeline const size = numberElements * 4; // int type this.outputBuffer = this.device.createBuffer({lable: 'outputBuffer', size, usage}); + this.printfBuffer = this.device.createBuffer({lable: 'outputBuffer', size: this.printfBufferSize, usage}); + usage = GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST; - const outputBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size, usage}); - this.outputBufferRead = outputBufferRead; + this.outputBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size, usage}); + this.printfBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size: this.printfBufferSize, usage}); const storageTexture = createOutputTexture(device, windowSize[0], windowSize[1], 'r32float'); this.outputTexture = storageTexture; @@ -126,4 +148,56 @@ class ComputePipeline this.createOutput(true, windowSize); this.createComputePipelineLayout(); } + + + // This is the definition of the printf buffer. + // struct FormatedStruct + // { + // uint32_t type = 0xFFFFFFFF; + // uint32_t low = 0; + // uint32_t high = 0; + // }; + parsePrintfBuffer(hashedString) + { + const printfBufferArray = new Uint32Array(computePipeline.printfBufferRead.getMappedRange()) + var elementIndex = 0; + var numberElements = printfBufferArray.byteLength / this.printfBufferElementSize; + + var formatString; + if (printfBufferArray[0] == 1) // type field + { + formatString = hashedString.getString(printfBufferArray[1]); // low field + } + + // TODO: We currently doesn't support 64-bit data type (e.g. uint64_t, int64_t, double, etc.) + // so 32-bit array should be able to contain everything we need. + var dataArray = new Uint32Array(numberElements); + var stringArray = []; + const elementSizeInWords = this.printfBufferElementSize / 4; + for (elementIndex = 1; elementIndex < numberElements; elementIndex++) + { + var offset = elementIndex * elementSizeInWords; + const type = printfBufferArray[offset]; + + if (type == 1) // type field, this is a string + { + stringArray.push(hashedString.getString(printfBufferArray[offset + 1])); // low field + } + else if (type == 2) // type field + { + dataArray[elementIndex - 1] = printfBufferArray[offset + 1]; // low field + } + else if (type == 0xFFFFFFFF) + { + break; + } + } + + return {formatString: formatString, dataArray: dataArray.slice(0, elementIndex - 1), stringArray: stringArray}; + } + + // TODO: construct the final formatted result + formatToString(formatString, dataArray, stringArray) + { + } } diff --git a/index.html b/index.html index f934226..ebd7317 100644 --- a/index.html +++ b/index.html @@ -45,6 +45,7 @@ ); + diff --git a/playgroundShader.js b/playgroundShader.js new file mode 100644 index 0000000..2eb90b2 --- /dev/null +++ b/playgroundShader.js @@ -0,0 +1,83 @@ + +const playgroundSource = ` +internal uniform float time; + +// Return the current time in milliseconds +public float getTime() +{ + return time; +} + +struct FormatedStruct +{ + uint32_t type = 0xFFFFFFFF; + uint32_t low = 0; + uint32_t high = 0; +}; + +internal RWStructuredBuffer g_printedBuffer; + +interface IPrintf +{ + uint32_t typeFlag(); + uint32_t writePrintfWords(); +}; + +extension uint : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return (uint32_t)this; } +} + +extension int : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return (uint32_t)this; } +} + +// extension int64_t : IPrintf +// { +// uint64_t writePrintfWords() { return (uint64_t)this; } +// } + +// extension uint64_t : IPrintf +// { +// uint64_t writePrintfWords() { return (uint64_t)this; } +// } + +extension float : IPrintf +{ + uint32_t typeFlag() { return 2;} + uint32_t writePrintfWords() { return bit_cast(this); } +} + +// extension double : IPrintf +// { +// uint64_t writePrintfWords() { return bit_cast(this); } +// } + +extension String : IPrintf +{ + uint32_t typeFlag() { return 1;} + uint32_t writePrintfWords() { return getStringHash(this); } +} + +void handleEach(T value, int index) where T : IPrintf +{ + g_printedBuffer[index].type = value.typeFlag(); + g_printedBuffer[index].low = value.writePrintfWords(); +} + +public void print(String format, expand each T values) where T : IPrintf +{ + //if (format.length != 0) + { + g_printedBuffer[0].type = 1; + g_printedBuffer[0].low = getStringHash(format); + int index = 1; + expand(handleEach(each values, index++)); + + g_printedBuffer[index] = {}; + } +} +`; diff --git a/try-slang.js b/try-slang.js index 65112bf..9bd7e04 100644 --- a/try-slang.js +++ b/try-slang.js @@ -232,6 +232,7 @@ async function printResult() // copy output buffer back in print mode encoder.copyBufferToBuffer(computePipeline.outputBuffer, 0, computePipeline.outputBufferRead, 0, computePipeline.outputBuffer.size); + encoder.copyBufferToBuffer(computePipeline.printfBuffer, 0, computePipeline.printfBufferRead, 0, computePipeline.printfBuffer.size); // Finish encoding and submit the commands const commandBuffer = encoder.finish(); @@ -239,26 +240,31 @@ async function printResult() await device.queue.onSubmittedWorkDone(); // Read the results once the job is done - await computePipeline.outputBufferRead.mapAsync(GPUMapMode.READ); + await Promise.all([ + computePipeline.outputBufferRead.mapAsync(GPUMapMode.READ), + computePipeline.printfBufferRead.mapAsync(GPUMapMode.READ)]); const output = new Int32Array(computePipeline.outputBufferRead.getMappedRange()); - const textResult = output.toString() + "\n"; + // debug testing: + let textResult = output.toString() + "\n"; + if (compiler.hashedString) + { + const result = computePipeline.parsePrintfBuffer(compiler.hashedString) + textResult += "Format string: " + result.formatString + "\n"; + textResult += "Data view: " + result.dataArray.toString() + "\n"; + textResult += "String view: " + result.stringArray.toString() + "\n"; + } computePipeline.outputBufferRead.unmap(); + computePipeline.printfBufferRead.unmap(); document.getElementById("printResult").value = textResult; } -function formatResult(output) +function parsePrintfBuffer(buffer) { - var result = ""; - for (let i = 0; i < output.length; i++) - { - result += output[i] + '\n'; - } - return result; } function checkShaderType(userSource) From 419093b41dfcd0149812112005cfa3e4c4fd9276 Mon Sep 17 00:00:00 2001 From: kaizhangNV Date: Wed, 30 Oct 2024 22:02:28 -0700 Subject: [PATCH 2/4] remove the WAR of encoding color to one chanel float --- build/README.md | 43 --- build/compiler.js | 478 ------------------------ build/compute.js | 203 ---------- build/index.html | 235 ------------ build/language-server.js | 722 ------------------------------------ build/pass_through.js | 141 ------- build/playgoundShader.js | 83 ----- build/playgroundShader.js | 83 ----- build/spirv-tools.js | 19 - build/spirv-tools.wasm | Bin 383130 -> 0 bytes build/static/slang-logo.png | Bin 32070 -> 0 bytes build/styles/styles.css | 449 ---------------------- build/try-slang.js | 520 -------------------------- build/ui.js | 287 -------------- build/util.js | 27 -- build/utility_module.slang | 4 - build/water_demo.js | 235 ------------ compiler.js | 15 +- compute.js | 6 +- pass_through.js | 9 +- try-slang.js | 5 - 21 files changed, 13 insertions(+), 3551 deletions(-) delete mode 100644 build/README.md delete mode 100644 build/compiler.js delete mode 100644 build/compute.js delete mode 100644 build/index.html delete mode 100644 build/language-server.js delete mode 100644 build/pass_through.js delete mode 100644 build/playgoundShader.js delete mode 100644 build/playgroundShader.js delete mode 100644 build/spirv-tools.js delete mode 100755 build/spirv-tools.wasm delete mode 100644 build/static/slang-logo.png delete mode 100644 build/styles/styles.css delete mode 100644 build/try-slang.js delete mode 100644 build/ui.js delete mode 100644 build/util.js delete mode 100644 build/utility_module.slang delete mode 100644 build/water_demo.js diff --git a/build/README.md b/build/README.md deleted file mode 100644 index aca0f70..0000000 --- a/build/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# SPIRV-Tools - -Wasm (WebAssembly) build of https://github.com/KhronosGroup/SPIRV-Tools - -## Usage - -```js -const spirvTools = require("spirv-tools"); - -const test = async () => { - // Load the library - const spv = await spirvTools(); - - // assemble - const source = ` - OpCapability Linkage - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpSource GLSL 450 - OpDecorate %spec SpecId 1 - %int = OpTypeInt 32 1 - %spec = OpSpecConstant %int 0 - %const = OpConstant %int 42`; - const asResult = spv.as( - source, - spv.SPV_ENV_UNIVERSAL_1_3, - spv.SPV_TEXT_TO_BINARY_OPTION_NONE - ); - console.log(`as returned ${asResult.byteLength} bytes`); - - // re-disassemble - const disResult = spv.dis( - asResult, - spv.SPV_ENV_UNIVERSAL_1_3, - spv.SPV_BINARY_TO_TEXT_OPTION_INDENT | - spv.SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | - spv.SPV_BINARY_TO_TEXT_OPTION_COLOR - ); - console.log("dis:\n", disResult); -}; - -test(); -``` diff --git a/build/compiler.js b/build/compiler.js deleted file mode 100644 index 9af2769..0000000 --- a/build/compiler.js +++ /dev/null @@ -1,478 +0,0 @@ -function isWholeProgramTarget(compileTarget) -{ - return compileTarget == "METAL" || compileTarget == "SPIRV"; -} - -const imageMainSource = ` -import user; -import playground; - -RWStructuredBuffer outputBuffer; -[format("r32f")] RWTexture2D texture; - -inline float encodeColor(float4 color) -{ - uint4 colorInt = { uint(color.x * 255.0f), - uint(color.y * 255.0f), - uint(color.z * 255.0f), - uint(color.w * 255.0f) }; - - float encodedColor = float(colorInt.x << 24 | colorInt.y << 16 | colorInt.z << 8 | colorInt.w); - return encodedColor; -} - -[shader("compute")] -[numthreads(16, 16, 1)] -void imageMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - uint width = 0; - uint height = 0; - texture.GetDimensions(width, height); - - if (dispatchThreadID.x >= width || dispatchThreadID.y >= height) - return; - - float4 color = imageMain(dispatchThreadID.xy, int2(width, height)); - float encodedColor = encodeColor(color); - - texture[dispatchThreadID.xy] = encodedColor; -} -`; - - -const printMainSource = ` -import user; -import playground; - -RWStructuredBuffer outputBuffer; -[format("r32f")] RWTexture2D texture; - -[shader("compute")] -[numthreads(1, 1, 1)] -void printMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - int res = printMain(); - outputBuffer[0] = res; -} -`; - -const emptyImageShader = ` -import playground; - -float4 imageMain(uint2 dispatchThreadID, int2 screenSize) -{ - return float4(0); -} -`; - -const emptyPrintShader = ` -import playground; - -int printMain() -{ - print("%d\\n", 0); - return 0; -} -`; - - -class SlangCompiler -{ - static SLANG_STAGE_VERTEX = 1; - static SLANG_STAGE_FRAGMENT = 5; - static SLANG_STAGE_COMPUTE = 6; - - static RENDER_SHADER = 0; - static PRINT_SHADER = 1; - static NON_RUNNABLE_SHADER = 2; - - globalSlangSession = null; - slangSession = null; - - compileTargetMap = null; - - slangWasmModule; - diagnosticsMsg; - shaderType; - - spirvToolsModule = null; - - mainModules = new Map(); - - // store the string hash if appears in the shader code - hashedString = null; - - constructor(module) - { - this.slangWasmModule = module; - this.diagnosticsMsg = ""; - this.shaderType = SlangCompiler.NON_RUNNABLE_SHADER; - this.mainModules['imageMain'] = {source: imageMainSource}; - this.mainModules['printMain'] = {source: printMainSource}; - FS.createDataFile("/", "user.slang", "", true, true); - FS.createDataFile("/", "playground.slang", "", true, true); - } - - init() - { - try { - this.globalSlangSession = this.slangWasmModule.createGlobalSession(); - this.compileTargetMap = this.slangWasmModule.getCompileTargets(); - - if(!this.globalSlangSession || !this.compileTargetMap) - { - var error = this.slangWasmModule.getLastError(); - return {ret: false, msg: (error.type + " error: " + error.message)}; - } - else - { - return {ret: true, msg: ""}; - } - } catch (e) { - console.log(e); - return {ret: false, msg: '' + e}; - } - } - - // In our playground, we only allow to run shaders with two entry points: renderMain and printMain - findRunnableEntryPoint(module) - { - const runnableEntryPointNames = ['imageMain', 'printMain']; - for (var i = 0; i < runnableEntryPointNames.length; i++) - { - var entryPointName = runnableEntryPointNames[i]; - var entryPoint = module.findAndCheckEntryPoint(entryPointName, SlangCompiler.SLANG_STAGE_COMPUTE); - if(entryPoint) - { - if (i == 0) - this.shaderType = SlangCompiler.RENDER_SHADER; - else - this.shaderType = SlangCompiler.PRINT_SHADER; - return entryPoint; - } - } - - return null; - } - - findEntryPoint(module, entryPointName, stage) - { - if (entryPointName == null || entryPointName == "") - { - var entryPoint = this.findRunnableEntryPoint(module); - if (!entryPoint) - { - this.diagnosticsMsg += "Warning: The current shader code is not runnable because 'imageMain' or 'printMain' functions are not found.\n"; - this.diagnosticsMsg += "Use the 'Compile' button to compile it to different targets.\n"; - } - return entryPoint; - } - else - { - var entryPoint = module.findAndCheckEntryPoint(entryPointName, stage); - if(!entryPoint) { - var error = this.slangWasmModule.getLastError(); - console.error(error.type + " error: " + error.message); - this.diagnosticsMsg += (error.type + " error: " + error.message); - return null; - } - return entryPoint; - } - } - - async initSpirvTools() - { - if (!this.spirvToolsModule) - { - const spirvTools = BrowserCJS.require("./spirv-tools.js"); - this.spirvToolsModule = await spirvTools(); - } - } - - spirvDisassembly(spirvBinary) - { - const disAsmCode = this.spirvToolsModule.dis( - spirvBinary, - this.spirvToolsModule.SPV_ENV_UNIVERSAL_1_3, - this.spirvToolsModule.SPV_BINARY_TO_TEXT_OPTION_INDENT | - this.spirvToolsModule.SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES - ); - - - if (disAsmCode == "Error") - { - this.diagnosticsMsg += ("SPIRV disassembly error"); - disAsmCode = ""; - } - - return disAsmCode; - } - - // If user code defines imageMain or printMain, we will know the entry point name because they're - // already defined in our pre-built module. So we will add those one of those entry points to the - // dropdown list. Then, we will find whether user code also defines other entry points, if it has - // we will also add them to the dropdown list. - findDefinedEntryPoints(shaderSource) - { - var result = []; - try { - var slangSession = this.globalSlangSession.createSession( - this.compileTargetMap.findCompileTarget("SPIRV")); - if(!slangSession) { - return []; - } - - if (shaderSource.match("imageMain")) - result.push("imageMain") - - if (shaderSource.match("printMain")) - result.push("printMain") - - var module = slangSession.loadModuleFromSource(shaderSource, "user", "/user.slang"); - if(!module) { - return result; - } - - var count = module.getDefinedEntryPointCount(); - for (var i = 0; i < count; i++) - { - var entryPoint = module.getDefinedEntryPoint(i); - const entryPointName = entryPoint.getName(); - - result.push(entryPoint.getName()); - entryPoint.delete(); - } - } catch (e) { - return []; - } - finally { - if(module) { - module.delete(); - } - if (slangSession) { - slangSession.delete(); - } - } - return result; - } - - // If user entrypoint name imageMain or printMain, we will load the pre-built main modules because they - // are defined in those modules. Otherwise, we will only need to load the user module and find the entry - // point in the user module. - shouldLoadMainModule(entryPointName) - { - return entryPointName == "imageMain" || entryPointName == "printMain"; - } - - // Since we will not let user to change the entry point code, we can precompile the entry point module - // and reuse it for every compilation. - - compileEntryPointModule(slangSession, moduleName) - { - var module = slangSession.loadModuleFromSource(this.mainModules[moduleName].source, moduleName, '/' + moduleName + '.slang'); - - if (!module) { - var error = this.slangWasmModule.getLastError(); - console.error(error.type + " error: " + error.message); - this.diagnosticsMsg+=(error.type + " error: " + error.message); - return null; - } - - // we use the same entry point name as module name - var entryPoint = this.findEntryPoint(module, moduleName, SlangCompiler.SLANG_STAGE_COMPUTE); - if (!entryPoint) - return null; - - return {module: module, entryPoint: entryPoint}; - - } - - getPrecompiledProgram(slangSession, moduleName) - { - if (moduleName != "printMain" && moduleName != "imageMain") - return null; - - let mainModule = this.compileEntryPointModule(slangSession, moduleName); - - this.shaderType = SlangCompiler.RENDER_SHADER; - return mainModule; - } - - addActiveEntryPoints(slangSession, shaderSource, entryPointName, isWholeProgram, userModule, componentList) - { - if (entryPointName == "" && !isWholeProgram) - { - this.diagnosticsMsg+=("error: No entry point specified"); - return false; - } - - // For now, we just don't allow user to define imageMain or printMain as entry point name for simplicity - var count = userModule.getDefinedEntryPointCount(); - for (var i = 0; i < count; i++) - { - var entryPointName = userModule.getDefinedEntryPoint(i).getName(); - if (entryPointName == "imageMain" || entryPointName == "printMain") - { - this.diagnosticsMsg+=("error: Entry point name 'imageMain' or 'printMain' is reserved"); - return false; - } - } - - // If entry point is provided, we know for sure this is not a whole program compilation, - // so we will just go to find the correct module to include in the compilation. - if (entryPointName != "") - { - if (this.shouldLoadMainModule(entryPointName)) - { - // we use the same entry point name as module name - var mainProgram = this.getPrecompiledProgram(slangSession, entryPointName); - if (!mainProgram) - return false; - - this.shaderType = entryPointName == "imageMain" ? - SlangCompiler.RENDER_SHADER : SlangCompiler.PRINT_SHADER; - - componentList.push_back(mainProgram.module); - componentList.push_back(mainProgram.entryPoint); - } - else - { - // we know the entry point is from user module - var entryPoint = this.findEntryPoint(userModule, entryPointName, SlangCompiler.SLANG_STAGE_COMPUTE); - if (!entryPoint) - return false; - - componentList.push_back(entryPoint); - } - } - // otherwise, it's a whole program compilation, we will find all active entry points in the user code - // and pre-built modules. - else - { - const results = this.findDefinedEntryPoints(shaderSource); - for (let i = 0; i < results.length; i++) - { - if (results[i] == "imageMain" || results[i] == "printMain") - { - var mainProgram = this.getPrecompiledProgram(slangSession, results[i]); - componentList.push_back(mainProgram.module); - componentList.push_back(mainProgram.entryPoint); - } - else - { - var entryPoint = this.findEntryPoint(userModule, results[i], SlangCompiler.SLANG_STAGE_COMPUTE); - if (!entryPoint) - return false; - - componentList.push_back(entryPoint); - } - } - } - } - - loadModule(slangSession, moduleName, source, componentTypeList) - { - var module = slangSession.loadModuleFromSource(source, moduleName, "/"+ moduleName + ".slang"); - if(!module) { - var error = this.slangWasmModule.getLastError(); - console.error(error.type + " error: " + error.message); - this.diagnosticsMsg+=(error.type + " error: " + error.message); - return false; - } - componentTypeList.push_back(module); - return true; - } - - compile(shaderSource, entryPointName, compileTargetStr, stage) - { - this.diagnosticsMsg = ""; - if (this.hashedString) - { - this.hashedString.delete(); - this.hashedString = null; - } - - const compileTarget = this.compileTargetMap.findCompileTarget(compileTargetStr); - let isWholeProgram = isWholeProgramTarget(compileTargetStr); - - if(!compileTarget) { - this.diagnosticsMsg = "unknown compile target: " + compileTargetStr; - return null; - } - - try { - var slangSession = this.globalSlangSession.createSession(compileTarget); - if(!slangSession) { - var error = this.slangWasmModule.getLastError(); - console.error(error.type + " error: " + error.message); - this.diagnosticsMsg += (error.type + " error: " + error.message); - return null; - } - - var components = new this.slangWasmModule.ComponentTypeList(); - - if (!this.loadModule(slangSession, "playground", playgroundSource, components)) - return null; - - if (!this.loadModule(slangSession, "user", shaderSource, components)) - return null; - - if (this.addActiveEntryPoints(slangSession, shaderSource, entryPointName, isWholeProgram, components.get(1), components) == false) - return null; - - var program = slangSession.createCompositeComponentType(components); - var linkedProgram = program.link(); - this.hashedString = linkedProgram.loadStrings(); - - var outCode; - if (compileTargetStr == "SPIRV") - { - const spirvCode = linkedProgram.getTargetCodeBlob( - 0 /* targetIndex */ - ); - outCode = this.spirvDisassembly(spirvCode); - } - else - { - if (isWholeProgram) - outCode = linkedProgram.getTargetCode(0); - else - outCode = linkedProgram.getEntryPointCode( - 0 /* entryPointIndex */, 0 /* targetIndex */); - } - - if (outCode == "") - { - var error = this.slangWasmModule.getLastError(); - console.error(error.type + " error: " + error.message); - this.diagnosticsMsg += (error.type + " error: " + error.message); - return null; - } - } catch (e) { - console.log(e); - return null; - } - finally { - if(linkedProgram) { - linkedProgram.delete(); - } - if(program) { - program.delete(); - } - - if (components) - { - for (let i = 0; i < components.size(); i++) - { - components.get(i).delete(); - } - components.delete(); - } - - if (slangSession) { - slangSession.delete(); - } - return outCode; - } - } -}; diff --git a/build/compute.js b/build/compute.js deleted file mode 100644 index 59cefae..0000000 --- a/build/compute.js +++ /dev/null @@ -1,203 +0,0 @@ - -class ComputePipeline -{ - pipeline; - pipelineLayout; - - // TODO: We should make this field optional, and only when user select a "Debug" mode will this option be available, - // and we will output this buffer to the output area. - - uniformBuffer; - uniformBufferHost = new Float32Array(4); - - - printfBufferElementSize = 12; - printfBufferSize = this.printfBufferElementSize * 100; // 16 bytes per printf struct - printfBuffer; - printfBufferRead; - - outputBuffer; - outputBufferRead; - outputTexture; - device; - bindGroup; - - constructor(device) - { - this.device = device; - } - - createComputePipelineLayout() - { - // We fill fix our bind group layout to have 2 entries in our playground. - const bindGroupLayoutDescriptor = { - lable: 'compute pipeline bind group layout', - entries: [ - {binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'uniform'}}, - {binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, - {binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, - {binding: 3, visibility: GPUShaderStage.COMPUTE, storageTexture: {access: "read-write", format: this.outputTexture.format}}, - ], - }; - - const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); - const layout = device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout]}); - - this.pipelineLayout = layout; - } - - createPipeline(shaderModule) - { - const pipeline = device.createComputePipeline({ - label: 'compute pipeline', - layout: this.pipelineLayout, - compute: {module: shaderModule}, - }); - - this.pipeline = pipeline; - this.createBindGroup(); - } - - createBindGroup() - { - const bindGroup = device.createBindGroup({ - layout: this.pipeline.getBindGroupLayout(0), - entries: [ - { binding: 0, resource: { buffer: this.uniformBuffer }}, - { binding: 1, resource: { buffer: this.printfBuffer }}, - { binding: 2, resource: { buffer: this.outputBuffer }}, - { binding: 3, resource: this.outputTexture.createView() }, - ], - }); - - this.bindGroup = bindGroup; - } - - destroyResources() - { - if (this.outputBuffer) - { - this.outputBuffer.destroy(); - this.outputBuffer = null; - } - - if (this.outputBufferRead) - { - this.outputBufferRead.destroy(); - this.outputBufferRead = null; - } - - if (this.printfBuffer) - { - this.printfBuffer.destroy(); - this.printfBuffer = null; - } - - if (this.printfBufferRead) - { - this.printfBufferRead.destroy(); - this.printfBufferRead = null; - } - - if (this.outputTexture) - { - this.outputTexture.destroy(); - this.outputTexture = null; - } - } - // All out compute pipeline will have 2 outputs: - // 1. A buffer that will be used to read the result back to the CPU - // 2. A texture that will be used to display the result on the screen - createOutput(invalid, windowSize) - { - if (invalid) - { - this.destroyResources(); - let usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC; - - // we will fix the size of the workgroup to be 2 x 2 for printMain. - const numberElements = 1; - const size = numberElements * 4; // int type - this.outputBuffer = this.device.createBuffer({lable: 'outputBuffer', size, usage}); - - this.printfBuffer = this.device.createBuffer({lable: 'outputBuffer', size: this.printfBufferSize, usage}); - - usage = GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST; - this.outputBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size, usage}); - this.printfBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size: this.printfBufferSize, usage}); - - const storageTexture = createOutputTexture(device, windowSize[0], windowSize[1], 'r32float'); - this.outputTexture = storageTexture; - - } - } - - createUniformBuffer() - { - this.uniformBuffer = this.device.createBuffer({size: this.uniformBufferHost.byteLength, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST}); - } - - updateUniformBuffer(data) - { - this.uniformBufferHost[0] = data; - this.device.queue.writeBuffer(this.uniformBuffer, 0, this.uniformBufferHost); - } - - setupComputePipeline(windowSize) - { - this.createOutput(true, windowSize); - this.createComputePipelineLayout(); - } - - - // This is the definition of the printf buffer. - // struct FormatedStruct - // { - // uint32_t type = 0xFFFFFFFF; - // uint32_t low = 0; - // uint32_t high = 0; - // }; - parsePrintfBuffer(hashedString) - { - const printfBufferArray = new Uint32Array(computePipeline.printfBufferRead.getMappedRange()) - var elementIndex = 0; - var numberElements = printfBufferArray.byteLength / this.printfBufferElementSize; - - var formatString; - if (printfBufferArray[0] == 1) // type field - { - formatString = hashedString.getString(printfBufferArray[1]); // low field - } - - // TODO: We currently doesn't support 64-bit data type (e.g. uint64_t, int64_t, double, etc.) - // so 32-bit array should be able to contain everything we need. - var dataArray = new Uint32Array(numberElements); - var stringArray = []; - const elementSizeInWords = this.printfBufferElementSize / 4; - for (elementIndex = 1; elementIndex < numberElements; elementIndex++) - { - var offset = elementIndex * elementSizeInWords; - const type = printfBufferArray[offset]; - - if (type == 1) // type field, this is a string - { - stringArray.push(hashedString.getString(printfBufferArray[offset + 1])); // low field - } - else if (type == 2) // type field - { - dataArray[elementIndex - 1] = printfBufferArray[offset + 1]; // low field - } - else if (type == 0xFFFFFFFF) - { - break; - } - } - - return {formatString: formatString, dataArray: dataArray.slice(0, elementIndex - 1), stringArray: stringArray}; - } - - // TODO: construct the final formatted result - formatToString(formatString, dataArray, stringArray) - { - } -} diff --git a/build/index.html b/build/index.html deleted file mode 100644 index ebd7317..0000000 --- a/build/index.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - Slang Playground - - - - - - - - - - - - - - - - - - - - -
- Slang Logo -
-
-

Loading Playground...

-
-
-
-
- - - - - - diff --git a/build/language-server.js b/build/language-server.js deleted file mode 100644 index c1d329a..0000000 --- a/build/language-server.js +++ /dev/null @@ -1,722 +0,0 @@ -const userCodeURI = "file:///user.slang"; -const playgroundCodeURI = "file:///playground.slang"; -var languageRegistered = false; -function initMonaco() { - if (languageRegistered) - return; - languageRegistered = true; - monaco.languages.register({ id: "slang" }); - monaco.languages.setMonarchTokensProvider("slang", { - keywords: [ - "if", "else", "switch", "case", "default", "return", - "try", "throw", "throws", "catch", "while", "for", - "do", "static", "const", "in", "out", "inout", - "ref", "__subscript", "__init", "property", "get", "set", - "class", "struct", "interface", "public", "private", "internal", - "protected", "typedef", "typealias", "uniform", "export", "groupshared", - "extension", "associatedtype", "this", "namespace", "This", "using", - "__generic", "__exported", "import", "enum", "break", "continue", - "discard", "defer", "cbuffer", "tbuffer", "func", "is", - "as", "nullptr", "none", "true", "false", "functype", - "sizeof", "alignof", "__target_switch", "__intrinsic_asm", - "typename", "each", "expand", "where", "register", "packoffset", - ], - brackets: [ - { open: '{', close: '}', token: 'delimiter.curly' }, - { open: '[', close: ']', token: 'delimiter.square' }, - { open: '(', close: ')', token: 'delimiter.parenthesis' }, - { open: '<', close: '>', token: 'delimiter.angle' } - ], - namespaceFollows: [ - 'namespace', 'using', - ], - typeKeywords: [ - 'bool', 'double', 'uint', 'int', 'short', 'char', 'void', 'float' - ], - - operators: [ - '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', - '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%', - '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=', - '%=', '<<=', '>>=', '>>>=' - ], - - // we include these common regular expressions - symbols: /[=>](?!@symbols)/, '@brackets'], - [/@symbols/, { - cases: { - '@operators': 'operator', - '@default': '' - } - }], - - // numbers - [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'], - [/0[xX][0-9a-fA-F]+/, 'number.hex'], - [/\d+/, 'number'], - - // delimiter: after number because of .\d floats - [/[;,.]/, 'delimiter'], - - // strings - [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string - [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }], - - // characters - [/'[^\\']'/, 'string'], - [/(')(@escapes)(')/, ['string', 'string.escape', 'string']], - [/'/, 'string.invalid'] - ], - - comment: [ - [/[^\/*]+/, 'comment'], - [/\/\*/, 'comment', '@push'], // nested comment - ["\\*/", 'comment', '@pop'], - [/[\/*]/, 'comment'] - ], - - string: [ - [/[^\\"]+/, 'string'], - [/@escapes/, 'string.escape'], - [/\\./, 'string.escape.invalid'], - [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] - ], - - rawstring: [ - // Closing of raw string literal with matching delimiter - [/\)([a-zA-Z0-9_]*?)"/, { - cases: { - '$1==$S2': { token: 'string.raw.quote', next: '@pop' }, // Match delimiter with initial delimiter - '@default': 'string.raw' // Otherwise, continue within raw string - } - }], - [/./, 'string.raw'] // Match any character within the raw string - ], - - whitespace: [ - [/[ \t\r\n]+/, 'white'], - [/\/\*/, 'comment', '@comment'], - [/\/\/.*$/, 'comment'], - ], - qualified: [ - [/[a-zA-Z_][\w]*/, { - cases: { - '@keywords': { token: 'keyword.$0' }, - '@default': 'identifier' - } - }], - [/\./, 'delimiter'], - ['', '', '@pop'], - ], - namespace: [ - { include: '@whitespace' }, - [/[A-Z]\w*/, 'namespace'], - [/[\.=]/, 'delimiter'], - ['', '', '@pop'], - ], - }, - }); - - // A general highlighting rule for all shading languages we care about. - monaco.languages.register({ id: "generic-shader" }); - monaco.languages.setMonarchTokensProvider("generic-shader", { - keywords: [ - "if", "else", "switch", "case", "default", "return", - "while", "for", "do", "static", "const", "in", "out", "inout", - "ref", "class", "struct", "interface", "public", "private", "internal", - "protected", "typedef", "uniform", "export", "groupshared", - "this", "namespace", "using", "enum", "break", "continue", - "discard", "cbuffer", "tbuffer", "true", "false", - "sizeof", "alignof", "layout", "buffer", "register", - "packoffset", "nointerpolation" - ], - brackets: [ - { open: '{', close: '}', token: 'delimiter.curly' }, - { open: '[', close: ']', token: 'delimiter.square' }, - { open: '(', close: ')', token: 'delimiter.parenthesis' }, - { open: '<', close: '>', token: 'delimiter.angle' } - ], - namespaceFollows: [ - 'namespace', 'using', - ], - typeKeywords: [ - 'bool', 'double', 'uint', 'int', 'short', 'char', 'void', 'float' - ], - operators: [ - '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=', - '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|', '^', '%', - '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', '^=', - '%=', '<<=', '>>=', '>>>=' - ], - - // we include these common regular expressions - symbols: /[=>](?!@symbols)/, '@brackets'], - [/@symbols/, { - cases: { - '@operators': 'operator', - '@default': '' - } - }], - - // numbers - [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'], - [/0[xX][0-9a-fA-F]+/, 'number.hex'], - [/\d+/, 'number'], - - // delimiter: after number because of .\d floats - [/[;,.]/, 'delimiter'], - - // strings - [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string - [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }], - - // characters - [/'[^\\']'/, 'string'], - [/(')(@escapes)(')/, ['string', 'string.escape', 'string']], - [/'/, 'string.invalid'] - ], - - comment: [ - [/[^\/*]+/, 'comment'], - [/\/\*/, 'comment', '@push'], // nested comment - ["\\*/", 'comment', '@pop'], - [/[\/*]/, 'comment'] - ], - - string: [ - [/[^\\"]+/, 'string'], - [/@escapes/, 'string.escape'], - [/\\./, 'string.escape.invalid'], - [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] - ], - - whitespace: [ - [/[ \t\r\n]+/, 'white'], - [/\/\*/, 'comment', '@comment'], - [/\/\/.*$/, 'comment'], - ], - qualified: [ - [/[a-zA-Z_][\w]*/, { - cases: { - '@keywords': { token: 'keyword.$0' }, - '@default': 'identifier' - } - }], - [/\./, 'delimiter'], - ['', '', '@pop'], - ], - namespace: [ - { include: '@whitespace' }, - [/[A-Z]\w*/, 'namespace'], - [/[\.=]/, 'delimiter'], - ['', '', '@pop'], - ], - }, - }); - - monaco.languages.register({ id: "spirv" }); - monaco.languages.setMonarchTokensProvider("spirv", { - brackets: [ - { open: '{', close: '}', token: 'delimiter.curly' }, - { open: '[', close: ']', token: 'delimiter.square' }, - { open: '(', close: ')', token: 'delimiter.parenthesis' }, - ], - operators: [ - '=', - ], - - symbols: /[=>](?!@symbols)/, '@brackets'], - [/@symbols/, { - cases: { - '@operators': 'operator', - '@default': '' - } - }], - - // numbers - [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'], - [/0[xX][0-9a-fA-F]+/, 'number.hex'], - [/\d+/, 'number'], - - // delimiter: after number because of .\d floats - [/[;,.]/, 'delimiter'], - - // strings - [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string - [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }], - - // characters - [/'[^\\']'/, 'string'], - [/(')(@escapes)(')/, ['string', 'string.escape', 'string']], - [/'/, 'string.invalid'] - ], - - string: [ - [/[^\\"]+/, 'string'], - [/@escapes/, 'string.escape'], - [/\\./, 'string.escape.invalid'], - [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] - ], - - whitespace: [ - [/[ \t\r\n]+/, 'white'], - ], - }, - }); - - monaco.languages.registerDefinitionProvider("spirv", { - provideDefinition: function (model, position) { - const word = model.getWordAtPosition(position); - if (!word) return null; - - const wordRange = new monaco.Range( - position.lineNumber, - word.startColumn, - position.lineNumber, - word.endColumn - ); - - // Extract the identifier under the cursor - const identifier = word.word; - - // Find the definition of the identifier (either a register or function) - for (let i = 1; i <= model.getLineCount(); i++) { - const lineContent = model.getLineContent(i); - - // Check for register definitions (%register) - if (lineContent.includes(`${identifier} =`)) { - return { - range: new monaco.Range(i, 1, i, lineContent.length + 1), - uri: model.uri - }; - } - - // Check for function definitions (OpFunction) - if (lineContent.includes(`OpFunction ${identifier}`)) { - return { - range: new monaco.Range(i, 1, i, lineContent.length + 1), - uri: model.uri - }; - } - } - - // Return null if no definition was found - return null; - } - }); - - monaco.languages.registerHoverProvider('spirv', { - provideHover: function(model, position) { - const word = model.getWordAtPosition(position); - if (!word) return null; - - const identifier = word.word; - let currentFunction = null; - - // Check for %register or OpFunction definitions - for (let i = 1; i <= model.getLineCount(); i++) { - const lineContent = model.getLineContent(i); - - // Detect function definitions - if (lineContent.includes(`OpFunction`)) { - const funcMatch = lineContent.match(/%?(\w+)\s+=\s+OpFunction\s+/); - if (funcMatch) { - currentFunction = funcMatch[1]; // Store the current function name - } - } - - // Detect function end to reset the current function - if (lineContent.includes(`OpFunctionEnd`)) { - currentFunction = null; - } - - // Hover text for register - if (lineContent.includes(`${identifier} =`)) { - var hoverContents = [ - { value: `**Register:** \`${identifier}\`` }, - { value: '---' }, - { value: `**Definition:** \n\n\`${lineContent.trim()}\`` } - ]; - // Add function context if inside a function - if (currentFunction) { - hoverContents.push({ value: `**In Function:** \`${currentFunction}\`` }); - } - return { - range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn), - contents: hoverContents - }; - } - - // Hover text for function - if (lineContent.includes(`OpFunction ${identifier}`)) { - return { - range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn), - contents: [ - { value: `**Function:** \`${identifier}\`` }, - { value: '---' }, - { value: `**Definition:** \n\n\`${lineContent.trim()}\`` } - ] - }; - } - } - - // If no match is found, return null - return null; - } - }); - - monaco.editor.defineTheme("slang-dark", { - base: "vs-dark", - inherit: true, - rules: [ - { token: "function", foreground: "DCDCAA" }, - { token: "parameter", foreground: "B0B0B0" }, - { token: "variable", foreground: "8CDCFE" }, - { token: "enumMember", foreground: "98AD1C" }, - ], - colors: { - "editor.foreground": "#F0F0F0", - }, - }); - - monaco.languages.registerHoverProvider("slang", { - provideHover: function (model, position) { - if (slangd == null) { - return null; - } - let result = slangd.hover(userCodeURI, { line: position.lineNumber - 1, character: position.column - 1 }); - if (result == null) { - return null; - } - return { - contents: [{ value: result.contents.value }], - range: { - startLineNumber: result.range.start.line + 1, - startColumn: result.range.start.character + 1, - endLineNumber: result.range.end.line + 1, - endColumn: result.range.end.character + 1 - } - }; - } - }); - monaco.languages.registerDefinitionProvider("slang", { - provideDefinition: function (model, position) { - if (slangd == null) { - return null; - } - let result = slangd.gotoDefinition(userCodeURI, { line: position.lineNumber - 1, character: position.column - 1 }); - if (result == null) { - return null; - } - var resultArray = []; - for (var i = 0; i < result.size(); i++) { - let lspResult = result.get(i); - resultArray.push({ - uri: monaco.Uri.parse(lspResult.uri), - range: { - startLineNumber: lspResult.range.start.line + 1, - startColumn: lspResult.range.start.character + 1, - endLineNumber: lspResult.range.end.line + 1, - endColumn: lspResult.range.end.character + 1 - } - }); - } - return resultArray; - } - }); - monaco.languages.registerCompletionItemProvider("slang", { - triggerCharacters: [".", ":", ">", "(", "<", " ", "["], - provideCompletionItems: function (model, position, context) { - if (slangd == null) { - return null; - } - let lspContext = { - triggerKind: context.triggerKind, - triggerCharacter: context.hasOwnProperty("triggerCharacter") ? context.triggerCharacter : "" - }; - let result = slangd.completion( - userCodeURI, - { line: position.lineNumber - 1, character: position.column - 1 }, - lspContext - ); - if (result == null) { - return null; - } - let items = []; - let word = model.getWordAtPosition(position); - if (word == null) - word = model.getWordUntilPosition(position); - var curRange = { - startLineNumber: position.lineNumber, - endLineNumber: position.lineNumber, - startColumn: word.startColumn, - endColumn: word.endColumn, - }; - for (var i = 0; i < result.size(); i++) { - let lspItem = result.get(i); - var item = { - label: lspItem.label, - kind: lspItem.kind, - detail: lspItem.detail, - documentation: lspItem.documentation.value, - insertText: lspItem.label, - range: curRange - }; - items.push(item) - } - return { suggestions: items }; - } - }); - - monaco.languages.registerSignatureHelpProvider("slang", { - signatureHelpTriggerCharacters: ["(", ","], - signatureHelpRetriggerCharacters: [","], - provideSignatureHelp: function (model, position) { - if (slangd == null) { - return null; - } - let result = slangd.signatureHelp(userCodeURI, { line: position.lineNumber - 1, character: position.column - 1 }); - if (result == null) { - return null; - } - let sigs = []; - for (var i = 0; i < result.signatures.size(); i++) { - let lspSignature = result.signatures.get(i); - let params = []; - for (var j = 0; j < lspSignature.parameters.size(); j++) { - let lspParameter = lspSignature.parameters.get(j); - params.push({ - label: [lspParameter.label[0], lspParameter.label[1]], - documentation: lspParameter.documentation.value - }); - } - let signature = { - label: lspSignature.label, - documentation: lspSignature.documentation.value, - parameters: params - }; - sigs.push(signature); - } - return { - value: { - signatures: sigs, - activeSignature: result.activeSignature, - activeParameter: result.activeParameter - }, - dispose: function () { } - }; - } - }); - - monaco.languages.registerDocumentRangeSemanticTokensProvider("slang", { - getLegend: function () { - return { - tokenTypes: [ - "type", - "enumMember", - "variable", - "parameter", - "function", - "property", - "namespace", - "keyword", - "macro", - "string", - ], - tokenModifiers: [] - }; - }, - provideDocumentRangeSemanticTokens: function (model, range, token) { - if (slangd == null) { - return null; - } - let result = slangd.semanticTokens(userCodeURI); - if (result == null) { - return null; - } - let rawData = new Uint32Array(result.size()); - for (var i = 0; i < result.size(); i++) { - rawData[i] = result.get(i); - } - return { - data: rawData - }; - } - }); -} - -function initLanguageServer() { - var text = ""; - if (monacoEditor) - { - text = monacoEditor.getValue(); - } - slangd.didOpenTextDocument(userCodeURI, text); - slangd.didOpenTextDocument(playgroundCodeURI, playgroundSource); -} - -var diagnosticTimeout = null; - -function translateSeverity(severity) { - switch(severity) - { - case 1: - return monaco.MarkerSeverity.Error; - case 2: - return monaco.MarkerSeverity.Warning; - case 3: - return monaco.MarkerSeverity.Information; - case 4: - return monaco.MarkerSeverity.Hint; - default: - return monaco.MarkerSeverity.Error; - } -} - -function codeEditorChangeContent(e) { - if (slangd == null) - return; - let lspChanges = new compiler.slangWasmModule.TextEditList(); - - e.changes.forEach(change => - lspChanges.push_back( - { - range: { - start: { line: change.range.startLineNumber - 1, character: change.range.startColumn - 1 }, - end: { line: change.range.endLineNumber - 1, character: change.range.endColumn - 1 } - }, - text: change.text - } - )); - try { - slangd.didChangeTextDocument(userCodeURI, lspChanges); - if (diagnosticTimeout != null) { - clearTimeout(diagnosticTimeout); - } - diagnosticTimeout = setTimeout(() => { - let diagnostics = slangd.getDiagnostics(userCodeURI); - if (diagnostics == null) { - monaco.editor.setModelMarkers(monacoEditor.getModel(), "slang", []); - return; - } - var markers = []; - for (var i = 0; i < diagnostics.size(); i++) { - let lspDiagnostic = diagnostics.get(i); - markers.push({ - startLineNumber: lspDiagnostic.range.start.line + 1, - startColumn: lspDiagnostic.range.start.character + 1, - endLineNumber: lspDiagnostic.range.end.line + 1, - endColumn: lspDiagnostic.range.end.character + 1, - message: lspDiagnostic.message, - severity: translateSeverity(lspDiagnostic.severity), - code: lspDiagnostic.code - }); - } - monaco.editor.setModelMarkers(monacoEditor.getModel(), "slang", markers); - diagnosticTimeout = null; - }, 500); - - } - finally { - lspChanges.delete(); - } - -} diff --git a/build/pass_through.js b/build/pass_through.js deleted file mode 100644 index d1374c6..0000000 --- a/build/pass_through.js +++ /dev/null @@ -1,141 +0,0 @@ - -var passThroughshaderCode = ` - - struct VertexShaderOutput { - @builtin(position) position: vec4f, - @location(0) texcoord: vec2f, - }; - - @vertex fn vs( - @builtin(vertex_index) vertexIndex : u32 - ) -> VertexShaderOutput { - let uv = array( - // 1st triangle - vec2f( 0.0, 0.0), // center - vec2f( 1.0, 0.0), // right, center - vec2f( 0.0, 1.0), // center, top - - // 2st triangle - vec2f( 0.0, 1.0), // center, top - vec2f( 1.0, 0.0), // right, center - vec2f( 1.0, 1.0), // right, top - ); - - let pos = array( - // 1st triangle - vec2f( -1.0, -1.0), // center - vec2f( 1.0, -1.0), // right, center - vec2f( -1.0, 1.0), // center, top - - // 2st triangle - vec2f( -1.0, 1.0), // center, top - vec2f( 1.0, -1.0), // right, center - vec2f( 1.0, 1.0), // right, top - ); - - var vsOutput: VertexShaderOutput; - let xy = pos[vertexIndex]; - vsOutput.position = vec4f(xy, 0.0, 1.0); - vsOutput.texcoord = uv[vertexIndex]; - return vsOutput; - } - - @group(0) @binding(0) var ourSampler: sampler; - @group(0) @binding(1) var ourTexture: texture_2d; - - @fragment fn fs(fsInput: VertexShaderOutput) -> @location(0) vec4f { - let color = textureSample(ourTexture, ourSampler, fsInput.texcoord); - let value = u32(color.x); - let r = ((value & 0xFF000000) >> 24); - let g = ((value & 0x00FF0000) >> 16); - let b = ((value & 0x0000FF00) >> 8); - - return vec4f(f32(r)/255.0f, f32(g)/255.0f, f32(b)/255.0f, 1.0f); - } -`; - -class GraphicsPipeline -{ - vertShader; - fragShader; - device; - pipeline; - sampler; - pipelineLayout; - - constructor(device) - { - this.device = device; - } - - createGraphicsPipelineLayout() - { - // Passthrough shader will need an input texture to be displayed on the screen - const bindGroupLayoutDescriptor = { - lable: 'pass through pipeline bind group layout', - entries: [ - {binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: {}}, - {binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: {sampleType: 'float'}}, - ], - }; - - const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor); - const layout = device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout]}); - this.pipelineLayout = layout; - } - - createPipeline(shaderModule, inputTexture) - { - this.createGraphicsPipelineLayout(); - - const pipeline = device.createRenderPipeline({ - label: 'pass through pipeline', - layout: this.pipelineLayout, - vertex: - { - module: shaderModule - }, - fragment: - { - module: shaderModule, - targets: [{format: navigator.gpu.getPreferredCanvasFormat()}] - }, - }); - this.pipeline = pipeline; - - this.sampler = device.createSampler(); - this.inputTexture = inputTexture; - this.createBindGroup(); - } - - createBindGroup() - { - const bindGroup = device.createBindGroup({ - label: 'pass through pipeline bind group', - layout: this.pipeline.getBindGroupLayout(0), - entries: [ - { binding: 0, resource: this.sampler }, - { binding: 1, resource: this.inputTexture.createView() }, - ], - }); - - this.bindGroup = bindGroup; - } - - createRenderPassDesc() - { - const renderPassDescriptor = { - label: 'pass through renderPass', - colorAttachments: [ - { - // view: <- to be filled out when we render - clearValue: [0.3, 0.3, 0.3, 1], - loadOp: 'clear', - storeOp: 'store', - }, - ], - }; - - return renderPassDescriptor; - } -}; diff --git a/build/playgoundShader.js b/build/playgoundShader.js deleted file mode 100644 index 2eb90b2..0000000 --- a/build/playgoundShader.js +++ /dev/null @@ -1,83 +0,0 @@ - -const playgroundSource = ` -internal uniform float time; - -// Return the current time in milliseconds -public float getTime() -{ - return time; -} - -struct FormatedStruct -{ - uint32_t type = 0xFFFFFFFF; - uint32_t low = 0; - uint32_t high = 0; -}; - -internal RWStructuredBuffer g_printedBuffer; - -interface IPrintf -{ - uint32_t typeFlag(); - uint32_t writePrintfWords(); -}; - -extension uint : IPrintf -{ - uint32_t typeFlag() { return 2;} - uint32_t writePrintfWords() { return (uint32_t)this; } -} - -extension int : IPrintf -{ - uint32_t typeFlag() { return 2;} - uint32_t writePrintfWords() { return (uint32_t)this; } -} - -// extension int64_t : IPrintf -// { -// uint64_t writePrintfWords() { return (uint64_t)this; } -// } - -// extension uint64_t : IPrintf -// { -// uint64_t writePrintfWords() { return (uint64_t)this; } -// } - -extension float : IPrintf -{ - uint32_t typeFlag() { return 2;} - uint32_t writePrintfWords() { return bit_cast(this); } -} - -// extension double : IPrintf -// { -// uint64_t writePrintfWords() { return bit_cast(this); } -// } - -extension String : IPrintf -{ - uint32_t typeFlag() { return 1;} - uint32_t writePrintfWords() { return getStringHash(this); } -} - -void handleEach(T value, int index) where T : IPrintf -{ - g_printedBuffer[index].type = value.typeFlag(); - g_printedBuffer[index].low = value.writePrintfWords(); -} - -public void print(String format, expand each T values) where T : IPrintf -{ - //if (format.length != 0) - { - g_printedBuffer[0].type = 1; - g_printedBuffer[0].low = getStringHash(format); - int index = 1; - expand(handleEach(each values, index++)); - - g_printedBuffer[index] = {}; - } -} -`; diff --git a/build/playgroundShader.js b/build/playgroundShader.js deleted file mode 100644 index 2eb90b2..0000000 --- a/build/playgroundShader.js +++ /dev/null @@ -1,83 +0,0 @@ - -const playgroundSource = ` -internal uniform float time; - -// Return the current time in milliseconds -public float getTime() -{ - return time; -} - -struct FormatedStruct -{ - uint32_t type = 0xFFFFFFFF; - uint32_t low = 0; - uint32_t high = 0; -}; - -internal RWStructuredBuffer g_printedBuffer; - -interface IPrintf -{ - uint32_t typeFlag(); - uint32_t writePrintfWords(); -}; - -extension uint : IPrintf -{ - uint32_t typeFlag() { return 2;} - uint32_t writePrintfWords() { return (uint32_t)this; } -} - -extension int : IPrintf -{ - uint32_t typeFlag() { return 2;} - uint32_t writePrintfWords() { return (uint32_t)this; } -} - -// extension int64_t : IPrintf -// { -// uint64_t writePrintfWords() { return (uint64_t)this; } -// } - -// extension uint64_t : IPrintf -// { -// uint64_t writePrintfWords() { return (uint64_t)this; } -// } - -extension float : IPrintf -{ - uint32_t typeFlag() { return 2;} - uint32_t writePrintfWords() { return bit_cast(this); } -} - -// extension double : IPrintf -// { -// uint64_t writePrintfWords() { return bit_cast(this); } -// } - -extension String : IPrintf -{ - uint32_t typeFlag() { return 1;} - uint32_t writePrintfWords() { return getStringHash(this); } -} - -void handleEach(T value, int index) where T : IPrintf -{ - g_printedBuffer[index].type = value.typeFlag(); - g_printedBuffer[index].low = value.writePrintfWords(); -} - -public void print(String format, expand each T values) where T : IPrintf -{ - //if (format.length != 0) - { - g_printedBuffer[0].type = 1; - g_printedBuffer[0].low = getStringHash(format); - int index = 1; - expand(handleEach(each values, index++)); - - g_printedBuffer[index] = {}; - } -} -`; diff --git a/build/spirv-tools.js b/build/spirv-tools.js deleted file mode 100644 index f2928ea..0000000 --- a/build/spirv-tools.js +++ /dev/null @@ -1,19 +0,0 @@ - -var Module = (() => { - var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined; - if (typeof __filename != 'undefined') _scriptName = _scriptName || __filename; - return ( -function(moduleArg = {}) { - var moduleRtn; - -var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";if(ENVIRONMENT_IS_NODE){}var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};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("fs");var nodePath=require("path");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);var ret=fs.readFileSync(filename);return ret};readAsync=(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return new Promise((resolve,reject)=>{fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)reject(err);else resolve(binary?data.buffer:data)})})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptName){scriptDirectory=_scriptName}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{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=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)})}return fetch(url,{credentials:"same-origin"}).then(response=>{if(response.ok){return response.arrayBuffer()}return Promise.reject(new Error(response.status+" : "+response.url))})}}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){var preRuns=Module["preRun"];if(preRuns){if(typeof preRuns=="function")preRuns=[preRuns];preRuns.forEach(addOnPreRun)}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){var postRuns=Module["postRun"];if(postRuns){if(typeof postRuns=="function")postRuns=[postRuns];postRuns.forEach(addOnPostRun)}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}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);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");function findWasmBinary(){var f="spirv-tools.wasm";if(!isDataURI(f)){return locateFile(f)}return f}var wasmBinaryFile;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"}function getBinaryPromise(binaryFile){if(!wasmBinary){return readAsync(binaryFile).then(response=>new Uint8Array(response),()=>getBinarySync(binaryFile))}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function getWasmImports(){return{a:wasmImports}}function createWasm(){var info=getWasmImports();function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["x"];updateMemoryViews();wasmTable=wasmExports["A"];addOnInit(wasmExports["y"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}wasmBinaryFile??=findWasmBinary();instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var callRuntimeCallbacks=callbacks=>{callbacks.forEach(f=>f(Module))};var noExitRuntime=Module["noExitRuntime"]||true;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>{abort("")};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{};var embind_init_charCodes=()=>{var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes};var embind_charCodes;var readLatin1String=ptr=>{var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret};var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var BindingError;var throwBindingError=message=>{throw new BindingError(message)};var InternalError;var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(type=>typeDependencies[type]=dependentTypes);function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){return sharedRegisterType(rawType,registeredInstance,options)}var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=readLatin1String(name);registerType(rawType,{name,fromWireType:function(wt){return!!wt},toWireType:function(destructors,o){return o?trueValue:falseValue},argPackAdvance:GenericWireTypeSize,readValueFromPointer:function(pointer){return this["fromWireType"](HEAPU8[pointer])},destructorFunction:null})};var __embind_register_constant=(name,type,value)=>{name=readLatin1String(name);whenDependentTypesAreResolved([],[type],type=>{type=type[0];Module[name]=type["fromWireType"](value);return[]})};var emval_freelist=[];var emval_handles=[];var __emval_decref=handle=>{if(handle>9&&0===--emval_handles[handle+1]){emval_handles[handle]=undefined;emval_freelist.push(handle)}};var count_emval_handles=()=>emval_handles.length/2-5-emval_freelist.length;var init_emval=()=>{emval_handles.push(0,1,undefined,1,null,1,true,1,false,1);Module["count_emval_handles"]=count_emval_handles};var Emval={toValue:handle=>{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles[handle]},toHandle:value=>{switch(value){case undefined:return 2;case null:return 4;case true:return 6;case false:return 8;default:{const handle=emval_freelist.pop()||emval_handles.length;emval_handles[handle]=value;emval_handles[handle+1]=1;return handle}}}};function readPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var EmValType={name:"emscripten::val",fromWireType:handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},toWireType:(destructors,value)=>Emval.toHandle(value),argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction:null};var __embind_register_emval=rawType=>registerType(rawType,EmValType);var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=readLatin1String(name);registerType(rawType,{name,fromWireType:value=>value,toWireType:(destructors,value)=>value,argPackAdvance:GenericWireTypeSize,readValueFromPointer:floatReadValueFromPointer(name,size),destructorFunction:null})};var createNamedFunction=(name,body)=>Object.defineProperty(body,"name",{value:name});var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function usesDestructorStack(argTypes){for(var i=1;i{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(...args){if(!proto[methodName].overloadTable.hasOwnProperty(args.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[args.length].apply(this,args)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i>2])}return array};var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistent public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var dynCallLegacy=(sig,ptr,args)=>{sig=sig.replace(/p/g,"i");var f=Module["dynCall_"+sig];return f(ptr,...args)};var wasmTable;var getWasmTableEntry=funcPtr=>wasmTable.get(funcPtr);var dynCall=(sig,ptr,args=[])=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr)(...args);return rtn};var getDynCaller=(sig,ptr)=>(...args)=>dynCall(sig,ptr,args);var embind__requireFunction=(signature,rawFunction)=>{signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};var extendError=(baseErrorType,errorName)=>{var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass};var UnboundTypeError;var getTypeName=type=>{var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var getFunctionName=signature=>{signature=signature.trim();const argsIndex=signature.indexOf("(");if(argsIndex!==-1){return signature.substr(0,argsIndex)}else{return signature}};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync,isNonnullReturn)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);name=getFunctionName(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,argTypes=>{var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer]:pointer=>HEAPU8[pointer];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name,fromWireType,toWireType,argPackAdvance:GenericWireTypeSize,readValueFromPointer:integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name,fromWireType:decodeMemoryView,argPackAdvance:GenericWireTypeSize,readValueFromPointer:decodeMemoryView},{ignoreDuplicateRegistrations:true})};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=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}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;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)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var __embind_register_std_string=(rawType,name)=>{name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name,fromWireType(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i{var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=readLatin1String(name);var decodeString,encodeString,readCharAt,lengthBytesUTF;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;readCharAt=pointer=>HEAPU16[pointer>>1]}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;readCharAt=pointer=>HEAPU32[pointer>>2]}registerType(rawType,{name,fromWireType:value=>{var length=HEAPU32[value>>2];var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||readCharAt(currentBytePtr)==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},toWireType:(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length/charSize;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},argPackAdvance:GenericWireTypeSize,readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var __embind_register_void=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{isVoid:true,name,argPackAdvance:0,fromWireType:()=>undefined,toWireType:(destructors,o)=>undefined})};var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`)}return impl};var __emval_take_value=(type,arg)=>{type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)};var __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?"-":"+";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,"0");var minutes=String(absOffset%60).padStart(2,"0");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffset{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i{var bufSize=0;getEnvStrings().forEach((string,i)=>{var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1});return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(string=>bufSize+=string.length+1);HEAPU32[penviron_buf_size>>2]=bufSize;return 0};var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("initRandomDevice")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf,0,BUFSIZE)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else{}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key of Object.keys(node.contents)){entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url).then(arrayBuffer=>{onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)},err=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}});if(dep)addRunDependency(dep)};var FS_createDataFile=(parent,name,fileData,canRead,canWrite,canOwn)=>{FS.createDataFile(parent,name,fileData,canRead,canWrite,canOwn)};var preloadPlugins=Module["preloadPlugins"]||[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={r:0,"r+":2,w:512|64|1,"w+":512|64|2,a:1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:class{constructor(errno){this.name="ErrnoError";this.errno=errno}},genericErrors:{},filesystems:null,syncFSRequests:0,readFiles:{},FSStream:class{constructor(){this.shared={}}get object(){return this.node}set object(val){this.node=val}get isRead(){return(this.flags&2097155)!==1}get isWrite(){return(this.flags&2097155)!==0}get isAppend(){return this.flags&1024}get flags(){return this.shared.flags}set flags(val){this.shared.flags=val}get position(){return this.shared.position}set position(val){this.shared.position=val}},FSNode:class{constructor(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev;this.readMode=292|73;this.writeMode=146}get read(){return(this.mode&this.readMode)===this.readMode}set read(val){val?this.mode|=this.readMode:this.mode&=~this.readMode}get write(){return(this.mode&this.writeMode)===this.writeMode}set write(val){val?this.mode|=this.writeMode:this.mode&=~this.writeMode}get isFolder(){return FS.isDir(this.mode)}get isDevice(){return FS.isChrdev(this.mode)}},lookupPath(path,opts={}){path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},dupStream(origStream,fd=-1){var stream=FS.createStream(origStream,fd);stream.stream_ops?.dup?.(stream);return stream},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type,opts,mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var i=0;iFS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams(input,output,error){if(input){FS.createDevice("/dev","stdin",input)}else{FS.symlink("/dev/tty","/dev/stdin")}if(output){FS.createDevice("/dev","stdout",null,output)}else{FS.symlink("/dev/tty","/dev/stdout")}if(error){FS.createDevice("/dev","stderr",null,error)}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""});FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={MEMFS}},init(input,output,error){FS.initialized=true;input??=Module["stdin"];output??=Module["stdout"];error??=Module["stderr"];FS.createStandardStreams(input,output,error)},quit(){FS.initialized=false;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]}setDataGetter(getter){this.getter=getter}cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true}get length(){if(!this.lengthKnown){this.cacheLength()}return this._length}get chunkSize(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat(func,path,buf){var stat=func(path);HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=stat.mode;HEAPU32[buf+8>>2]=stat.nlink;HEAP32[buf+12>>2]=stat.uid;HEAP32[buf+16>>2]=stat.gid;HEAP32[buf+20>>2]=stat.rdev;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>2]=tempI64[0],HEAP32[buf+28>>2]=tempI64[1];HEAP32[buf+32>>2]=4096;HEAP32[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAPU32[buf+48>>2]=atime%1e3*1e3*1e3;tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>2]=tempI64[0],HEAP32[buf+60>>2]=tempI64[1];HEAPU32[buf+64>>2]=mtime%1e3*1e3*1e3;tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>2]=tempI64[0],HEAP32[buf+76>>2]=tempI64[1];HEAPU32[buf+80>>2]=ctime%1e3*1e3*1e3;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>2]=tempI64[0],HEAP32[buf+92>>2]=tempI64[1];return 0},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream},varargs:undefined,getStr(ptr){var ret=UTF8ToString(ptr);return ret}};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var convertI32PairToI53Checked=(lo,hi)=>hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN;function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};init_emval();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();var wasmImports={h:___cxa_throw,t:__abort_js,l:__embind_register_bigint,j:__embind_register_bool,v:__embind_register_constant,i:__embind_register_emval,e:__embind_register_float,g:__embind_register_function,b:__embind_register_integer,a:__embind_register_memory_view,d:__embind_register_std_string,c:__embind_register_std_wstring,n:__embind_register_void,u:__emval_decref,w:__emval_take_value,m:__tzset_js,s:_emscripten_resize_heap,o:_environ_get,p:_environ_sizes_get,q:_fd_close,r:_fd_read,k:_fd_seek,f:_fd_write};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["y"])();var ___getTypeName=a0=>(___getTypeName=wasmExports["z"])(a0);var _malloc=a0=>(_malloc=wasmExports["B"])(a0);var _free=a0=>(_free=wasmExports["C"])(a0);var dynCall_viijii=Module["dynCall_viijii"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_viijii=Module["dynCall_viijii"]=wasmExports["D"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_jiji=Module["dynCall_jiji"]=(a0,a1,a2,a3,a4)=>(dynCall_jiji=Module["dynCall_jiji"]=wasmExports["E"])(a0,a1,a2,a3,a4);var dynCall_iiiiij=Module["dynCall_iiiiij"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_iiiiij=Module["dynCall_iiiiij"]=wasmExports["F"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8)=>(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=wasmExports["G"])(a0,a1,a2,a3,a4,a5,a6,a7,a8);var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9)=>(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=wasmExports["H"])(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9);var calledRun;var calledPrerun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}if(!calledPrerun){calledPrerun=1;preRun();if(runDependencies>0){return}}function doRun(){if(calledRun)return;calledRun=1;Module["calledRun"]=1;if(ABORT)return;initRuntime();readyPromiseResolve(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();moduleRtn=readyPromise; - - - return moduleRtn; -} -); -})(); -if (typeof exports === 'object' && typeof module === 'object') - module.exports = Module; -else if (typeof define === 'function' && define['amd']) - define([], () => Module); diff --git a/build/spirv-tools.wasm b/build/spirv-tools.wasm deleted file mode 100755 index 36463c20e156b338ffbfbe1477b5b186eb8c9260..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 383130 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%0AeN85a)2PI~CaSZqs6s3}b{L-r#X;ZFI7F#c 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�>S0 ztrK>9M?>l~S!fpxlI3B}YM#o>d-;|4YLTz2HTyq=oun=z87G%2^|ck|VxHwcZ{-p@a&zlrj%UL=X%t^BAnz6t_;|SyeO~c{?b1OEb z+O>KO2wsCB{)Gn1-Zx$a&m>9HUL>-cN^;#A6MS+86`=`!E9eWP=C95|3S19t4}Xx% zCgnsxC@;ua>iJ+oNI+iMrvThKeGQGCD?@=qw|uFe7nsh(s#w&BnrT@9WObF0SZGn~ zaBi6x6G-~v6JBWo;$xNV*_48N$Mq4)OrXpQk?PKwO1vx)>gX+vk$_X-8i+ySOe-I= zT(UR0P-%lIvq;bm`KAw?V5P{CWP!3of$hr6TMfr>>Y~afI*RgchkPS~s-~__7}oEz zkkx2Yw|n1*vwT}K z;Y~Kz-}H1UPp&OXpH)eZyJ-FJTg$#bY6tzZc2XndV47Kw|MM)qsdnNJO7N<_Rg}4r z_FyCw&JQm*#Sd)(ZC&;5r-FNX!|$zvgdJNfXOSE+-eR1<=U0++ z6Rk(n7ae};asTCW;QAg}<@Qa;b}u@Y?25FW|H-Gm+w6NDKgmR`|Myd{v`B#2=ARma;@J_1Uzh{Z_ZV+&!{2tC~(+d^Qk%hfv+5u`*E7k zOw+s3s+Xe<*R7m!Tgv=Kg_#~BE2JAKb8nmuWUAf9yNb)42B|vi$BprN-B?qd*wRFS zGP&5fi!D!yfJPrdH<7Wt?+*I2$|s~G97(1BV(4#s@0GMHR%|y}5lxP#FK@<4yj%rm zHG)^DpgtaOQc;Ucw}BNxsaG34{X~i!lB0G=jyk@)FlYJYqk`MW#817Qgw6c@|4jWr zRJhB6^o(J?2l3xKCoahiZ#jc|4B4Lqe>!9FtBPYFC2(mOX?s|JJ*Ab9^=8q|1_pzg zUV+Tb;=7q?J?f@({K;Uvqp~XSO22okGO<+lT?BtQ3E~PIuV7cw(wzX|`pHe&aZnjO zfO+f@RGr%pb3)(R4pXCNZsy7|T|fvf3epN59b>@&q4+-T2T!o|yKN1Fz7Zn|2V z&`&qG^;LhXC0LsICcFcFrbobL8J6L_CthG$bv>xh@X4Vggu(}K@J!?YV5|gUk4lZg zuW&m`8{~H*6?5u|)}kfVS3gB;M!qf=s^xPwDZktLcX`?eEM(kW;0SX(;xJy}jkBto zZSJ?|mD&G^v3gG2!kg+oL#N(a$~-CX)i-TUvajxV#X}bzU?mMN!ZLo=h8}z~ficg3 z7@)rMdTV@JgH7mt-R&1gnWpvV3YPzEGE16XsSFR=gxc}JC(m9uvqL^a8P5tDADXkL zZ5@jF2Ilx&H)m=3QBvZEpGz^*p1#_%wXc~JB8K1CAy_7DX=`zA#G!jAk?supK;jx4o{tD%RC(pz41{+d>ZJ=5S#TtvL((zyN+? zOx49qQzdj@V#JK55+#}UinN+YcZndhz4{72B|IpNBN$08FH!Hjbw%hs`S1LzQJ=5n zrNEHMu8fKC=GLKi7T^B8hvg20oqGuxd(SNAO<|kCsaF9{ZImTEhd^xZ=D9xe8Lhh! z_*3ECse)DfCv?nu^w%(fTzO-f5{_diSu<&ds6v?{}wx!0Rb!tHJ3<14?5t zD2=a!qt3_IzOwN}iy{`|McMiAAJ`Z54iR$2N~%f6d>LC5&Qljb}YsW3Onqg8G2HR z1|uny%vnCQc~6!_h8jwhj+U_>B&g5cjwEER-;ZtIDPIMa9sZ(~DUEkVxbz%LHSjw5 zxV$f>(ys$rb-0e~q4j0Wo+r@yi?n|For2OR)WmZy$L2X14oiPxF;0Mc1r~ozH-Cde zLcs#hCrE6CKq?7hZMcf#(k*`6zT)P9%7ueRvqBMs=%uZNI7#}FRuOV|W&;(Z?Z0m?OnX8MTy}(&VgAwhzaQ8nC4s(9e8mDvUlovnm*>o{@M;FICIlnwda$~5P{k$w6kL53p!&DI^$6&_D&y1c>Y7eQ8C>cZ`az5{4^q>FTmjo;n*WOQ^L)#?rhZ{<*CNyP+X>gLM zau7!1dPu^(1hh{arU?ilz{XmwqSQiUd53j|X1qUVm~wqm=*1NK>VXW-{iTH<}Bai>QFZg znaVwvgzu|jL|?4lZ+<*ibtq+md-JdmpF|N%ncYDUdoB(=pU7+8sl^VIG7~b}`t+w= zDm=MMZp!0>jO^31bEVArxxzUIbKU$a7w?{2lk@5;+zHs&GM>*pGGeN(W6C7?UIDu9 z4)!P4H8r4Nx{NTNW3rdvU+u~&dHZ98BMI%4YFzenC;VqcV@__4Yv}nYBRk@Lgdywv zVr!tcU?oi{YTvnkpYw3a{^ThHXb93q*f6a8kgkV4YOVl=5z(q!UyIGD%h0Vn84Mf| z2?xU0ZupoD=60)UT#z&8ryPB|J5^43g2V8K(o< { resizeCanvasHandler(entries); }); - observer.observe(canvas); -} - -function resizeCanvas(entries) -{ - const canvas = entries[0].target; - - if (canvas.style.display == "none") - { - var parentDiv = document.getElementById("output"); - currentWindowSize = [parentDiv.clientWidth, parentDiv.clientHeight]; - return true; - } - - const width = canvas.clientWidth; - const height = canvas.clientHeight; - - if (width != currentWindowSize[0] || height != currentWindowSize[1]) - { - // ensure the size won't be 0 nor exceed the limit, otherwise WebGPU will throw an errors - canvas.width = Math.max(1, Math.min(width, device.limits.maxTextureDimension2D)); - canvas.height = Math.max(1, Math.min(height, device.limits.maxTextureDimension2D)); - - currentWindowSize = [canvas.width, canvas.height]; - return true; - } - - return false; -} - -var renderDelayTimer = null; - -function startRendering() { - if (renderDelayTimer) - clearTimeout(renderDelayTimer); - - renderDelayTimer = setTimeout(() => { - if (computePipeline && passThroughPipeline && - currentWindowSize[0] > 1 && currentWindowSize[1] > 1) { - computePipeline.createOutput(true, currentWindowSize); - computePipeline.createBindGroup(); - passThroughPipeline.inputTexture = computePipeline.outputTexture; - passThroughPipeline.createBindGroup(); - if (canvas.style.display != "none") { - requestAnimationFrame(render); - } - } - }, 100); -} - -// We use the timer in the resize handler debounce the resize event, otherwise we could end of rendering -// multiple useless frames. -function resizeCanvasHandler(entries) -{ - var needResize = resizeCanvas(entries); - if (needResize) { - startRendering(); - } -} - -function toggleDisplayMode(displayMode) -{ - if (currentMode == displayMode) - return; - if (currentMode == HIDDEN_MODE && displayMode != HIDDEN_MODE) - { - document.getElementById("resultSplitContainer").style.gridTemplateRows="50% 14px 1fr"; - } - if (displayMode == RENDER_MODE) - { - var printResult = document.getElementById("printResult") - printResult.style.display = "none"; - canvas.style.display="grid"; - canvas.style.width = "100%"; - canvas.style.height = "100%"; - currentMode = RENDER_MODE; - } - else if (displayMode == PRINT_MODE) - { - canvas.style.display="none"; - var printResult = document.getElementById("printResult") - printResult.style.display = "grid"; - - currentMode = PRINT_MODE; - } - else if (displayMode == HIDDEN_MODE) - { - canvas.style.display="none"; - document.getElementById("printResult").style.display = "none"; - document.getElementById("resultSplitContainer").style.gridTemplateRows="0px 14px 1fr"; - currentMode = HIDDEN_MODE; - } - else - { - console.log("Invalid display mode " + displayMode); - } -} - -async function render(timeMS) -{ - if (currentMode == HIDDEN_MODE) - return; - if (currentWindowSize[0] < 2 || currentWindowSize[1] < 2) - return; - - computePipeline.updateUniformBuffer(timeMS * 0.01); - // Encode commands to do the computation - const encoder = device.createCommandEncoder({ label: 'compute builtin encoder' }); - const pass = encoder.beginComputePass({ label: 'compute builtin pass' }); - - pass.setBindGroup(0, computePipeline.bindGroup); - pass.setPipeline(computePipeline.pipeline); - const workGroupSizeX = (currentWindowSize[0] + 15) / 16; - const workGroupSizeY = (currentWindowSize[1] + 15) / 16; - pass.dispatchWorkgroups(workGroupSizeX, workGroupSizeY); - pass.end(); - - if (currentMode == RENDER_MODE) - { - var renderPassDescriptor = passThroughPipeline.createRenderPassDesc(); - renderPassDescriptor.colorAttachments[0].view = context.getCurrentTexture().createView(); - const renderPass = encoder.beginRenderPass(renderPassDescriptor); - - renderPass.setBindGroup(0, passThroughPipeline.bindGroup); - renderPass.setPipeline(passThroughPipeline.pipeline); - renderPass.draw(6); // call our vertex shader 6 times. - renderPass.end(); - } - - // copy output buffer back in print mode - if (currentMode == PRINT_MODE) - encoder.copyBufferToBuffer(computePipeline.outputBuffer, 0, computePipeline.outputBufferRead, 0, computePipeline.outputBuffer.size); - - // Finish encoding and submit the commands - const commandBuffer = encoder.finish(); - device.queue.submit([commandBuffer]); - - // Only request the next frame if we are in the render mode - if (currentMode == RENDER_MODE) - requestAnimationFrame(render); -} - -async function printResult() -{ - // Encode commands to do the computation - const encoder = device.createCommandEncoder({ label: 'compute builtin encoder' }); - const pass = encoder.beginComputePass({ label: 'compute builtin pass' }); - - pass.setBindGroup(0, computePipeline.bindGroup); - pass.setPipeline(computePipeline.pipeline); - pass.dispatchWorkgroups(1, 1); - pass.end(); - - // copy output buffer back in print mode - encoder.copyBufferToBuffer(computePipeline.outputBuffer, 0, computePipeline.outputBufferRead, 0, computePipeline.outputBuffer.size); - encoder.copyBufferToBuffer(computePipeline.printfBuffer, 0, computePipeline.printfBufferRead, 0, computePipeline.printfBuffer.size); - - // Finish encoding and submit the commands - const commandBuffer = encoder.finish(); - device.queue.submit([commandBuffer]); - - await device.queue.onSubmittedWorkDone(); - // Read the results once the job is done - await Promise.all([ - computePipeline.outputBufferRead.mapAsync(GPUMapMode.READ), - computePipeline.printfBufferRead.mapAsync(GPUMapMode.READ)]); - - const output = new Int32Array(computePipeline.outputBufferRead.getMappedRange()); - - // debug testing: - let textResult = output.toString() + "\n"; - if (compiler.hashedString) - { - const result = computePipeline.parsePrintfBuffer(compiler.hashedString) - textResult += "Format string: " + result.formatString + "\n"; - textResult += "Data view: " + result.dataArray.toString() + "\n"; - textResult += "String view: " + result.stringArray.toString() + "\n"; - } - - computePipeline.outputBufferRead.unmap(); - computePipeline.printfBufferRead.unmap(); - - document.getElementById("printResult").value = textResult; -} - -function parsePrintfBuffer(buffer) -{ - -} - -function checkShaderType(userSource) -{ - // we did a pre-filter on the user input source code. - const isImageMain = userSource.match("imageMain"); - const isPrintMain = userSource.match("printMain"); - - // Only one of the main function should be defined. - // In this case, we will know that the shader is not runnable, so we can only compile it. - if (isImageMain == isPrintMain) - return SlangCompiler.NON_RUNNABLE_SHADER; - - if (isImageMain) - return SlangCompiler.RENDER_SHADER; - else - return SlangCompiler.PRINT_SHADER; -} - -var onRun = () => { - if (!device) - return; - if (!monacoEditor) - return; - if (!compiler) - return; - if (!computePipeline) - { - computePipeline = new ComputePipeline(device); - computePipeline.setupComputePipeline(currentWindowSize); - computePipeline.createUniformBuffer(4); // 4 bytes for float number - } - - if (!passThroughPipeline) - { - passThroughPipeline = new GraphicsPipeline(device); - const shaderModule = device.createShaderModule({code: passThroughshaderCode}); - const inputTexture = computePipeline.outputTexture; - passThroughPipeline.createPipeline(shaderModule, inputTexture); - } - - // We will have some restrictions on runnable shader, the user code has to define imageMain or printMain function. - // We will do a pre-filter on the user input source code, if it's not runnable, we will not run it. - const userSource = monacoEditor.getValue(); - const shaderType = checkShaderType(userSource); - if (shaderType == SlangCompiler.NON_RUNNABLE_SHADER) - { - diagnosticsArea.setValue("Error: In order to run the shader, please define either imageMain or printMain function in the shader code."); - // clear content in render area and code-gen area - toggleDisplayMode(HIDDEN_MODE); - codeGenArea.setValue(""); - return; - } - - const entryPointName = shaderType == SlangCompiler.RENDER_SHADER? "imageMain" : "printMain"; - const ret = compileShader(userSource, entryPointName, "WGSL"); - - // Recompile the pipeline. - if (ret.succ) - { - const module = device.createShaderModule({code:ret.code}); - computePipeline.createPipeline(module); - } - - toggleDisplayMode(compiler.shaderType); - if (compiler.shaderType == SlangCompiler.PRINT_SHADER) - { - printResult(); - } - else if (compiler.shaderType == SlangCompiler.RENDER_SHADER) - { - startRendering(); - } -} - -function compileShader(userSource, entryPoint, compileTarget) -{ - var compiledCode = compiler.compile(userSource, entryPoint, compileTarget, SlangCompiler.SLANG_STAGE_COMPUTE); - diagnosticsArea.setValue(compiler.diagnosticsMsg); - - // If compile is failed, we just clear the codeGenArea - if (!compiledCode) - { - codeGenArea.setValue('Compilation returned empty result.'); - return {succ: false, code: compiledCode}; - } - - codeGenArea.setValue(compiledCode); - if (compileTarget == "WGSL") - codeGenArea.getModel().setLanguage("wgsl"); - else if (compileTarget == "SPIRV") - codeGenArea.getModel().setLanguage("spirv"); - else - codeGenArea.getModel().setLanguage("generic-shader"); - return {succ: true, code: compiledCode}; -} - -// For the compile button action, we don't have restriction on user code that it has to define imageMain or printMain function. -// But if it doesn't define any of them, then user code has to define a entry point function name. Because our built-in shader -// have no way to call the user defined function, and compile engine cannot compile the source code. -var onCompile = async () => { - - toggleDisplayMode(HIDDEN_MODE); - const compileTarget = document.getElementById("target-select").value; - - const entryPoint = document.getElementById("entrypoint-select").value; - if (entryPoint == "" && !isWholeProgramTarget(compileTarget)) - { - diagnosticsArea.setValue("Please select the entry point name"); - return; - } - - if (compileTarget == "SPIRV") - await compiler.initSpirvTools(); - - // compile the compute shader code from input text area - const userSource = monacoEditor.getValue(); - compileShader(userSource, entryPoint, compileTarget); - - if (compiler.diagnosticsMsg.length > 0) - { - diagnosticsArea.setValue(compiler.diagnosticsMsg); - return; - } -} - -function onSourceCodeChange() -{ - sourceCodeChange = true; -} - - -function loadEditor(readOnlyMode = false, containerId, preloadCode) { - - require(["vs/editor/editor.main"], function () { - var container = document.getElementById(containerId); - initMonaco(); - var model = readOnlyMode - ? monaco.editor.createModel(preloadCode) - : monaco.editor.createModel("", "slang", monaco.Uri.parse(userCodeURI)); - var editor = monaco.editor.create(container, { - model: model, - language: readOnlyMode?'csharp':'slang', - theme: 'slang-dark', - readOnly: readOnlyMode, - lineNumbers: readOnlyMode?"off":"on", - automaticLayout: true, - "semanticHighlighting.enabled": true, - renderValidationDecorations: "on", - minimap: { - enabled: false - }, - }); - if (!readOnlyMode) - { - model.onDidChangeContent(codeEditorChangeContent); - model.setValue(preloadCode); - } - - if (containerId == "codeEditor") - monacoEditor = editor; - else if (containerId == "diagnostics") - { - var model = editor.getModel(); - monaco.editor.setModelLanguage(model, "text") - diagnosticsArea = editor; - } - else if (containerId == "codeGen") - { - codeGenArea = editor; - codeGenArea.onDidChangeModelContent(function (e) { - onSourceCodeChange(); - }); - } - }); - } - - -// Event when loading the WebAssembly module -var moduleLoadingMessage = ""; - -// Define the Module object with a callback for initialization -var Module = { - onRuntimeInitialized: function () { - var label = document.getElementById("loadingStatusLabel"); - if (label) - label.innerText = "Initializing Slang Compiler..."; - compiler = new SlangCompiler(Module); - slangd = Module.createLanguageServer(); - initLanguageServer(); - var result = compiler.init(); - if (result.ret) { - document.getElementById("compile-btn").disabled = false; - moduleLoadingMessage = "Slang compiler initialized successfully.\n"; - runIfFullyInitialized(); - } - else { - console.log(result.msg); - moduleLoadingMessage = "Failed to initialize Slang Compiler, Run and Compile features are disabled.\n"; - } - } -}; - -function loadSlangWasm() { - var label = document.getElementById("loadingStatusLabel"); - if (label) - label.innerText = "Loading Slang Compiler..."; - const script = document.createElement("script"); - script.src = "slang-wasm.js"; - document.head.appendChild(script); -} - -var pageLoaded = false; -// event when loading the page -window.onload = async function () -{ - loadSlangWasm(); - pageLoaded = true; - - await webgpuInit(); - if (device) - { - document.getElementById("run-btn").disabled = false; - } - else - { - diagnosticsArea.setValue(moduleLoadingMessage + "Browser does not support WebGPU, Run shader feature is disabled."); - document.getElementById("run-btn").title = "Run shader feature is disabled because the current browser does not support WebGPU."; - } - runIfFullyInitialized(); -} - -function runIfFullyInitialized() -{ - if (compiler && slangd && pageLoaded) - { - const loadingScreen = document.getElementById('loading-screen'); - // Start fade-out by setting opacity to 0 - loadingScreen.style.opacity = '0'; - // Wait for the transition to finish before hiding completely - loadingScreen.addEventListener('transitionend', () => { - loadingScreen.style.display = 'none'; - }); - document.getElementById('contentDiv').style=""; - - restoreSelectedTargetFromURL(); - - if (device) - { - onRun(); - } - } -} diff --git a/build/ui.js b/build/ui.js deleted file mode 100644 index 09e1589..0000000 --- a/build/ui.js +++ /dev/null @@ -1,287 +0,0 @@ -// target -> profile mappings -const targetProfileMap = { - // TODO: uncomment when we support specifying profiles. - //"SPIRV": {default:"1.5", options:["1.3", "1.4", "1.5", "1.6"]}, -}; - -var entrypointSelect = null; - -// Function to update the profile dropdown based on the selected target -function updateProfileOptions(targetSelect, profileSelect) { - const selectedTarget = targetSelect.value; - // Clear the existing options in profile dropdown - profileSelect.innerHTML = ""; - - // If the selected target does not have any profiles, hide the profile dropdown. - const profiles = targetProfileMap[selectedTarget] || null; - if (!profiles) { - document.getElementById("profile-dropdown").style.display = "none"; - } - else{ - document.getElementById("profile-dropdown").style = ""; - - // Populate the profile dropdown with new options - profiles.options.forEach((profile) => { - const option = document.createElement("option"); - option.value = profile; - option.textContent = profile; - profileSelect.appendChild(option); - }); - profileSelect.value = profiles.default; - } - - // If the target can be compiled as a whole program without entrypoint selection, hide the entrypoint dropdown. - if (isWholeProgramTarget(targetSelect.value)) { - document.getElementById("entrypoint-dropdown").style.display = "none"; - document.getElementById("entrypoint-select").value = ""; - } else { - document.getElementById("entrypoint-dropdown").style = ""; - updateEntryPointOptions(); - } -} - -function updateEntryPointOptions() -{ - if (!compiler) - return; - if (!entrypointSelect) - return; - const prevValue = entrypointSelect.value; - entrypointSelect.innerHTML = ""; - var defaultOption = document.createElement("option"); - defaultOption.value = ""; - defaultOption.textContent = "Entrypoint"; - defaultOption.disabled = true; - entrypointSelect.appendChild(defaultOption); - - const entryPoints = compiler.findDefinedEntryPoints(monacoEditor.getValue()); - var prevValueExists = false; - entryPoints.forEach((entryPoint) => { - const option = document.createElement("option"); - option.value = entryPoint; - option.textContent = entryPoint; - entrypointSelect.appendChild(option); - if (entryPoint === prevValue) - { - option.selected = true; - prevValueExists = true; - } - }); - if (prevValue == "" && entryPoints.length > 0) - entrypointSelect.value = entryPoints[0]; - else if (prevValueExists) - entrypointSelect.value = prevValue; - else - { - entrypointSelect.value = ""; - defaultOption.selected = true; - } -} - -// Set all containers to overflow:hidden before resizing so they can properly shrink. -function prepareForResize() { - var codeEditors = document.getElementsByClassName("editorContainer"); - - for (var i = 0; i < codeEditors.length; i++) { - codeEditors[i].style.overflow = "hidden"; - } - document.getElementById("workSpaceDiv").style.overflow = "hidden"; - document.getElementById("leftContainerDiv").style.overflow = "hidden"; -} -// Restore the containers to overflow:visible after resizing. -function finishResizing() { - var codeEditors = document.getElementsByClassName("editorContainer"); - document.getElementById("workSpaceDiv").style.overflow = "visible"; - document.getElementById("leftContainerDiv").style.overflow = "visible"; - for (var i = 0; i < codeEditors.length; i++) { - codeEditors[i].style.overflow = "visible"; - } -} - -var finishResizingTimeout = null; -window.onresize = function () { - prepareForResize(); - if (finishResizingTimeout) - clearTimeout(finishResizingTimeout); - finishResizingTimeout = setTimeout(() => { - finishResizing(); - finishResizingTimeout = null; - }, 50); -}; - -function initializeModal() { - const modal = document.getElementById("helpModal"); - const btn = document.getElementById("helpButton"); - const closeBtn = document.querySelector(".close"); - - btn.onclick = () => { - modal.style.display = "block"; - }; - - closeBtn.onclick = () => { - modal.style.display = "none"; - }; - - window.onclick = (event) => { - if (event.target === modal) { - modal.style.display = "none"; - } - }; -} - -function handleDemoDropdown() { - const demoDropdown = document.getElementById("demo-dropdown"); - const selectInput = demoDropdown.querySelector(".dropdown-select"); - - selectInput.addEventListener("change", function () { - const selectedDemo = this.value; - switch (selectedDemo) { - case "Circle": - monacoEditor.setValue(defaultShaderCode); - break; - case "Ocean": - monacoEditor.setValue(oceanDemoCode); - break; - case "Empty Image Shader": - monacoEditor.setValue(emptyImageShader); - break; - case "Empty Print Shader": - monacoEditor.setValue(emptyPrintShader); - break; - } - sourceCodeChange = true; - }); -} - -function restoreSelectedTargetFromURL() -{ - const urlParams = new URLSearchParams(window.location.search); - const target = urlParams.get('target'); - if (target) { - const targetSelect = document.getElementById("target-select"); - const profileSelect = document.getElementById("profile-select"); - targetSelect.value = target; - updateProfileOptions(targetSelect, profileSelect); - } -} - -document.addEventListener("DOMContentLoaded", function () { - var initShaderCode = defaultShaderCode; - const urlParams = new URLSearchParams(window.location.search); - const code = urlParams.get('code'); - if (code) { - decompressFromBase64URL(code).then((decompressed) => { - initShaderCode = decompressed; - loadEditor(false, "codeEditor", initShaderCode); - }); - } - else { - loadEditor(false, "codeEditor", defaultShaderCode); - } - loadEditor(true, "diagnostics", "Diagnostic Output"); - loadEditor(true, "codeGen", "Generated Target Code"); - - Split({ - columnGutters: [ - { - track: 1, - element: document.querySelector(".mainContainer > .gutter-horizontal"), - }, - ], - rowGutters: [ - { - track: 1, - element: document.querySelector(".workSpace > .gutter-vertical"), - }, - { - track: 1, - element: document.querySelector(".resultSpace > .gutter-vertical"), - }, - ], - onDragStart: ()=>prepareForResize(), - onDragEnd: ()=>finishResizing(), - }); - handleDemoDropdown(); - - // Target -> Profile handling - const targetSelect = document.getElementById("target-select"); - const profileSelect = document.getElementById("profile-select"); - entrypointSelect = document.getElementById("entrypoint-select"); - entrypointSelect.addEventListener('focus', updateEntryPointOptions); // for keyboard access - entrypointSelect.addEventListener('mousedown', updateEntryPointOptions); // for mouse access - - updateProfileOptions(targetSelect, profileSelect); - - targetSelect.addEventListener("change", () => { - updateProfileOptions(targetSelect, profileSelect); - }); - - // modal functionality - initializeModal(); -}); - - -let pakoLoaded = false; -var pako = null; -// Lazy load function that loads pako on the first call -function loadPako() { - if (pako == null) - pako = BrowserCJS.require("https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.4/pako.min.js"); - return pako; -} - -// Function to compress and decompress text, loading pako if necessary -async function compressToBase64URL(text) { - const pako = loadPako(); // Ensure pako is loaded - - // Compress the text - const compressed = pako.deflate(text, { to: 'string' }); - const base64 = btoa(String.fromCharCode(...new Uint8Array(compressed))); - - return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); -} - -async function decompressFromBase64URL(base64) { - const pako = loadPako(); // Ensure pako is loaded - // Decode the base64 URL - base64 = base64.replace(/-/g, '+').replace(/_/g, '/'); - const compressed = Uint8Array.from(atob(base64), c => c.charCodeAt(0)); - // Decompress the data - const decompressed = pako.inflate(compressed, { to: 'string' }); - - return decompressed; -} - -function showTooltip(button, text) { - document.getElementById("tooltip").textContent = text; - // Position the tooltip near the button - const rect = button.getBoundingClientRect(); - tooltip.style.top = `${rect.bottom + window.scrollY + 15}px`; - tooltip.style.left = `${rect.left + window.scrollX}px`; - - // Show the tooltip - tooltip.classList.add('show'); - - // Hide the tooltip after 3 seconds - setTimeout(() => { - tooltip.classList.remove('show'); - }, 3000); -} - -var btnShareLink = document.getElementById("shareButton"); -btnShareLink.onclick = async function () { - if (!monacoEditor) return; - try{ - const code = monacoEditor.getValue(); - const compressed = await compressToBase64URL(code); - let url = new URL(window.location.href.split('?')[0]); - const compileTarget = document.getElementById("target-select").value; - url.searchParams.set("target", compileTarget) - url.searchParams.set("code", compressed); - navigator.clipboard.writeText(url.href); - showTooltip(btnShareLink, "Link copied to clipboard."); - } - catch(e){ - showTooltip(btnShareLink, "Failed to copy link to clipboard."); - } -}; diff --git a/build/util.js b/build/util.js deleted file mode 100644 index 7aa5dcc..0000000 --- a/build/util.js +++ /dev/null @@ -1,27 +0,0 @@ -function configContext(device, canvas) { - let context = canvas.getContext('webgpu'); - - const canvasConfig = { - device: device, - format: navigator.gpu.getPreferredCanvasFormat(), - usage: - GPUTextureUsage.RENDER_ATTACHMENT, - }; - - context.configure(canvasConfig); - return context; -} - -function createOutputTexture(device, width, height, format) { - const textureDesc = { - label: 'output storage texture', - size: {width: width, height: height}, - format: format, - usage: GPUTextureUsage.COPY_SRC | - GPUTextureUsage.STORAGE_BINDING | - GPUTextureUsage.TEXTURE_BINDING, - }; - - let storageTexture = device.createTexture(textureDesc); - return storageTexture; -} diff --git a/build/utility_module.slang b/build/utility_module.slang deleted file mode 100644 index b429f4c..0000000 --- a/build/utility_module.slang +++ /dev/null @@ -1,4 +0,0 @@ -export int testFunc(int a) -{ - return a + 1; -} diff --git a/build/water_demo.js b/build/water_demo.js deleted file mode 100644 index 7c069bb..0000000 --- a/build/water_demo.js +++ /dev/null @@ -1,235 +0,0 @@ -const oceanDemoCode = -` -// afl_ext 2017-2024 -// MIT License -import playground; - -#define DRAG_MULT 0.38 // changes how much waves pull on the water -#define WATER_DEPTH 1.0 // how deep is the water -#define CAMERA_HEIGHT 1.5 // how high the camera should be -#define ITERATIONS_RAYMARCH 12 // waves iterations of raymarching -#define ITERATIONS_NORMAL 37 // waves iterations when calculating normals - - -// Calculates wave value and its derivative, -// for the wave direction, position in space, wave frequency and time -float2 wavedx(float2 position, float2 direction, float frequency, float timeshift) { - float x = dot(direction, position) * frequency + timeshift; - float wave = exp(sin(x) - 1.0); - float dx = wave * cos(x); - return float2(wave, -dx); -} - -// Calculates waves by summing octaves of various waves with various parameters -float getwaves(float2 position, int iterations) { - float wavePhaseShift = length(position) * 0.1; // this is to avoid every octave having exactly the same phase everywhere - float iter = 0.0; // this will help generating well distributed wave directions - float frequency = 1.0; // frequency of the wave, this will change every iteration - float timeMultiplier = 0.5; // time multiplier for the wave, this will change every iteration - float weight = 1.0;// weight in final sum for the wave, this will change every iteration - float sumOfValues = 0.0; // will store final sum of values - float sumOfWeights = 0.0; // will store final sum of weights - for(int i=0; i < iterations; i++) { - // generate some wave direction that looks kind of random - float2 p = float2(sin(iter), cos(iter)); - - // calculate wave data - float2 res = wavedx(position, p, frequency, getTime() * timeMultiplier + wavePhaseShift); - - // shift position around according to wave drag and derivative of the wave - position += p * res.y * weight * DRAG_MULT; - - // add the results to sums - sumOfValues += res.x * weight; - sumOfWeights += weight; - - // modify next octave ; - weight = lerp(weight, 0.0, 0.2); - frequency *= 1.18; - timeMultiplier *= 1.07; - - // add some kind of random value to make next wave look random too - iter += 1232.399963; - } - // calculate and return - return sumOfValues / sumOfWeights; -} - -float3 interpolation(float3 x, float3 y, float factor) -{ - return x + (y - x) * factor; -} - -// Raymarches the ray from top water layer boundary to low water layer boundary -float raymarchwater(float3 camera, float3 start, float3 end, float depth) { - float3 pos = start; - float3 dir = normalize(end - start); - for(int i=0; i < 64; i++) { - // the height is from 0 to -depth - float height = getwaves(pos.xz, ITERATIONS_RAYMARCH) * depth - depth; - // if the waves height almost nearly matches the ray height, assume its a hit and return the hit distance - if(height + 0.01 > pos.y) { - return distance(pos, camera); - } - // iterate forwards according to the height mismatch - pos += dir * (pos.y - height); - } - // if hit was not registered, just assume hit the top layer, - // this makes the raymarching faster and looks better at higher distances - return distance(start, camera); -} - -// Calculate normal at point by calculating the height at the pos and 2 additional points very close to pos -float3 normal(float2 pos, float e, float depth) { - float2 ex = float2(e, 0); - float H = getwaves(pos.xy, ITERATIONS_NORMAL) * depth; - float3 a = float3(pos.x, H, pos.y); - return normalize( - cross( - a - float3(pos.x - e, getwaves(pos.xy - ex.xy, ITERATIONS_NORMAL) * depth, pos.y), - a - float3(pos.x, getwaves(pos.xy + ex.yx, ITERATIONS_NORMAL) * depth, pos.y + e) - ) - ); -} - -// Helper function generating a rotation matrix around the axis by the angle -float3x3 createRotationMatrixAxisAngle(float3 axis, float angle) { - float s = sin(angle); - float c = cos(angle); - float oc = 1.0 - c; - return float3x3( - oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, - oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, - oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c - ); -} - -// Helper function that generates camera ray based on UV and mouse -float3 getRay(float2 fragCoord, float2 resolution) { - float2 uv = ((fragCoord.xy / resolution.xy) * 2.0 - 1.0) * float2(resolution.x / resolution.y, 1.0); - // for fisheye, uncomment following line and comment the next one - //float3 proj = normalize(float3(uv.x, uv.y, 1.0) + float3(uv.x, uv.y, -1.0) * pow(length(uv), 2.0) * 0.05); - float3 proj = normalize(float3(uv.x, uv.y, 1.5)); - if(resolution.x < 600.0) { - return proj; - } - float3x3 mat = mul(createRotationMatrixAxisAngle(float3(0.0, -1.0, 0.0), 0.0), - createRotationMatrixAxisAngle(float3(1.0, 0.0, 0.0), 0.0) - ); - return mul(mat, proj); -} - -// Ray-Plane intersection checker -float intersectPlane(float3 origin, float3 direction, float3 point, float3 normal) { - return clamp(dot(point - origin, normal) / dot(direction, normal), -1.0, 9991999.0); -} - -// Some very barebones but fast atmosphere approximation -float3 extra_cheap_atmosphere(float3 raydir, float3 sundir) { - sundir.y = max(sundir.y, -0.07); - float special_trick = 1.0 / (raydir.y * 1.0 + 0.1); - float special_trick2 = 1.0 / (sundir.y * 11.0 + 1.0); - float raysundt = pow(abs(dot(sundir, raydir)), 2.0); - float sundt = pow(max(0.0, dot(sundir, raydir)), 8.0); - float mymie = sundt * special_trick * 0.2; - float3 suncolor = lerp(float3(1.0), max(float3(0.0), float3(1.0) - float3(5.5, 13.0, 22.4) / 22.4), special_trick2); - float3 bluesky= float3(5.5, 13.0, 22.4) / 22.4 * suncolor; - float3 bluesky2 = max(float3(0.0), bluesky - float3(5.5, 13.0, 22.4) * 0.002 * (special_trick + -6.0 * sundir.y * sundir.y)); - bluesky2 *= special_trick * (0.24 + raysundt * 0.24); - return bluesky2 * (1.0 + 1.0 * pow(1.0 - raydir.y, 3.0)); -} - -// Calculate where the sun should be, it will be moving around the sky -float3 getSunDirection() { - float time = getTime(); - return normalize(float3(sin(time * 0.1), 1.0, cos(time * 0.1))); -} - -// Get atmosphere color for given direction -float3 getAtmosphere(float3 dir) { - float time = getTime(); - return extra_cheap_atmosphere(dir, getSunDirection()) * 0.5; -} - -// Get sun color for given direction -float getSun(float3 dir) { - float time = getTime(); - return pow(max(0.0, dot(dir, getSunDirection())), 720.0) * 210.0; -} - -// Great tonemapping function from my other shader: https://www.shadertoy.com/view/XsGfWV -float3 aces_tonemap(float3 color) { - float3x3 m1 = float3x3( - 0.59719, 0.07600, 0.02840, - 0.35458, 0.90834, 0.13383, - 0.04823, 0.01566, 0.83777 - ); - - float3x3 m2 = float3x3( - 1.60475, -0.10208, -0.00327, - -0.53108, 1.10813, -0.07276, - -0.07367, -0.00605, 1.07602 - ); - - float3 v = mul(m1, color); - float3 a = v * (v + 0.0245786) - 0.000090537; - float3 b = v * (0.983729 * v + 0.4329510) + 0.238081; - return pow(clamp(mul(m2, (a / b)), 0.0, 1.0), float3(1.0 / 2.2)); -} - -float4 imageMain(uint2 dispatchThreadID, int2 screenSize) -{ - float2 size = float2(screenSize.x, screenSize.y); - - // get the ray - float3 ray = getRay(dispatchThreadID.xy, size); - if(ray.y >= 0.0) { - // if ray.y is positive, render the sky - float3 C = getAtmosphere(ray) + getSun(ray); - float4 color = float4(aces_tonemap(C * 2.0),1.0); - return color; - } - - // now ray.y must be negative, water must be hit - // define water planes - float3 waterPlaneHigh = float3(0.0, 0.0, 0.0); - float3 waterPlaneLow = float3(0.0, -WATER_DEPTH, 0.0); - - // define ray origin, moving around - float3 origin = float3(getTime() * 0.2, CAMERA_HEIGHT, 1); - - // calculate intersections and reconstruct positions - float highPlaneHit = intersectPlane(origin, ray, waterPlaneHigh, float3(0.0, 1.0, 0.0)); - float lowPlaneHit = intersectPlane(origin, ray, waterPlaneLow, float3(0.0, 1.0, 0.0)); - float3 highHitPos = origin + ray * highPlaneHit; - float3 lowHitPos = origin + ray * lowPlaneHit; - - // raymatch water and reconstruct the hit pos - float dist = raymarchwater(origin, highHitPos, lowHitPos, WATER_DEPTH); - float3 waterHitPos = origin + ray * dist; - - // calculate normal at the hit position - float3 N = normal(waterHitPos.xz, 0.01, WATER_DEPTH); - - // smooth the normal with distance to avoid disturbing high frequency noise - float interpFactor = 0.8 * min(1.0, sqrt(dist*0.01) * 1.1); - // N = lerp(N, float3(0.0, 1.0, 0.0), interpFactor); - N = interpolation(N, float3(0.0, 1.0, 0.0), interpFactor); - - // calculate fresnel coefficient - float fresnel = (0.04 + (1.0-0.04)*(pow(1.0 - max(0.0, dot(-N, ray)), 5.0))); - - // reflect the ray and make sure it bounces up - float3 R = normalize(reflect(ray, N)); - R.y = abs(R.y); - - // calculate the reflection and approximate subsurface scattering - float3 reflection = getAtmosphere(R) + getSun(R); - float3 scattering = float3(0.0293, 0.0698, 0.1717) * 0.1 * (0.2 + (waterHitPos.y + WATER_DEPTH) / WATER_DEPTH); - - // return the combined result - float3 C = fresnel * reflection + scattering; - float4 color = float4(aces_tonemap(C * 2.0), 1.0); - return color; -} -`; diff --git a/compiler.js b/compiler.js index 9af2769..d617be4 100644 --- a/compiler.js +++ b/compiler.js @@ -7,8 +7,10 @@ const imageMainSource = ` import user; import playground; -RWStructuredBuffer outputBuffer; -[format("r32f")] RWTexture2D texture; +RWStructuredBuffer outputBuffer; + +[format("rgba8")] +WTexture2D outputTexture; inline float encodeColor(float4 color) { @@ -27,15 +29,14 @@ void imageMain(uint3 dispatchThreadID : SV_DispatchThreadID) { uint width = 0; uint height = 0; - texture.GetDimensions(width, height); + outputTexture.GetDimensions(width, height); if (dispatchThreadID.x >= width || dispatchThreadID.y >= height) return; float4 color = imageMain(dispatchThreadID.xy, int2(width, height)); - float encodedColor = encodeColor(color); - texture[dispatchThreadID.xy] = encodedColor; + outputTexture.Store(dispatchThreadID.xy, color); } `; @@ -45,7 +46,9 @@ import user; import playground; RWStructuredBuffer outputBuffer; -[format("r32f")] RWTexture2D texture; + +[format("rgba8")] +WTexture2D outputTexture; [shader("compute")] [numthreads(1, 1, 1)] diff --git a/compute.js b/compute.js index 59cefae..ed003f8 100644 --- a/compute.js +++ b/compute.js @@ -36,7 +36,7 @@ class ComputePipeline {binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'uniform'}}, {binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, {binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}}, - {binding: 3, visibility: GPUShaderStage.COMPUTE, storageTexture: {access: "read-write", format: this.outputTexture.format}}, + {binding: 3, visibility: GPUShaderStage.COMPUTE, storageTexture: {access: "write-only", format: this.outputTexture.format}}, ], }; @@ -126,9 +126,7 @@ class ComputePipeline this.outputBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size, usage}); this.printfBufferRead = this.device.createBuffer({lable: 'outputBufferRead', size: this.printfBufferSize, usage}); - const storageTexture = createOutputTexture(device, windowSize[0], windowSize[1], 'r32float'); - this.outputTexture = storageTexture; - + this.outputTexture = createOutputTexture(device, windowSize[0], windowSize[1], 'rgba8unorm'); } } diff --git a/pass_through.js b/pass_through.js index d1374c6..d9e5f98 100644 --- a/pass_through.js +++ b/pass_through.js @@ -45,12 +45,7 @@ var passThroughshaderCode = ` @fragment fn fs(fsInput: VertexShaderOutput) -> @location(0) vec4f { let color = textureSample(ourTexture, ourSampler, fsInput.texcoord); - let value = u32(color.x); - let r = ((value & 0xFF000000) >> 24); - let g = ((value & 0x00FF0000) >> 16); - let b = ((value & 0x0000FF00) >> 8); - - return vec4f(f32(r)/255.0f, f32(g)/255.0f, f32(b)/255.0f, 1.0f); + return color; } `; @@ -98,7 +93,7 @@ class GraphicsPipeline fragment: { module: shaderModule, - targets: [{format: navigator.gpu.getPreferredCanvasFormat()}] + targets: [{format: navigator.gpu.getPreferredCanvasFormat(),}] }, }); this.pipeline = pipeline; diff --git a/try-slang.js b/try-slang.js index 9bd7e04..afbdbe5 100644 --- a/try-slang.js +++ b/try-slang.js @@ -262,11 +262,6 @@ async function printResult() document.getElementById("printResult").value = textResult; } -function parsePrintfBuffer(buffer) -{ - -} - function checkShaderType(userSource) { // we did a pre-filter on the user input source code. From 18cecd16a62aac317172348f8e33e30635bff006 Mon Sep 17 00:00:00 2001 From: kaizhangNV Date: Thu, 31 Oct 2024 10:01:19 -0700 Subject: [PATCH 3/4] Finish parsing printf format string --- compiler.js | 2 +- compute.js | 38 +++++++---- playgroundShader.js | 3 +- try-slang.js | 13 ++-- util.js | 156 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 190 insertions(+), 22 deletions(-) diff --git a/compiler.js b/compiler.js index d617be4..31adbfd 100644 --- a/compiler.js +++ b/compiler.js @@ -73,7 +73,7 @@ import playground; int printMain() { - print("%d\\n", 0); + print("%d, %3.2d, 0x%x, %8.3f, %s, %e\n", 2, 3456, 2134, 40.1234, "hello world", 12.547); return 0; } `; diff --git a/compute.js b/compute.js index ed003f8..a663bd5 100644 --- a/compute.js +++ b/compute.js @@ -1,4 +1,6 @@ +var sprintf = null; + class ComputePipeline { pipeline; @@ -166,24 +168,39 @@ class ComputePipeline { formatString = hashedString.getString(printfBufferArray[1]); // low field } + else + { + // If the first element is not a string, we will just return an empty string, it indicates + // that the printf buffer is empty. + return ""; + } // TODO: We currently doesn't support 64-bit data type (e.g. uint64_t, int64_t, double, etc.) // so 32-bit array should be able to contain everything we need. - var dataArray = new Uint32Array(numberElements); - var stringArray = []; + var dataArray = []; const elementSizeInWords = this.printfBufferElementSize / 4; for (elementIndex = 1; elementIndex < numberElements; elementIndex++) { var offset = elementIndex * elementSizeInWords; const type = printfBufferArray[offset]; - if (type == 1) // type field, this is a string + if (type == 1) // type field, this is a string + { + dataArray.push(hashedString.getString(printfBufferArray[offset + 1])); // low field + } + else if (type == 2) // type field { - stringArray.push(hashedString.getString(printfBufferArray[offset + 1])); // low field + dataArray.push(printfBufferArray[offset + 1]); // low field } - else if (type == 2) // type field + else if (type == 3) // type field { - dataArray[elementIndex - 1] = printfBufferArray[offset + 1]; // low field + const floatData = reinterpretUint32AsFloat(printfBufferArray[offset + 1]); + dataArray.push(floatData); // low field + } + else if (type == 4) // type field + { + // TODO: We can't handle 64-bit data type yet. + dataArray.push(0); // low field } else if (type == 0xFFFFFFFF) { @@ -191,11 +208,8 @@ class ComputePipeline } } - return {formatString: formatString, dataArray: dataArray.slice(0, elementIndex - 1), stringArray: stringArray}; - } - - // TODO: construct the final formatted result - formatToString(formatString, dataArray, stringArray) - { + const parsedTokens = parsePrintfFormat(formatString); + const output = formatPrintfString(parsedTokens, dataArray); + return output; } } diff --git a/playgroundShader.js b/playgroundShader.js index 2eb90b2..e90f7bf 100644 --- a/playgroundShader.js +++ b/playgroundShader.js @@ -8,6 +8,7 @@ public float getTime() return time; } +// type field: 1 for string, 2 for integer, 3 for float, 4 for double struct FormatedStruct { uint32_t type = 0xFFFFFFFF; @@ -47,7 +48,7 @@ extension int : IPrintf extension float : IPrintf { - uint32_t typeFlag() { return 2;} + uint32_t typeFlag() { return 3;} uint32_t writePrintfWords() { return bit_cast(this); } } diff --git a/try-slang.js b/try-slang.js index afbdbe5..1b30fa3 100644 --- a/try-slang.js +++ b/try-slang.js @@ -247,14 +247,11 @@ async function printResult() const output = new Int32Array(computePipeline.outputBufferRead.getMappedRange()); // debug testing: - let textResult = output.toString() + "\n"; - if (compiler.hashedString) - { - const result = computePipeline.parsePrintfBuffer(compiler.hashedString) - textResult += "Format string: " + result.formatString + "\n"; - textResult += "Data view: " + result.dataArray.toString() + "\n"; - textResult += "String view: " + result.stringArray.toString() + "\n"; - } + let textResult = "Data Output:\n" + output.toString() + "\n\n"; + const formatPrint = computePipeline.parsePrintfBuffer(compiler.hashedString); + if (formatPrint != "") + textResult += "Formatted Printf:\n" + formatPrint + "\n"; + computePipeline.outputBufferRead.unmap(); computePipeline.printfBufferRead.unmap(); diff --git a/util.js b/util.js index 7aa5dcc..e10f85f 100644 --- a/util.js +++ b/util.js @@ -25,3 +25,159 @@ function createOutputTexture(device, width, height, format) { let storageTexture = device.createTexture(textureDesc); return storageTexture; } + +function reinterpretUint32AsFloat(uint32) +{ + const buffer = new ArrayBuffer(4); + const uint32View = new Uint32Array(buffer); + const float32View = new Float32Array(buffer); + + uint32View[0] = uint32; + return float32View[0]; +} + +function parsePrintfFormat(formatString) +{ + const formatSpecifiers = []; + const regex = /%([-+ #0]*)(\d*)(\.\d+)?([diufFeEgGxXosc])/g; + let lastIndex = 0; + + let match; + while ((match = regex.exec(formatString)) !== null) + { + const [fullMatch, flags, width, precision, type] = match; + const literalText = formatString.slice(lastIndex, match.index); + + // Add literal text before the match as a token, if any + if (literalText) + { + formatSpecifiers.push({ type: 'text', value: literalText }); + } + + // Add the format specifier as a token + formatSpecifiers.push({ + type: 'specifier', + flags: flags || '', + width: width || null, + precision: precision ? precision.slice(1) : null, // remove leading '.' + specifierType: type + }); + + lastIndex = regex.lastIndex; + } + + // Add any remaining literal text after the last match + if (lastIndex < formatString.length) + { + formatSpecifiers.push({ type: 'text', value: formatString.slice(lastIndex) }); + } + + return formatSpecifiers; +} + +function formatPrintfString(parsedTokens, data) +{ + let result = ''; + let dataIndex = 0; + + parsedTokens.forEach(token => { + if (token.type === 'text') + { + result += token.value; + } + else if (token.type === 'specifier') + { + const value = data[dataIndex++]; + result += formatSpecifier(value, token); + } + }); + + return result; +} + +// Helper function to format each specifier +function formatSpecifier(value, { flags, width, precision, specifierType }) +{ + let formattedValue; + + switch (specifierType) + { + case 'd': + case 'i': // Integer (decimal) + formattedValue = parseInt(value).toString(); + break; + case 'u': // Unsigned integer + formattedValue = Math.abs(parseInt(value)).toString(); + break; + case 'o': // Octal + formattedValue = Math.abs(parseInt(value)).toString(8); + break; + case 'x': // Hexadecimal (lowercase) + formattedValue = Math.abs(parseInt(value)).toString(16); + break; + case 'X': // Hexadecimal (uppercase) + formattedValue = Math.abs(parseInt(value)).toString(16).toUpperCase(); + break; + case 'f': + case 'F': // Floating-point + formattedValue = parseFloat(value).toFixed(precision || 6); + break; + case 'e': // Scientific notation (lowercase) + formattedValue = parseFloat(value).toExponential(precision || 6); + break; + case 'E': // Scientific notation (uppercase) + formattedValue = parseFloat(value).toExponential(precision || 6).toUpperCase(); + break; + case 'g': + case 'G': // Shortest representation of floating-point + formattedValue = parseFloat(value).toPrecision(precision || 6); + break; + case 'c': // Character + formattedValue = String.fromCharCode(parseInt(value)); + break; + case 's': // String + formattedValue = String(value); + if (precision) + { + formattedValue = formattedValue.slice(0, precision); + } + break; + case '%': // Literal '%' + return '%'; + default: + throw new Error(`Unsupported specifier: ${specifierType}`); + } + + // Handle width and flags (like zero-padding, space, left alignment, sign) + if (width) + { + const paddingChar = flags.includes('0') && !flags.includes('-') ? '0' : ' '; + const isLeftAligned = flags.includes('-'); + const needsSign = flags.includes('+') && parseFloat(value) >= 0; + const needsSpace = flags.includes(' ') && !needsSign && parseFloat(value) >= 0; + + if (needsSign) + { + formattedValue = '+' + formattedValue; + } + else if (needsSpace) + { + formattedValue = ' ' + formattedValue; + } + + if (formattedValue.length < width) + { + const padding = paddingChar.repeat(width - formattedValue.length); + formattedValue = isLeftAligned ? formattedValue + padding : padding + formattedValue; + } + } + + return formattedValue; +} + +// // Example usage +// const formatString = "Int: %d, Unsigned: %u, Hex: %X, Float: %8.2f, Sci: %e, Char: %c, Str: %.5s!"; +// const parsedTokens = parsePrintfFormat(formatString); +// const data = [42, -42, 255, 3.14159, 0.00001234, 65, "Hello, world"]; +// const output = formatPrintfString(parsedTokens, data); +// console.log(output); From 40c0204a78d91e7ee62e17f7862237e5314586de Mon Sep 17 00:00:00 2001 From: kaizhangNV Date: Thu, 31 Oct 2024 12:47:38 -0700 Subject: [PATCH 4/4] cleanup --- compiler.js | 8 +++----- compute.js | 2 -- try-slang.js | 13 +++---------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/compiler.js b/compiler.js index 31adbfd..558e393 100644 --- a/compiler.js +++ b/compiler.js @@ -54,8 +54,7 @@ WTexture2D outputTexture; [numthreads(1, 1, 1)] void printMain(uint3 dispatchThreadID : SV_DispatchThreadID) { - int res = printMain(); - outputBuffer[0] = res; + printMain(); } `; @@ -71,10 +70,9 @@ float4 imageMain(uint2 dispatchThreadID, int2 screenSize) const emptyPrintShader = ` import playground; -int printMain() +void printMain() { - print("%d, %3.2d, 0x%x, %8.3f, %s, %e\n", 2, 3456, 2134, 40.1234, "hello world", 12.547); - return 0; + print("%d, %3.2d, 0x%x, %8.3f, %s, %e\\n", 2, 3456, 2134, 40.1234, "hello world", 12.547); } `; diff --git a/compute.js b/compute.js index a663bd5..4f21f06 100644 --- a/compute.js +++ b/compute.js @@ -1,6 +1,4 @@ -var sprintf = null; - class ComputePipeline { pipeline; diff --git a/try-slang.js b/try-slang.js index 1b30fa3..a70c4af 100644 --- a/try-slang.js +++ b/try-slang.js @@ -239,23 +239,16 @@ async function printResult() device.queue.submit([commandBuffer]); await device.queue.onSubmittedWorkDone(); - // Read the results once the job is done - await Promise.all([ - computePipeline.outputBufferRead.mapAsync(GPUMapMode.READ), - computePipeline.printfBufferRead.mapAsync(GPUMapMode.READ)]); - const output = new Int32Array(computePipeline.outputBufferRead.getMappedRange()); + // Read the results once the job is done + await computePipeline.printfBufferRead.mapAsync(GPUMapMode.READ); - // debug testing: - let textResult = "Data Output:\n" + output.toString() + "\n\n"; + var textResult = ""; const formatPrint = computePipeline.parsePrintfBuffer(compiler.hashedString); if (formatPrint != "") textResult += "Formatted Printf:\n" + formatPrint + "\n"; - - computePipeline.outputBufferRead.unmap(); computePipeline.printfBufferRead.unmap(); - document.getElementById("printResult").value = textResult; }