diff --git a/base/sources/backends/data/wasm/index.html b/base/sources/backends/data/wasm/index.html index 93c96326..18e1ef4d 100644 --- a/base/sources/backends/data/wasm/index.html +++ b/base/sources/backends/data/wasm/index.html @@ -1,6 +1,5 @@ - - + diff --git a/base/sources/backends/data/wasm/start.js b/base/sources/backends/data/wasm/start.js index 1ea61de8..d4b37917 100644 --- a/base/sources/backends/data/wasm/start.js +++ b/base/sources/backends/data/wasm/start.js @@ -1,35 +1,12 @@ -// Includes snippets from https://surma.dev/things/c-to-webassembly/ and https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API --> -let memory = null; -let heapu8 = null; -let heapu16 = null; -let heapu32 = null; -let heapi32 = null; -let heapf32 = null; -let mod = null; +let memory = null; +let heapu8 = null; +let heapu16 = null; +let heapu32 = null; +let heapi32 = null; +let heapf32 = null; +let module = null; let instance = null; -let audio_thread_started = false; - -function create_thread(func) { - console.log('Creating thread'); - const thread_starter = new Worker('thread_starter.js'); - const arr = new Uint8Array(memory.buffer, func, 256); - let str = ''; - for (let i = 0; arr[i] != 0; ++i) { - str += String.fromCharCode(arr[i]); - } - thread_starter.postMessage({ mod, memory, func: str }); -} - -async function start_audio_thread() { - const audioContext = new AudioContext(); - await audioContext.audioWorklet.addModule('audio-thread.js'); - const audioThreadNode = new AudioWorkletNode(audioContext, 'audio-thread', { processorOptions: { mod, memory }}); - audioThreadNode.port.onmessage = (message) => { - console.log(message.data); - }; - audioThreadNode.connect(audioContext.destination); -} function read_string(ptr) { let str = ''; @@ -46,30 +23,48 @@ function write_string(ptr, str) { heapu8[ptr + str.length] = 0; } +async function init_webgpu(canvas) { + if (!navigator.gpu) { + throw new Error('WebGPU not supported'); + } + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter) { + throw new Error('No GPU adapter found'); + } + const device = await adapter.requestDevice(); + + const context = canvas.getContext('webgpu'); + const format = navigator.gpu.getPreferredCanvasFormat(); + + context.configure({device, format}); + return {context, device}; +} + async function init() { - let wasm_bytes = null; - await fetch("./ShaderTest.wasm").then(res => res.arrayBuffer()).then(buffer => wasm_bytes = new Uint8Array(buffer)); + let wasm_bytes = null; + await fetch("./start.wasm").then(res => res.arrayBuffer()).then(buffer => wasm_bytes = new Uint8Array(buffer)); // Read memory size from wasm file let memory_size = 0; - let i = 8; + let i = 8; while (i < wasm_bytes.length) { function read_leb() { let result = 0; - let shift = 0; + let shift = 0; while (true) { let byte = wasm_bytes[i++]; result |= (byte & 0x7f) << shift; - if ((byte & 0x80) == 0) return result; + if ((byte & 0x80) == 0) + return result; shift += 7; } } - let type = read_leb() + let type = read_leb() let length = read_leb() if (type == 6) { read_leb(); // count - i++; // gtype - i++; // mutable + i++; // gtype + i++; // mutable read_leb(); // opcode memory_size = read_leb() / 65536 + 1; break; @@ -77,464 +72,237 @@ async function init() { i += length; } - memory = new WebAssembly.Memory({ initial: memory_size, maximum: memory_size, shared: true }); - heapu8 = new Uint8Array(memory.buffer); + memory = new WebAssembly.Memory({initial : memory_size, maximum : memory_size, shared : true}); + heapu8 = new Uint8Array(memory.buffer); heapu16 = new Uint16Array(memory.buffer); heapu32 = new Uint32Array(memory.buffer); heapi32 = new Int32Array(memory.buffer); heapf32 = new Float32Array(memory.buffer); - const kanvas = document.getElementById('kanvas'); - const gl = kanvas.getContext('webgl2', { antialias: false, alpha: false }); - // gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1); - gl.getExtension("EXT_color_buffer_float"); - gl.getExtension("OES_texture_float_linear"); - gl.getExtension("OES_texture_half_float_linear"); - gl.getExtension("EXT_texture_filter_anisotropic"); + const canvas = document.getElementById('iron'); - let file_buffer = null; + const {context, device} = await init_webgpu(canvas); + + let file_buffer = null; let file_buffer_pos = 0; - let gl_programs = [null]; - let gl_shaders = [null]; - let gl_buffers = [null]; - let gl_framebuffers = [null]; - let gl_renderbuffers = [null]; - let gl_textures = [null]; - let gl_locations = [null]; - const result = await WebAssembly.instantiate( - wasm_bytes, { - env: { memory }, - imports: { - create_thread, - glViewport: function(x, y, width, height) { - gl.viewport(x, y, width, height); - }, - glScissor: function(x, y, width, height) { - gl.scissor(x, y, width, height); - }, - glGetIntegerv: function(pname, data) { - if (pname == 2) { // GL_MAJOR_VERSION - heapu32[data / 4] = 3; - } - else { - heapu32[data / 4] = gl.getParameter(pname); - } - }, - glGetFloatv: function(pname, data) { - heapf32[data / 4] = gl.getParameter(pname); - }, - glGetString: function(name) { - // return gl.getParameter(name); - }, - glDrawElements: function(mode, count, type, offset) { - gl.drawElements(mode, count, type, offset); - }, - glDrawElementsInstanced: function(mode, count, type, indices, instancecount) { - gl.drawElementsInstanced(mode, count, type, indices, instancecount); - }, - glVertexAttribDivisor: function(index, divisor) { - gl.vertexAttribDivisor(index, divisor); - }, - glBindFramebuffer: function(target, framebuffer) { - gl.bindFramebuffer(target, gl_framebuffers[framebuffer]); - }, - glFramebufferTexture2D: function(target, attachment, textarget, texture, level) { - gl.framebufferTexture2D(target, attachment, textarget, gl_textures[texture], level); - if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { - console.log("Incomplete framebuffer"); - } - }, - glGenFramebuffers: function(n, framebuffers) { - for (let i = 0; i < n; ++i) { - gl_framebuffers.push(gl.createFramebuffer()); - heapu32[framebuffers / 4 + i] = gl_framebuffers.length - 1; - } - }, - glGenRenderbuffers: function(n, renderbuffers) { - for (let i = 0; i < n; ++i) { - gl_renderbuffers.push(gl.createRenderbuffer()); - heapu32[renderbuffers / 4 + i] = gl_renderbuffers.length - 1; - } - }, - glBindRenderbuffer: function(target, renderbuffer) { - gl.bindRenderbuffer(target, gl_renderbuffers[renderbuffer]); - }, - glRenderbufferStorage: function(target, internalformat, width, height) { - gl.renderbufferStorage(target, internalformat, width, height) - }, - glFramebufferRenderbuffer: function(target, attachment, renderbuffertarget, renderbuffer) { - gl.framebufferRenderbuffer(target, attachment, renderbuffertarget, gl_renderbuffers[renderbuffer]); - }, - glReadPixels: function(x, y, width, height, format, type, data) { - let pixels = type == gl.FLOAT ? heapf32.subarray(data / 4) : heapu8.subarray(data); - gl.readPixels(x, y, width, height, format, type, pixels); - }, - glTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, type, pixels) { - gl.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, heapu8.subarray(pixels)); - }, - glEnable: function(cap) { - gl.enable(cap); - }, - glDisable: function(cap) { - gl.disable(cap); - }, - glColorMask: function(red, green, blue, alpha) { - gl.colorMask(red, green, blue, alpha); - }, - glClearColor: function(red, green, blue, alpha) { - gl.clearColor(red, green, blue, alpha); - }, - glDepthMask: function(flag) { - gl.depthMask(flag); - }, - glClearDepthf: function(depth) { - gl.clearDepth(depth); - }, - glStencilMask: function(mask) { - gl.stencilMask(mask); - }, - glClearStencil: function(s) { - gl.clearStencil(s); - }, - glClear: function(mask) { - gl.clear(mask); - }, - glBindBuffer: function(target, buffer) { - gl.bindBuffer(target, gl_buffers[buffer]); - }, - glUseProgram: function(program) { - gl.useProgram(gl_programs[program]); - }, - glStencilMaskSeparate: function(face, mask) { - gl.stencilMaskSeparate(face, mask); - }, - glStencilOpSeparate: function(face, fail, zfail, zpass) { - gl.stencilOpSeparate(face, fail, zfail, zpass); - }, - glStencilFuncSeparate: function(face, func, ref, mask) { - gl.stencilFuncSeparate(face, func, ref, mask); - }, - glDepthFunc: function(func) { - gl.depthFunc(func); - }, - glCullFace: function(mode) { - gl.cullFace(mode); - }, - glBlendFuncSeparate: function(src_rgb, dst_rgb, src_alpha, dst_alpha) { - gl.blendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); - }, - glBlendEquationSeparate: function(mode_rgb, mode_alpha) { - gl.blendEquationSeparate(mode_rgb, mode_alpha); - }, - glGenBuffers: function(n, buffers) { - for (let i = 0; i < n; ++i) { - gl_buffers.push(gl.createBuffer()); - heapu32[buffers / 4 + i] = gl_buffers.length - 1; - } - }, - glBufferData: function(target, size, data, usage) { - gl.bufferData(target, heapu8.subarray(data, data + Number(size)), usage); - }, - glCreateProgram: function() { - gl_programs.push(gl.createProgram()); - return gl_programs.length - 1; - }, - glAttachShader: function(program, shader) { - gl.attachShader(gl_programs[program], gl_shaders[shader]); - }, - glBindAttribLocation: function(program, index, name) { - gl.bindAttribLocation(gl_programs[program], index, read_string(name)); - }, - glLinkProgram: function(program) { - gl.linkProgram(gl_programs[program]); - }, - glGetProgramiv: function(program, pname, params) { - heapu32[params / 4] = gl.getProgramParameter(gl_programs[program], pname); - }, - glGetProgramInfoLog: function(program) { - console.log(gl.getProgramInfoLog(gl_programs[program])); - }, - glCreateShader: function(type) { - gl_shaders.push(gl.createShader(type)); - return gl_shaders.length - 1; - }, - glShaderSource: function(shader, count, source, length) { - gl.shaderSource(gl_shaders[shader], read_string(heapu32[source / 4])); - }, - glCompileShader: function(shader) { - gl.compileShader(gl_shaders[shader]); - }, - glGetShaderiv: function(shader, pname, params) { - heapu32[params / 4] = gl.getShaderParameter(gl_shaders[shader], pname); - }, - glGetShaderInfoLog: function(shader) { - console.log(gl.getShaderInfoLog(gl_shaders[shader])); - }, - glBufferSubData: function(target, offset, size, data) { - gl.bufferSubData(target, Number(offset), heapu8.subarray(data, data + Number(size)), 0); - }, - glEnableVertexAttribArray: function(index) { - gl.enableVertexAttribArray(index); - }, - glVertexAttribPointer: function(index, size, type, normalized, stride, offset) { - gl.vertexAttribPointer(index, size, type, normalized, stride, offset); - }, - glDisableVertexAttribArray: function(index) { - gl.disableVertexAttribArray(index); - }, - glGetUniformLocation: function(program, name) { - gl_locations.push(gl.getUniformLocation(gl_programs[program], read_string(name))); - return gl_locations.length - 1; - }, - glUniform1i: function(location, v0) { - gl.uniform1i(gl_locations[location], v0); - }, - glUniform2i: function(location, v0, v1) { - gl.uniform2i(gl_locations[location], v0, v1); - }, - glUniform3i: function(location, v0, v1, v2) { - gl.uniform3i(gl_locations[location], v0, v1, v2); - }, - glUniform4i: function(location, v0, v1, v2, v3) { - gl.uniform4i(gl_locations[location], v0, v1, v2, v3); - }, - glUniform1iv: function(location, count, value) { - gl.uniform1iv(gl_locations[location], count, heapi32.subarray(value / 4)); - }, - glUniform2iv: function(location, count, value) { - gl.uniform2iv(gl_locations[location], count, heapi32.subarray(value / 4)); - }, - glUniform3iv: function(location, count, value) { - gl.uniform3iv(gl_locations[location], count, heapi32.subarray(value / 4)); - }, - glUniform4iv: function(location, count, value) { - gl.uniform4iv(gl_locations[location], count, heapi32.subarray(value / 4)); - }, - glUniform1f: function(location, v0) { - gl.uniform1f(gl_locations[location], v0); - }, - glUniform2f: function(location, v0, v1) { - gl.uniform2f(gl_locations[location], v0, v1); - }, - glUniform3f: function(location, v0, v1, v2) { - gl.uniform3f(gl_locations[location], v0, v1, v2); - }, - glUniform4f: function(location, v0, v1, v2, v3) { - gl.uniform4f(gl_locations[location], v0, v1, v2, v3); - }, - glUniform1fv: function(location, count, value) { - var f32 = new Float32Array(memory.buffer, value, count); - gl.uniform1fv(gl_locations[location], f32); - }, - glUniform2fv: function(location, count, value) { - var f32 = new Float32Array(memory.buffer, value, count * 2); - gl.uniform2fv(gl_locations[location], f32); - }, - glUniform3fv: function(location, count, value) { - var f32 = new Float32Array(memory.buffer, value, count * 3); - gl.uniform3fv(gl_locations[location], f32); - }, - glUniform4fv: function(location, count, value) { - var f32 = new Float32Array(memory.buffer, value, count * 4); - gl.uniform4fv(gl_locations[location], f32); - }, - glUniformMatrix3fv: function(location, count, transpose, value) { - var f32 = new Float32Array(memory.buffer, value, 3 * 3); - gl.uniformMatrix3fv(gl_locations[location], transpose, f32); - }, - glUniformMatrix4fv: function(location, count, transpose, value) { - var f32 = new Float32Array(memory.buffer, value, 4 * 4); - gl.uniformMatrix4fv(gl_locations[location], transpose, f32); - }, - glTexParameterf: function(target, pname, param) { - gl.texParameterf(target, pname, param); - }, - glActiveTexture: function(texture) { - gl.activeTexture(texture); - }, - glBindTexture: function(target, texture) { - gl.bindTexture(target, gl_textures[texture]); - }, - glTexParameteri: function(target, pname, param) { - gl.texParameteri(target, pname, param); - }, - glGetActiveUniform: function(program, index, bufSize, length, size, type, name) { - let u = gl.getActiveUniform(gl_programs[program], index); - heapu32[size / 4] = u.size; - heapu32[type / 4] = u.type; - write_string(name, u.name); - }, - glGenTextures: function(n, textures) { - for (let i = 0; i < n; ++i) { - gl_textures.push(gl.createTexture()); - heapu32[textures / 4 + i] = gl_textures.length - 1; - } - }, - glTexImage2D: function(target, level, internalformat, width, height, border, format, type, data) { - let pixels = type == gl.FLOAT ? heapf32.subarray(data / 4) : - type == gl.UNSIGNED_INT ? heapu32.subarray(data / 4) : - type == gl.UNSIGNED_SHORT ? heapu16.subarray(data / 2) : - type == gl.HALF_FLOAT ? heapu16.subarray(data / 2) : heapu8.subarray(data); - gl.texImage2D(target, level, internalformat, width, height, border, format, type, pixels); - }, - glPixelStorei: function(pname, param) { - gl.pixelStorei(pname, param); - }, - glCompressedTexImage2D: function(target, level, internalformat, width, height, border, imageSize, data) { - gl.compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, heapu8.subarray(data)); - }, - glDrawBuffers: function(n, bufs) { - let ar = []; - for (let i = 0; i < n; ++i) { - ar.push(gl.COLOR_ATTACHMENT0 + i); - } - gl.drawBuffers(ar); - }, - glGenerateMipmap: function(target) { - gl.generateMipmap(target); - }, - glFlush: function() { - gl.flush(); - }, - glDeleteBuffers: function(n, buffers) { - for (let i = 0; i < n; ++i) { - gl.deleteBuffer(gl_buffers[heapu32[buffers / 4 + i]]); - } - }, - glDeleteTextures: function(n, textures) { - for (let i = 0; i < n; ++i) { - gl.deleteTexture(gl_textures[heapu32[textures / 4 + i]]); - } - }, - glDeleteFramebuffers: function(n, framebuffers) { - for (let i = 0; i < n; ++i) { - gl.deleteFramebuffer(gl_framebuffers[heapu32[framebuffers / 4 + i]]); - } - }, - glDeleteProgram: function(program) { - gl.deleteProgram(gl_programs[program]); - }, - glDeleteShader: function(shader) { - gl.deleteShader(gl_shaders[shader]); - }, - js_fprintf: function(format) { - console.log(read_string(format)); - }, - js_fopen: function(filename) { - const req = new XMLHttpRequest(); - req.open("GET", read_string(filename), false); - req.overrideMimeType("text/plain; charset=x-user-defined"); - req.send(); - let str = req.response; - file_buffer_pos = 0; - file_buffer = new ArrayBuffer(str.length); - let buf_view = new Uint8Array(file_buffer); - for (let i = 0; i < str.length; ++i) { - buf_view[i] = str.charCodeAt(i); - } - return 1; - }, - js_ftell: function(stream) { - return file_buffer_pos; - }, - js_fseek: function(stream, offset, origin) { - file_buffer_pos = offset; - if (origin == 1) file_buffer_pos += file_buffer.byteLength; // SEEK_END - return 0; - }, - js_fread: function(ptr, size, count, stream) { - let buf_view = new Uint8Array(file_buffer); - for (let i = 0; i < count; ++i) { - heapu8[ptr + i] = buf_view[file_buffer_pos++]; - } - return count; - }, - js_time: function() { - return window.performance.now(); - }, - js_pow: function(x) { - return Math.pow(x); - }, - js_floor: function(x) { - return Math.floor(x); - }, - js_sin: function(x) { - return Math.sin(x); - }, - js_cos: function(x) { - return Math.cos(x); - }, - js_tan: function(x) { - return Math.tan(x); - }, - js_log: function(base, exponent) { - return Math.log(base, exponent); - }, - js_exp: function(x) { - return Math.exp(x); - }, - js_sqrt: function(x) { - return Math.sqrt(x); - }, - js_eval: function(str) { - (1, eval)(read_string(str)); - } + const result = await WebAssembly.instantiate(wasm_bytes, { + env : {memory}, + imports : { + + wgpuDeviceCreateTexture : function(device, descriptor) { + return null; // WGPUTexture + }, + wgpuTextureCreateView : function(texture, descriptor) { + return null; // WGPUTextureView + }, + wgpuCreateInstance : function(descriptor) { + return null; // WGPUInstance + }, + wgpuInstanceRequestAdapter : function(instance, options, callbackInfo) { + return null; // WGPUFuture + }, + wgpuAdapterGetInfo : function(adapter, info) { + return null; // WGPUStatus + }, + wgpuAdapterInfoFreeMembers : function(adapterInfo) { + }, + wgpuAdapterRequestDevice : function(adapter, descriptor, callbackInfo) { + return null; // WGPUFuture + }, + wgpuDeviceGetQueue : function(device) { + return null; // WGPUQueue + }, + wgpuDeviceCreateBindGroupLayout : function(device, descriptor) { + return null; // WGPUBindGroupLayout + }, + wgpuDeviceCreateBuffer : function(device, descriptor) { + return null; // WGPUBuffer + }, + wgpuBufferGetMappedRange : function(buffer, offset, size) { + return null; // void * + }, + wgpuBufferUnmap : function(buffer) { + }, + wgpuDeviceCreateCommandEncoder : function(device, descriptor) { + return null; // WGPUCommandEncoder + }, + wgpuCommandEncoderCopyBufferToTexture : function(commandEncoder, source, destination, copySize) { + }, + wgpuCommandEncoderFinish : function(commandEncoder, descriptor) { + return null; // WGPUCommandBuffer + }, + wgpuQueueSubmit : function(queue, commandCount, commands) { + }, + wgpuBufferRelease : function(buffer) { + }, + wgpuDeviceCreateSampler : function(device, descriptor) { + return null; // WGPUSampler + }, + wgpuSurfaceGetCapabilities : function(surface, adapter, capabilities) { + return null; // WGPUStatus + }, + wgpuSurfaceCapabilitiesFreeMembers : function(surfaceCapabilities) { + }, + wgpuBufferDestroy : function(buffer) { + }, + wgpuSurfaceGetCurrentTexture : function(surface, surfaceTexture) { + }, + wgpuCommandEncoderBeginRenderPass : function(commandEncoder, descriptor) { + return null; // WGPURenderPassEncoder + }, + wgpuRenderPassEncoderSetViewport : function(renderPassEncoder, x, y, width, height, minDepth, maxDepth) { + }, + wgpuRenderPassEncoderSetScissorRect : function(renderPassEncoder, x, y, width, height) { + }, + wgpuRenderPassEncoderEnd : function(renderPassEncoder) { + }, + wgpuRenderPassEncoderRelease : function(renderPassEncoder) { + }, + wgpuCommandBufferRelease : function(commandBuffer) { + }, + wgpuCommandEncoderRelease : function(commandEncoder) { + }, + wgpuSurfacePresent : function(surface) { + return null; // WGPUStatus + }, + wgpuRenderPassEncoderDrawIndexed : function(renderPassEncoder, indexCount, instanceCount, firstIndex, baseVertex, firstInstance) { + }, + wgpuRenderPassEncoderSetPipeline : function(renderPassEncoder, pipeline) { + }, + wgpuRenderPassEncoderSetVertexBuffer : function(renderPassEncoder, slot, buffer, offset, size) { + }, + wgpuRenderPassEncoderSetIndexBuffer : function(renderPassEncoder, buffer, format, offset, size) { + }, + wgpuDeviceCreateBindGroup : function(device, descriptor) { + return null; // WGPUBindGroup + }, + wgpuRenderPassEncoderSetBindGroup : function(renderPassEncoder, groupIndex, group, dynamicOffsetCount, dynamicOffsets) { + }, + wgpuBindGroupRelease : function(bindGroup) { + }, + wgpuRenderPipelineRelease : function(renderPipeline) { + }, + wgpuPipelineLayoutRelease : function(pipelineLayout) { + }, + wgpuDeviceCreatePipelineLayout : function(device, descriptor) { + return null; // WGPUPipelineLayout + }, + wgpuDeviceCreateShaderModule : function(device, descriptor) { + return null; // WGPUShaderModule + }, + wgpuDeviceCreateRenderPipeline : function(device, descriptor) { + return null; // WGPURenderPipeline + }, + wgpuShaderModuleRelease : function(shaderModule) { + }, + wgpuQueueWriteBuffer : function(queue, buffer, bufferOffset, data, size) { + }, + wgpuTextureDestroy : function(texture) { + }, + wgpuTextureRelease : function(texture) { + }, + wgpuTextureViewRelease : function(textureView) { + }, + wgpuCommandEncoderCopyBufferToBuffer : function(commandEncoder, source, sourceOffset, destination, destinationOffset, size) { + }, + wgpuSurfaceConfigure : function(surface, config) { + }, + + js_fprintf : function(format) { + console.log(read_string(format)); + }, + js_fopen : function(filename) { + const req = new XMLHttpRequest(); + req.open("GET", read_string(filename), false); + req.overrideMimeType("text/plain; charset=x-user-defined"); + req.send(); + let str = req.response; + file_buffer_pos = 0; + file_buffer = new ArrayBuffer(str.length); + let buf_view = new Uint8Array(file_buffer); + for (let i = 0; i < str.length; ++i) { + buf_view[i] = str.charCodeAt(i); + } + return 1; + }, + js_ftell : function(stream) { + return file_buffer_pos; + }, + js_fseek : function(stream, offset, origin) { + file_buffer_pos = offset; + if (origin == 1) + file_buffer_pos += file_buffer.byteLength; // SEEK_END + return 0; + }, + js_fread : function(ptr, size, count, stream) { + let buf_view = new Uint8Array(file_buffer); + for (let i = 0; i < count; ++i) { + heapu8[ptr + i] = buf_view[file_buffer_pos++]; + } + return count; + }, + js_time : function() { + return window.performance.now(); + }, + js_pow : function(x) { + return Math.pow(x); + }, + js_floor : function(x) { + return Math.floor(x); + }, + js_sin : function(x) { + return Math.sin(x); + }, + js_cos : function(x) { + return Math.cos(x); + }, + js_tan : function(x) { + return Math.tan(x); + }, + js_log : function(base, exponent) { + return Math.log(base, exponent); + }, + js_exp : function(x) { + return Math.exp(x); + }, + js_sqrt : function(x) { + return Math.sqrt(x); + }, + js_eval : function(str) { + (1, eval)(read_string(str)); } } - ); + }); - mod = result.module; + module = result.module; instance = result.instance; - instance.exports._start(); + instance.exports.wasm_start(); function update() { - instance.exports._update(); + instance.exports.wasm_update(); window.requestAnimationFrame(update); } window.requestAnimationFrame(update); - kanvas.addEventListener('click', (event) => { - if (!audio_thread_started) { - start_audio_thread(); - audio_thread_started = true; - } - }); - - kanvas.addEventListener('contextmenu', (event) => { - event.preventDefault(); - }); - - kanvas.addEventListener('mousedown', (event) => { - instance.exports._mousedown(event.button, event.clientX, event.clientY); - }); - - kanvas.addEventListener('mouseup', (event) => { - instance.exports._mouseup(event.button, event.clientX, event.clientY); - }); - - kanvas.addEventListener('mousemove', (event) => { - instance.exports._mousemove(event.clientX, event.clientY); - }); - - kanvas.addEventListener('wheel', (event) => { - instance.exports._wheel(event.deltaY); - }); - - kanvas.addEventListener('keydown', (event) => { + canvas.addEventListener('contextmenu', (event) => { event.preventDefault(); }); + canvas.addEventListener('mousedown', (event) => { instance.exports.wasm_mousedown(event.button, event.clientX, event.clientY); }); + canvas.addEventListener('mouseup', (event) => { instance.exports.wasm_mouseup(event.button, event.clientX, event.clientY); }); + canvas.addEventListener('mousemove', (event) => { instance.exports.wasm_mousemove(event.clientX, event.clientY); }); + canvas.addEventListener('wheel', (event) => { instance.exports.wasm_wheel(event.deltaY); }); + canvas.addEventListener('keydown', (event) => { if (event.repeat) { event.preventDefault(); return; } - instance.exports._keydown(event.keyCode); + instance.exports.wasm_keydown(event.keyCode); }); - - kanvas.addEventListener('keyup', (event) => { + canvas.addEventListener('keyup', (event) => { if (event.repeat) { event.preventDefault(); return; } - instance.exports._keyup(event.keyCode); + instance.exports.wasm_keyup(event.keyCode); }); } diff --git a/base/sources/backends/wasm_system.c b/base/sources/backends/wasm_system.c index c8a5a23d..a2899990 100644 --- a/base/sources/backends/wasm_system.c +++ b/base/sources/backends/wasm_system.c @@ -77,7 +77,7 @@ void iron_internal_shutdown(void) {} extern int kickstart(int argc, char **argv); -__attribute__((export_name("_start"))) void _start(void) { +__attribute__((export_name("wasm_start"))) void wasm_start(void) { kickstart(0, NULL); } diff --git a/base/sources/backends/webgpu_gpu.c b/base/sources/backends/webgpu_gpu.c index 2f1b1813..356aa193 100644 --- a/base/sources/backends/webgpu_gpu.c +++ b/base/sources/backends/webgpu_gpu.c @@ -7,6 +7,56 @@ #include #include +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateTexture"))) WGPUTexture wgpuDeviceCreateTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuTextureCreateView"))) WGPUTextureView wgpuTextureCreateView(WGPUTexture texture, WGPU_NULLABLE WGPUTextureViewDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuCreateInstance"))) WGPUInstance wgpuCreateInstance(WGPU_NULLABLE WGPUInstanceDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuInstanceRequestAdapter"))) WGPUFuture wgpuInstanceRequestAdapter(WGPUInstance instance, WGPU_NULLABLE WGPURequestAdapterOptions const * options, WGPURequestAdapterCallbackInfo callbackInfo); +__attribute__((import_module("imports"), import_name("wgpuAdapterGetInfo"))) WGPUStatus wgpuAdapterGetInfo(WGPUAdapter adapter, WGPUAdapterInfo * info); +__attribute__((import_module("imports"), import_name("wgpuAdapterInfoFreeMembers"))) void wgpuAdapterInfoFreeMembers(WGPUAdapterInfo adapterInfo); +__attribute__((import_module("imports"), import_name("wgpuAdapterRequestDevice"))) WGPUFuture wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallbackInfo callbackInfo); +__attribute__((import_module("imports"), import_name("wgpuDeviceGetQueue"))) WGPUQueue wgpuDeviceGetQueue(WGPUDevice device); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateBindGroupLayout"))) WGPUBindGroupLayout wgpuDeviceCreateBindGroupLayout(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateBuffer"))) WGPUBuffer wgpuDeviceCreateBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuBufferGetMappedRange"))) void *wgpuBufferGetMappedRange(WGPUBuffer buffer, size_t offset, size_t size); +__attribute__((import_module("imports"), import_name("wgpuBufferUnmap"))) void wgpuBufferUnmap(WGPUBuffer buffer); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateCommandEncoder"))) WGPUCommandEncoder wgpuDeviceCreateCommandEncoder(WGPUDevice device, WGPU_NULLABLE WGPUCommandEncoderDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuCommandEncoderCopyBufferToTexture"))) void wgpuCommandEncoderCopyBufferToTexture(WGPUCommandEncoder commandEncoder, WGPUTexelCopyBufferInfo const * source, WGPUTexelCopyTextureInfo const * destination, WGPUExtent3D const * copySize); +__attribute__((import_module("imports"), import_name("wgpuCommandEncoderFinish"))) WGPUCommandBuffer wgpuCommandEncoderFinish(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUCommandBufferDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuQueueSubmit"))) void wgpuQueueSubmit(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands); +__attribute__((import_module("imports"), import_name("wgpuBufferRelease"))) void wgpuBufferRelease(WGPUBuffer buffer); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateSampler"))) WGPUSampler wgpuDeviceCreateSampler(WGPUDevice device, WGPU_NULLABLE WGPUSamplerDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuSurfaceGetCapabilities"))) WGPUStatus wgpuSurfaceGetCapabilities(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities); +__attribute__((import_module("imports"), import_name("wgpuSurfaceCapabilitiesFreeMembers"))) void wgpuSurfaceCapabilitiesFreeMembers(WGPUSurfaceCapabilities surfaceCapabilities); +__attribute__((import_module("imports"), import_name("wgpuBufferDestroy"))) void wgpuBufferDestroy(WGPUBuffer buffer); +__attribute__((import_module("imports"), import_name("wgpuSurfaceGetCurrentTexture"))) void wgpuSurfaceGetCurrentTexture(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture); +__attribute__((import_module("imports"), import_name("wgpuCommandEncoderBeginRenderPass"))) WGPURenderPassEncoder wgpuCommandEncoderBeginRenderPass(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderSetViewport"))) void wgpuRenderPassEncoderSetViewport(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderSetScissorRect"))) void wgpuRenderPassEncoderSetScissorRect(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderEnd"))) void wgpuRenderPassEncoderEnd(WGPURenderPassEncoder renderPassEncoder); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderRelease"))) void wgpuRenderPassEncoderRelease(WGPURenderPassEncoder renderPassEncoder); +__attribute__((import_module("imports"), import_name("wgpuCommandBufferRelease"))) void wgpuCommandBufferRelease(WGPUCommandBuffer commandBuffer); +__attribute__((import_module("imports"), import_name("wgpuCommandEncoderRelease"))) void wgpuCommandEncoderRelease(WGPUCommandEncoder commandEncoder); +__attribute__((import_module("imports"), import_name("wgpuSurfacePresent"))) WGPUStatus wgpuSurfacePresent(WGPUSurface surface); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderDrawIndexed"))) void wgpuRenderPassEncoderDrawIndexed(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderSetPipeline"))) void wgpuRenderPassEncoderSetPipeline(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderSetVertexBuffer"))) void wgpuRenderPassEncoderSetVertexBuffer(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderSetIndexBuffer"))) void wgpuRenderPassEncoderSetIndexBuffer(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateBindGroup"))) WGPUBindGroup wgpuDeviceCreateBindGroup(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuRenderPassEncoderSetBindGroup"))) void wgpuRenderPassEncoderSetBindGroup(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets); +__attribute__((import_module("imports"), import_name("wgpuBindGroupRelease"))) void wgpuBindGroupRelease(WGPUBindGroup bindGroup); +__attribute__((import_module("imports"), import_name("wgpuRenderPipelineRelease"))) void wgpuRenderPipelineRelease(WGPURenderPipeline renderPipeline); +__attribute__((import_module("imports"), import_name("wgpuPipelineLayoutRelease"))) void wgpuPipelineLayoutRelease(WGPUPipelineLayout pipelineLayout); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreatePipelineLayout"))) WGPUPipelineLayout wgpuDeviceCreatePipelineLayout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateShaderModule"))) WGPUShaderModule wgpuDeviceCreateShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuDeviceCreateRenderPipeline"))) WGPURenderPipeline wgpuDeviceCreateRenderPipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor); +__attribute__((import_module("imports"), import_name("wgpuShaderModuleRelease"))) void wgpuShaderModuleRelease(WGPUShaderModule shaderModule); +__attribute__((import_module("imports"), import_name("wgpuQueueWriteBuffer"))) void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size); +__attribute__((import_module("imports"), import_name("wgpuTextureDestroy"))) void wgpuTextureDestroy(WGPUTexture texture); +__attribute__((import_module("imports"), import_name("wgpuTextureRelease"))) void wgpuTextureRelease(WGPUTexture texture); +__attribute__((import_module("imports"), import_name("wgpuTextureViewRelease"))) void wgpuTextureViewRelease(WGPUTextureView textureView); +__attribute__((import_module("imports"), import_name("wgpuCommandEncoderCopyBufferToBuffer"))) void wgpuCommandEncoderCopyBufferToBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size); +__attribute__((import_module("imports"), import_name("wgpuSurfaceConfigure"))) void wgpuSurfaceConfigure(WGPUSurface surface, WGPUSurfaceConfiguration const * config); + bool gpu_transpose_mat = true; extern int constant_buffer_index; static gpu_buffer_t *current_vb; diff --git a/base/tools/make.js b/base/tools/make.js index 6087f704..d9fdd684 100644 --- a/base/tools/make.js +++ b/base/tools/make.js @@ -945,7 +945,7 @@ class WasmExporter extends Exporter { let compilerFlags = ""; this.make = new MakeExporter(compiler, compiler, compilerFlags, compilerFlags, - '--target=wasm32 -nostdlib -matomics -mbulk-memory "-Wl,--import-memory,--shared-memory" "-Wl,--allow-undefined"', '.wasm'); + '--target=wasm32 -nostdlib -matomics -mbulk-memory "-Wl,--import-memory,--shared-memory" "-Wl,--allow-undefined,--no-entry"', '.wasm'); } export_solution(project) {