Skip to content

Commit 108b8fe

Browse files
committed
Add vendor:wgpu
1 parent 68781f8 commit 108b8fe

23 files changed

+5431
-19
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ bin/
303303
# - Linux/MacOS
304304
odin
305305
!odin/
306-
odin.dSYM
306+
**/*.dSYM
307307
*.bin
308308
demo.bin
309309
libLLVM*.so*

core/sys/darwin/Foundation/NSWindow.odin

+4
Original file line numberDiff line numberDiff line change
@@ -712,3 +712,7 @@ Window_setDelegate :: proc "c" (self: ^Window, delegate: ^WindowDelegate) {
712712
Window_backingScaleFactor :: proc "c" (self: ^Window) -> Float {
713713
return msgSend(Float, self, "backingScaleFactor")
714714
}
715+
@(objc_type=Window, objc_name="setWantsLayer")
716+
Window_setWantsLayer :: proc "c" (self: ^Window, ok: BOOL) {
717+
msgSend(nil, self, "setWantsLayer:", ok)
718+
}

vendor/glfw/native_linux.odin

+15-11
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
package glfw
44

5-
// TODO: Native Linux
6-
// Display* glfwGetX11Display(void);
7-
// RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
8-
// RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
9-
// Window glfwGetX11Window(GLFWwindow* window);
10-
// void glfwSetX11SelectionString(const char* string);
11-
// const char* glfwGetX11SelectionString(void);
12-
13-
// struct wl_display* glfwGetWaylandDisplay(void);
14-
// struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
15-
// struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
5+
import "vendor:x11/xlib"
6+
7+
@(default_calling_convention="c", link_prefix="glfw")
8+
foreign {
9+
GetX11Display :: proc() -> ^xlib.Display ---
10+
GetX11Window :: proc(window: WindowHandle) -> xlib.Window ---
11+
GetX11Adapter :: proc(monitor: MonitorHandle) -> xlib.RRCrtc ---
12+
GetX11Monitor :: proc(monitor: MonitorHandle) -> xlib.RROutput ---
13+
SetX11SelectionString :: proc(string: cstring) ---
14+
GetX11SelectionString :: proc() -> cstring ---
15+
16+
GetWaylandDisplay :: proc() -> rawptr /* struct wl_display* */ ---
17+
GetWaylandWindow :: proc(window: WindowHandle) -> rawptr /* struct wl_surface* */ ---
18+
GetWaylandMonitor :: proc(monitor: MonitorHandle) -> rawptr /* struct wl_output* */ ---
19+
}

vendor/wasm/js/runtime.js

+37-7
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ class WasmMemoryInterface {
9696
};
9797
loadPtr(addr) { return this.loadU32(addr); }
9898

99+
loadB32(addr) {
100+
return this.loadU32(addr) != 0;
101+
}
102+
99103
loadBytes(ptr, len) {
100104
return new Uint8Array(this.memory.buffer, ptr, Number(len));
101105
}
@@ -104,6 +108,16 @@ class WasmMemoryInterface {
104108
const bytes = this.loadBytes(ptr, Number(len));
105109
return new TextDecoder().decode(bytes);
106110
}
111+
112+
loadCstring(ptr) {
113+
const start = this.loadPtr(ptr);
114+
if (start == 0) {
115+
return null;
116+
}
117+
let len = 0;
118+
for (; this.mem.getUint8(start+len) != 0; len += 1) {}
119+
return this.loadString(start, len);
120+
}
107121

108122
storeU8(addr, value) { this.mem.setUint8 (addr, value); }
109123
storeI8(addr, value) { this.mem.setInt8 (addr, value); }
@@ -1245,7 +1259,7 @@ class WebGLInterface {
12451259
};
12461260

12471261

1248-
function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
1262+
function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory) {
12491263
const MAX_INFO_CONSOLE_LINES = 512;
12501264
let infoConsoleLines = new Array();
12511265
let currentLine = {};
@@ -1366,8 +1380,15 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
13661380
let event_temp_data = {};
13671381

13681382
let webglContext = new WebGLInterface(wasmMemoryInterface);
1383+
1384+
const env = {};
1385+
1386+
if (memory) {
1387+
env.memory = memory;
1388+
}
1389+
13691390
return {
1370-
"env": {},
1391+
env,
13711392
"odin_env": {
13721393
write: (fd, ptr, len) => {
13731394
const str = wasmMemoryInterface.loadString(ptr, len);
@@ -1720,13 +1741,16 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
17201741
* @param {string} wasmPath - Path to the WASM module to run
17211742
* @param {?HTMLPreElement} consoleElement - Optional console/pre element to append output to, in addition to the console
17221743
* @param {any} extraForeignImports - Imports, in addition to the default runtime to provide the module
1744+
* @param {?WasmMemoryInterface} wasmMemoryInterface - Optional memory to use instead of the defaults
17231745
* @param {?int} intSize - Size (in bytes) of the integer type, should be 4 on `js_wasm32` and 8 on `js_wasm64p32`
17241746
*/
1725-
async function runWasm(wasmPath, consoleElement, extraForeignImports, intSize = 4) {
1726-
const wasmMemoryInterface = new WasmMemoryInterface();
1747+
async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemoryInterface, intSize = 4) {
1748+
if (!wasmMemoryInterface) {
1749+
wasmMemoryInterface = new WasmMemoryInterface();
1750+
}
17271751
wasmMemoryInterface.setIntSize(intSize);
17281752

1729-
let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement);
1753+
let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement, wasmMemoryInterface.memory);
17301754
let exports = {};
17311755

17321756
if (extraForeignImports !== undefined) {
@@ -1741,11 +1765,17 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, intSize =
17411765
const wasm = await WebAssembly.instantiate(file, imports);
17421766
exports = wasm.instance.exports;
17431767
wasmMemoryInterface.setExports(exports);
1744-
wasmMemoryInterface.setMemory(exports.memory);
1768+
1769+
if (exports.memory) {
1770+
if (wasmMemoryInterface.memory) {
1771+
console.warn("WASM module exports memory, but `runWasm` was given an interface with existing memory too");
1772+
}
1773+
wasmMemoryInterface.setMemory(exports.memory);
1774+
}
17451775

17461776
exports._start();
17471777

1748-
// Define a `@export step :: proc(dt: f32) -> (continue: bool) {`
1778+
// Define a `@export step :: proc(dt: f32) -> (keep_going: bool) {`
17491779
// in your app and it will get called every frame.
17501780
// return `false` to stop the execution of the module.
17511781
if (exports.step) {

vendor/wgpu/.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
lib/*
2+
!lib/.gitkeep
3+
example/web/triangle.wasm
4+
example/web/wgpu.js
5+
example/web/runtime.js
6+
example/example
7+
example/example.exe
8+
example/triangle
9+
example/triangle.exe

vendor/wgpu/README.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# WGPU
2+
3+
A cross-platform (and WASM) GPU API.
4+
5+
WASM support is achieved by providing wrappers around the browser native WebGPU API
6+
that are called instead of the [wgpu-native](https://github.com/gfx-rs/wgpu-native) library,
7+
the wgpu-native library provides support for all other targets.
8+
9+
Have a look at the `example/` directory for the rendering of a basic triangle.
10+
11+
## Getting the wgpu-native libraries
12+
13+
For native support (not the browser), some libraries are required. Fortunately this is
14+
extremely easy, just download them from the [releases on GitHub](https://github.com/gfx-rs/wgpu-native/releases/tag/v0.19.4.1),
15+
the bindings are for v0.19.4.1 at the moment.
16+
17+
These are expected in the `lib` folder under the same name as they are released (just unzipped).
18+
By default it will look for a static release version (`wgpu-OS-ARCH-release.a|lib`),
19+
you can set `-define:WGPU_DEBUG=true` for it to look for a debug version,
20+
and use `-define:WGPU_SHARED=true` to look for the shared libraries.
21+
22+
## WASM
23+
24+
For WASM, the module has to be built with a function table to enable callbacks.
25+
You can do so using `-extra-linker-flags:"--export-table"`.
26+
27+
Being able to allocate is also required (for some auxiliary APIs but also for mapping/unmapping buffers).
28+
29+
You can set the context that is used for allocations by setting the global variable `wpgu.g_context`.
30+
It will default to the `runtime.default_context`.
31+
32+
Again, have a look at the `example/` and how it is set up, doing the `--import-memory` and the likes
33+
is not strictly necessary but allows your app more memory than the minimal default.
34+
35+
The bindings work on both `-target:js_wasm32` and `-target:js_wasm64p32`.
36+
37+
## GLFW Glue
38+
39+
There is an inner package `glfwglue` that can be used to glue together WGPU and GLFW.
40+
It exports one procedure `GetSurface(wgpu.Instance, glfw.WindowHandle) -> glfw.Surface`.
41+
The procedure will call the needed target specific procedures and return a surface configured
42+
for the given window.
43+
44+
To support Wayland on Linux, you need to have GLFW compiled to support it, and use
45+
`-define:WGPU_GFLW_GLUE_SUPPORT_WAYLAND=true` to enable the package to check for Wayland.
46+
47+
Do note that wgpu does not require GLFW, you can use native windows or another windowing library too.
48+
For that you can take inspiration from `glfwglue` on glueing them together.

vendor/wgpu/example/Makefile

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FILES := $(wildcard *)
2+
3+
# NOTE: changing this requires changing the same values in the `web/index.html`.
4+
INITIAL_MEMORY_PAGES := 2000
5+
MAX_MEMORY_PAGES := 65536
6+
7+
PAGE_SIZE := 65536
8+
INITIAL_MEMORY_BYTES := $(shell expr $(INITIAL_MEMORY_PAGES) \* $(PAGE_SIZE))
9+
MAX_MEMORY_BYTES := $(shell expr $(MAX_MEMORY_PAGES) \* $(PAGE_SIZE))
10+
11+
web/triangle.wasm: $(FILES) ../wgpu.js ../../wasm/js/runtime.js
12+
odin build . \
13+
-target:js_wasm32 -out:web/triangle.wasm -o:size \
14+
-extra-linker-flags:"--export-table --import-memory --initial-memory=$(INITIAL_MEMORY_BYTES) --max-memory=$(MAX_MEMORY_BYTES)"
15+
16+
cp ../wgpu.js web/wgpu.js
17+
cp ../../wasm/js/runtime.js web/runtime.js

vendor/wgpu/example/build.bat

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
REM NOTE: changing this requires changing the same values in the `web/index.html`.
2+
set INITIAL_MEMORY_PAGES=2000
3+
set MAX_MEMORY_PAGES=65536
4+
5+
set PAGE_SIZE=65536
6+
set /a INITIAL_MEMORY_BYTES=%INITIAL_MEMORY_PAGES% * %PAGE_SIZE%
7+
set /a MAX_MEMORY_BYTES=%MAX_MEMORY_PAGES% * %PAGE_SIZE%
8+
9+
call odin.exe build . -target:js_wasm32 -out:web/triangle.wasm -o:size -extra-linker-flags:"--export-table --import-memory --initial-memory=%INITIAL_MEMORY_BYTES% --max-memory=%MAX_MEMORY_BYTES%"
10+
11+
copy "..\wgpu.js" "web\wgpu.js"
12+
copy "..\..\wasm\js\runtime.js" "web\runtime.js"

0 commit comments

Comments
 (0)