mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
+1
-1
@@ -303,7 +303,7 @@ bin/
|
|||||||
# - Linux/MacOS
|
# - Linux/MacOS
|
||||||
odin
|
odin
|
||||||
!odin/
|
!odin/
|
||||||
odin.dSYM
|
**/*.dSYM
|
||||||
*.bin
|
*.bin
|
||||||
demo.bin
|
demo.bin
|
||||||
libLLVM*.so*
|
libLLVM*.so*
|
||||||
|
|||||||
@@ -712,3 +712,7 @@ Window_setDelegate :: proc "c" (self: ^Window, delegate: ^WindowDelegate) {
|
|||||||
Window_backingScaleFactor :: proc "c" (self: ^Window) -> Float {
|
Window_backingScaleFactor :: proc "c" (self: ^Window) -> Float {
|
||||||
return msgSend(Float, self, "backingScaleFactor")
|
return msgSend(Float, self, "backingScaleFactor")
|
||||||
}
|
}
|
||||||
|
@(objc_type=Window, objc_name="setWantsLayer")
|
||||||
|
Window_setWantsLayer :: proc "c" (self: ^Window, ok: BOOL) {
|
||||||
|
msgSend(nil, self, "setWantsLayer:", ok)
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+14
-10
@@ -2,14 +2,18 @@
|
|||||||
|
|
||||||
package glfw
|
package glfw
|
||||||
|
|
||||||
// TODO: Native Linux
|
import "vendor:x11/xlib"
|
||||||
// Display* glfwGetX11Display(void);
|
|
||||||
// RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
|
||||||
// RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
|
||||||
// Window glfwGetX11Window(GLFWwindow* window);
|
|
||||||
// void glfwSetX11SelectionString(const char* string);
|
|
||||||
// const char* glfwGetX11SelectionString(void);
|
|
||||||
|
|
||||||
// struct wl_display* glfwGetWaylandDisplay(void);
|
@(default_calling_convention="c", link_prefix="glfw")
|
||||||
// struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
foreign {
|
||||||
// struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
GetX11Display :: proc() -> ^xlib.Display ---
|
||||||
|
GetX11Window :: proc(window: WindowHandle) -> xlib.Window ---
|
||||||
|
GetX11Adapter :: proc(monitor: MonitorHandle) -> xlib.RRCrtc ---
|
||||||
|
GetX11Monitor :: proc(monitor: MonitorHandle) -> xlib.RROutput ---
|
||||||
|
SetX11SelectionString :: proc(string: cstring) ---
|
||||||
|
GetX11SelectionString :: proc() -> cstring ---
|
||||||
|
|
||||||
|
GetWaylandDisplay :: proc() -> rawptr /* struct wl_display* */ ---
|
||||||
|
GetWaylandWindow :: proc(window: WindowHandle) -> rawptr /* struct wl_surface* */ ---
|
||||||
|
GetWaylandMonitor :: proc(monitor: MonitorHandle) -> rawptr /* struct wl_output* */ ---
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+37
-7
@@ -96,6 +96,10 @@ class WasmMemoryInterface {
|
|||||||
};
|
};
|
||||||
loadPtr(addr) { return this.loadU32(addr); }
|
loadPtr(addr) { return this.loadU32(addr); }
|
||||||
|
|
||||||
|
loadB32(addr) {
|
||||||
|
return this.loadU32(addr) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
loadBytes(ptr, len) {
|
loadBytes(ptr, len) {
|
||||||
return new Uint8Array(this.memory.buffer, ptr, Number(len));
|
return new Uint8Array(this.memory.buffer, ptr, Number(len));
|
||||||
}
|
}
|
||||||
@@ -105,6 +109,16 @@ class WasmMemoryInterface {
|
|||||||
return new TextDecoder().decode(bytes);
|
return new TextDecoder().decode(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadCstring(ptr) {
|
||||||
|
const start = this.loadPtr(ptr);
|
||||||
|
if (start == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let len = 0;
|
||||||
|
for (; this.mem.getUint8(start+len) != 0; len += 1) {}
|
||||||
|
return this.loadString(start, len);
|
||||||
|
}
|
||||||
|
|
||||||
storeU8(addr, value) { this.mem.setUint8 (addr, value); }
|
storeU8(addr, value) { this.mem.setUint8 (addr, value); }
|
||||||
storeI8(addr, value) { this.mem.setInt8 (addr, value); }
|
storeI8(addr, value) { this.mem.setInt8 (addr, value); }
|
||||||
storeU16(addr, value) { this.mem.setUint16 (addr, value, true); }
|
storeU16(addr, value) { this.mem.setUint16 (addr, value, true); }
|
||||||
@@ -1245,7 +1259,7 @@ class WebGLInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
|
function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory) {
|
||||||
const MAX_INFO_CONSOLE_LINES = 512;
|
const MAX_INFO_CONSOLE_LINES = 512;
|
||||||
let infoConsoleLines = new Array();
|
let infoConsoleLines = new Array();
|
||||||
let currentLine = {};
|
let currentLine = {};
|
||||||
@@ -1366,8 +1380,15 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
|
|||||||
let event_temp_data = {};
|
let event_temp_data = {};
|
||||||
|
|
||||||
let webglContext = new WebGLInterface(wasmMemoryInterface);
|
let webglContext = new WebGLInterface(wasmMemoryInterface);
|
||||||
|
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
if (memory) {
|
||||||
|
env.memory = memory;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"env": {},
|
env,
|
||||||
"odin_env": {
|
"odin_env": {
|
||||||
write: (fd, ptr, len) => {
|
write: (fd, ptr, len) => {
|
||||||
const str = wasmMemoryInterface.loadString(ptr, len);
|
const str = wasmMemoryInterface.loadString(ptr, len);
|
||||||
@@ -1720,13 +1741,16 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) {
|
|||||||
* @param {string} wasmPath - Path to the WASM module to run
|
* @param {string} wasmPath - Path to the WASM module to run
|
||||||
* @param {?HTMLPreElement} consoleElement - Optional console/pre element to append output to, in addition to the console
|
* @param {?HTMLPreElement} consoleElement - Optional console/pre element to append output to, in addition to the console
|
||||||
* @param {any} extraForeignImports - Imports, in addition to the default runtime to provide the module
|
* @param {any} extraForeignImports - Imports, in addition to the default runtime to provide the module
|
||||||
|
* @param {?WasmMemoryInterface} wasmMemoryInterface - Optional memory to use instead of the defaults
|
||||||
* @param {?int} intSize - Size (in bytes) of the integer type, should be 4 on `js_wasm32` and 8 on `js_wasm64p32`
|
* @param {?int} intSize - Size (in bytes) of the integer type, should be 4 on `js_wasm32` and 8 on `js_wasm64p32`
|
||||||
*/
|
*/
|
||||||
async function runWasm(wasmPath, consoleElement, extraForeignImports, intSize = 4) {
|
async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemoryInterface, intSize = 4) {
|
||||||
const wasmMemoryInterface = new WasmMemoryInterface();
|
if (!wasmMemoryInterface) {
|
||||||
|
wasmMemoryInterface = new WasmMemoryInterface();
|
||||||
|
}
|
||||||
wasmMemoryInterface.setIntSize(intSize);
|
wasmMemoryInterface.setIntSize(intSize);
|
||||||
|
|
||||||
let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement);
|
let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement, wasmMemoryInterface.memory);
|
||||||
let exports = {};
|
let exports = {};
|
||||||
|
|
||||||
if (extraForeignImports !== undefined) {
|
if (extraForeignImports !== undefined) {
|
||||||
@@ -1741,11 +1765,17 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, intSize =
|
|||||||
const wasm = await WebAssembly.instantiate(file, imports);
|
const wasm = await WebAssembly.instantiate(file, imports);
|
||||||
exports = wasm.instance.exports;
|
exports = wasm.instance.exports;
|
||||||
wasmMemoryInterface.setExports(exports);
|
wasmMemoryInterface.setExports(exports);
|
||||||
wasmMemoryInterface.setMemory(exports.memory);
|
|
||||||
|
if (exports.memory) {
|
||||||
|
if (wasmMemoryInterface.memory) {
|
||||||
|
console.warn("WASM module exports memory, but `runWasm` was given an interface with existing memory too");
|
||||||
|
}
|
||||||
|
wasmMemoryInterface.setMemory(exports.memory);
|
||||||
|
}
|
||||||
|
|
||||||
exports._start();
|
exports._start();
|
||||||
|
|
||||||
// Define a `@export step :: proc(dt: f32) -> (continue: bool) {`
|
// Define a `@export step :: proc(dt: f32) -> (keep_going: bool) {`
|
||||||
// in your app and it will get called every frame.
|
// in your app and it will get called every frame.
|
||||||
// return `false` to stop the execution of the module.
|
// return `false` to stop the execution of the module.
|
||||||
if (exports.step) {
|
if (exports.step) {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
lib/*
|
||||||
|
!lib/.gitkeep
|
||||||
|
example/web/triangle.wasm
|
||||||
|
example/web/wgpu.js
|
||||||
|
example/web/runtime.js
|
||||||
|
example/example
|
||||||
|
example/example.exe
|
||||||
|
example/triangle
|
||||||
|
example/triangle.exe
|
||||||
Vendored
+48
@@ -0,0 +1,48 @@
|
|||||||
|
# WGPU
|
||||||
|
|
||||||
|
A cross-platform (and WASM) GPU API.
|
||||||
|
|
||||||
|
WASM support is achieved by providing wrappers around the browser native WebGPU API
|
||||||
|
that are called instead of the [wgpu-native](https://github.com/gfx-rs/wgpu-native) library,
|
||||||
|
the wgpu-native library provides support for all other targets.
|
||||||
|
|
||||||
|
Have a look at the `example/` directory for the rendering of a basic triangle.
|
||||||
|
|
||||||
|
## Getting the wgpu-native libraries
|
||||||
|
|
||||||
|
For native support (not the browser), some libraries are required. Fortunately this is
|
||||||
|
extremely easy, just download them from the [releases on GitHub](https://github.com/gfx-rs/wgpu-native/releases/tag/v0.19.4.1),
|
||||||
|
the bindings are for v0.19.4.1 at the moment.
|
||||||
|
|
||||||
|
These are expected in the `lib` folder under the same name as they are released (just unzipped).
|
||||||
|
By default it will look for a static release version (`wgpu-OS-ARCH-release.a|lib`),
|
||||||
|
you can set `-define:WGPU_DEBUG=true` for it to look for a debug version,
|
||||||
|
and use `-define:WGPU_SHARED=true` to look for the shared libraries.
|
||||||
|
|
||||||
|
## WASM
|
||||||
|
|
||||||
|
For WASM, the module has to be built with a function table to enable callbacks.
|
||||||
|
You can do so using `-extra-linker-flags:"--export-table"`.
|
||||||
|
|
||||||
|
Being able to allocate is also required (for some auxiliary APIs but also for mapping/unmapping buffers).
|
||||||
|
|
||||||
|
You can set the context that is used for allocations by setting the global variable `wpgu.g_context`.
|
||||||
|
It will default to the `runtime.default_context`.
|
||||||
|
|
||||||
|
Again, have a look at the `example/` and how it is set up, doing the `--import-memory` and the likes
|
||||||
|
is not strictly necessary but allows your app more memory than the minimal default.
|
||||||
|
|
||||||
|
The bindings work on both `-target:js_wasm32` and `-target:js_wasm64p32`.
|
||||||
|
|
||||||
|
## GLFW Glue
|
||||||
|
|
||||||
|
There is an inner package `glfwglue` that can be used to glue together WGPU and GLFW.
|
||||||
|
It exports one procedure `GetSurface(wgpu.Instance, glfw.WindowHandle) -> glfw.Surface`.
|
||||||
|
The procedure will call the needed target specific procedures and return a surface configured
|
||||||
|
for the given window.
|
||||||
|
|
||||||
|
To support Wayland on Linux, you need to have GLFW compiled to support it, and use
|
||||||
|
`-define:WGPU_GFLW_GLUE_SUPPORT_WAYLAND=true` to enable the package to check for Wayland.
|
||||||
|
|
||||||
|
Do note that wgpu does not require GLFW, you can use native windows or another windowing library too.
|
||||||
|
For that you can take inspiration from `glfwglue` on glueing them together.
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
FILES := $(wildcard *)
|
||||||
|
|
||||||
|
# NOTE: changing this requires changing the same values in the `web/index.html`.
|
||||||
|
INITIAL_MEMORY_PAGES := 2000
|
||||||
|
MAX_MEMORY_PAGES := 65536
|
||||||
|
|
||||||
|
PAGE_SIZE := 65536
|
||||||
|
INITIAL_MEMORY_BYTES := $(shell expr $(INITIAL_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||||
|
MAX_MEMORY_BYTES := $(shell expr $(MAX_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||||
|
|
||||||
|
web/triangle.wasm: $(FILES) ../wgpu.js ../../wasm/js/runtime.js
|
||||||
|
odin 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)"
|
||||||
|
|
||||||
|
cp ../wgpu.js web/wgpu.js
|
||||||
|
cp ../../wasm/js/runtime.js web/runtime.js
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
REM NOTE: changing this requires changing the same values in the `web/index.html`.
|
||||||
|
set INITIAL_MEMORY_PAGES=2000
|
||||||
|
set MAX_MEMORY_PAGES=65536
|
||||||
|
|
||||||
|
set PAGE_SIZE=65536
|
||||||
|
set /a INITIAL_MEMORY_BYTES=%INITIAL_MEMORY_PAGES% * %PAGE_SIZE%
|
||||||
|
set /a MAX_MEMORY_BYTES=%MAX_MEMORY_PAGES% * %PAGE_SIZE%
|
||||||
|
|
||||||
|
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%"
|
||||||
|
|
||||||
|
copy "..\wgpu.js" "web\wgpu.js"
|
||||||
|
copy "..\..\wasm\js\runtime.js" "web\runtime.js"
|
||||||
Vendored
+187
@@ -0,0 +1,187 @@
|
|||||||
|
package vendor_wgpu_example_triangle
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
import "vendor:wgpu"
|
||||||
|
|
||||||
|
State :: struct {
|
||||||
|
ctx: runtime.Context,
|
||||||
|
os: OS,
|
||||||
|
|
||||||
|
instance: wgpu.Instance,
|
||||||
|
surface: wgpu.Surface,
|
||||||
|
adapter: wgpu.Adapter,
|
||||||
|
device: wgpu.Device,
|
||||||
|
config: wgpu.SurfaceConfiguration,
|
||||||
|
queue: wgpu.Queue,
|
||||||
|
module: wgpu.ShaderModule,
|
||||||
|
pipeline_layout: wgpu.PipelineLayout,
|
||||||
|
pipeline: wgpu.RenderPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
|
state: State
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
state.ctx = context
|
||||||
|
|
||||||
|
os_init(&state.os)
|
||||||
|
|
||||||
|
state.instance = wgpu.CreateInstance(nil)
|
||||||
|
if state.instance == nil {
|
||||||
|
panic("WebGPU is not supported")
|
||||||
|
}
|
||||||
|
state.surface = os_get_surface(&state.os, state.instance)
|
||||||
|
|
||||||
|
wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, on_adapter, nil)
|
||||||
|
|
||||||
|
on_adapter :: proc "c" (status: wgpu.RequestAdapterStatus, adapter: wgpu.Adapter, message: cstring, userdata: rawptr) {
|
||||||
|
context = state.ctx
|
||||||
|
if status != .Success || adapter == nil {
|
||||||
|
fmt.panicf("request adapter failure: [%v] %s", status, message)
|
||||||
|
}
|
||||||
|
state.adapter = adapter
|
||||||
|
wgpu.AdapterRequestDevice(adapter, nil, on_device)
|
||||||
|
}
|
||||||
|
|
||||||
|
on_device :: proc "c" (status: wgpu.RequestDeviceStatus, device: wgpu.Device, message: cstring, userdata: rawptr) {
|
||||||
|
context = state.ctx
|
||||||
|
if status != .Success || device == nil {
|
||||||
|
fmt.panicf("request device failure: [%v] %s", status, message)
|
||||||
|
}
|
||||||
|
state.device = device
|
||||||
|
|
||||||
|
width, height := os_get_render_bounds(&state.os)
|
||||||
|
|
||||||
|
state.config = wgpu.SurfaceConfiguration {
|
||||||
|
device = state.device,
|
||||||
|
usage = { .RenderAttachment },
|
||||||
|
format = .BGRA8Unorm,
|
||||||
|
width = width,
|
||||||
|
height = height,
|
||||||
|
presentMode = .Fifo,
|
||||||
|
alphaMode = .Opaque,
|
||||||
|
}
|
||||||
|
wgpu.SurfaceConfigure(state.surface, &state.config)
|
||||||
|
|
||||||
|
state.queue = wgpu.DeviceGetQueue(state.device)
|
||||||
|
|
||||||
|
shader :: `
|
||||||
|
@vertex
|
||||||
|
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
|
||||||
|
let x = f32(i32(in_vertex_index) - 1);
|
||||||
|
let y = f32(i32(in_vertex_index & 1u) * 2 - 1);
|
||||||
|
return vec4<f32>(x, y, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fs_main() -> @location(0) vec4<f32> {
|
||||||
|
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}`
|
||||||
|
|
||||||
|
state.module = wgpu.DeviceCreateShaderModule(state.device, &{
|
||||||
|
nextInChain = &wgpu.ShaderModuleWGSLDescriptor{
|
||||||
|
sType = .ShaderModuleWGSLDescriptor,
|
||||||
|
code = shader,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
state.pipeline_layout = wgpu.DeviceCreatePipelineLayout(state.device, &{})
|
||||||
|
state.pipeline = wgpu.DeviceCreateRenderPipeline(state.device, &{
|
||||||
|
layout = state.pipeline_layout,
|
||||||
|
vertex = {
|
||||||
|
module = state.module,
|
||||||
|
entryPoint = "vs_main",
|
||||||
|
},
|
||||||
|
fragment = &{
|
||||||
|
module = state.module,
|
||||||
|
entryPoint = "fs_main",
|
||||||
|
targetCount = 1,
|
||||||
|
targets = &wgpu.ColorTargetState{
|
||||||
|
format = .BGRA8Unorm,
|
||||||
|
writeMask = wgpu.ColorWriteMaskFlags_All,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
primitive = {
|
||||||
|
topology = .TriangleList,
|
||||||
|
|
||||||
|
},
|
||||||
|
multisample = {
|
||||||
|
count = 1,
|
||||||
|
mask = 0xFFFFFFFF,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
os_run(&state.os)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resize :: proc "c" () {
|
||||||
|
context = state.ctx
|
||||||
|
|
||||||
|
state.config.width, state.config.height = os_get_render_bounds(&state.os)
|
||||||
|
wgpu.SurfaceConfigure(state.surface, &state.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
frame :: proc "c" (dt: f32) {
|
||||||
|
context = state.ctx
|
||||||
|
|
||||||
|
surface_texture := wgpu.SurfaceGetCurrentTexture(state.surface)
|
||||||
|
switch surface_texture.status {
|
||||||
|
case .Success:
|
||||||
|
// All good, could check for `surface_texture.suboptimal` here.
|
||||||
|
case .Timeout, .Outdated, .Lost:
|
||||||
|
// Skip this frame, and re-configure surface.
|
||||||
|
if surface_texture.texture != nil {
|
||||||
|
wgpu.TextureRelease(surface_texture.texture)
|
||||||
|
}
|
||||||
|
resize()
|
||||||
|
return
|
||||||
|
case .OutOfMemory, .DeviceLost:
|
||||||
|
// Fatal error
|
||||||
|
fmt.panicf("[triangle] get_current_texture status=%v", surface_texture.status)
|
||||||
|
}
|
||||||
|
defer wgpu.TextureRelease(surface_texture.texture)
|
||||||
|
|
||||||
|
frame := wgpu.TextureCreateView(surface_texture.texture, nil)
|
||||||
|
defer wgpu.TextureViewRelease(frame)
|
||||||
|
|
||||||
|
command_encoder := wgpu.DeviceCreateCommandEncoder(state.device, nil)
|
||||||
|
defer wgpu.CommandEncoderRelease(command_encoder)
|
||||||
|
|
||||||
|
render_pass_encoder := wgpu.CommandEncoderBeginRenderPass(
|
||||||
|
command_encoder, &{
|
||||||
|
colorAttachmentCount = 1,
|
||||||
|
colorAttachments = &wgpu.RenderPassColorAttachment{
|
||||||
|
view = frame,
|
||||||
|
loadOp = .Clear,
|
||||||
|
storeOp = .Store,
|
||||||
|
clearValue = { r = 0, g = 1, b = 0, a = 1 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer wgpu.RenderPassEncoderRelease(render_pass_encoder)
|
||||||
|
|
||||||
|
wgpu.RenderPassEncoderSetPipeline(render_pass_encoder, state.pipeline)
|
||||||
|
wgpu.RenderPassEncoderDraw(render_pass_encoder, vertexCount=3, instanceCount=1, firstVertex=0, firstInstance=0)
|
||||||
|
wgpu.RenderPassEncoderEnd(render_pass_encoder)
|
||||||
|
|
||||||
|
command_buffer := wgpu.CommandEncoderFinish(command_encoder, nil)
|
||||||
|
defer wgpu.CommandBufferRelease(command_buffer)
|
||||||
|
|
||||||
|
wgpu.QueueSubmit(state.queue, { command_buffer })
|
||||||
|
wgpu.SurfacePresent(state.surface)
|
||||||
|
}
|
||||||
|
|
||||||
|
finish :: proc() {
|
||||||
|
wgpu.RenderPipelineRelease(state.pipeline)
|
||||||
|
wgpu.PipelineLayoutRelease(state.pipeline_layout)
|
||||||
|
wgpu.ShaderModuleRelease(state.module)
|
||||||
|
wgpu.QueueRelease(state.queue)
|
||||||
|
wgpu.DeviceRelease(state.device)
|
||||||
|
wgpu.AdapterRelease(state.adapter)
|
||||||
|
wgpu.SurfaceRelease(state.surface)
|
||||||
|
wgpu.InstanceRelease(state.instance)
|
||||||
|
}
|
||||||
Vendored
+55
@@ -0,0 +1,55 @@
|
|||||||
|
//+build !js
|
||||||
|
package vendor_wgpu_example_triangle
|
||||||
|
|
||||||
|
import "core:time"
|
||||||
|
|
||||||
|
import "vendor:glfw"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
import "vendor:wgpu/glfwglue"
|
||||||
|
|
||||||
|
OS :: struct {
|
||||||
|
window: glfw.WindowHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
os_init :: proc(os: ^OS) {
|
||||||
|
if !glfw.Init() {
|
||||||
|
panic("[glfw] init failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
glfw.WindowHint(glfw.CLIENT_API, glfw.NO_API)
|
||||||
|
os.window = glfw.CreateWindow(960, 540, "WGPU Native Triangle", nil, nil)
|
||||||
|
|
||||||
|
glfw.SetFramebufferSizeCallback(os.window, size_callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
os_run :: proc(os: ^OS) {
|
||||||
|
dt: f32
|
||||||
|
|
||||||
|
for !glfw.WindowShouldClose(os.window) {
|
||||||
|
start := time.tick_now()
|
||||||
|
|
||||||
|
glfw.PollEvents()
|
||||||
|
frame(dt)
|
||||||
|
|
||||||
|
dt = f32(time.duration_seconds(time.tick_since(start)))
|
||||||
|
}
|
||||||
|
|
||||||
|
finish()
|
||||||
|
|
||||||
|
glfw.DestroyWindow(os.window)
|
||||||
|
glfw.Terminate()
|
||||||
|
}
|
||||||
|
|
||||||
|
os_get_render_bounds :: proc(os: ^OS) -> (width, height: u32) {
|
||||||
|
iw, ih := glfw.GetWindowSize(os.window)
|
||||||
|
return u32(iw), u32(ih)
|
||||||
|
}
|
||||||
|
|
||||||
|
os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface {
|
||||||
|
return glfwglue.GetSurface(instance, os.window)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
|
size_callback :: proc "c" (window: glfw.WindowHandle, width, height: i32) {
|
||||||
|
resize()
|
||||||
|
}
|
||||||
Vendored
+60
@@ -0,0 +1,60 @@
|
|||||||
|
package vendor_wgpu_example_triangle
|
||||||
|
|
||||||
|
import "vendor:wgpu"
|
||||||
|
import "vendor:wasm/js"
|
||||||
|
|
||||||
|
OS :: struct {
|
||||||
|
initialized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
|
g_os: ^OS
|
||||||
|
|
||||||
|
os_init :: proc(os: ^OS) {
|
||||||
|
g_os = os
|
||||||
|
assert(js.add_window_event_listener(.Resize, nil, size_callback))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: frame loop is done by the runtime.js repeatedly calling `step`.
|
||||||
|
os_run :: proc(os: ^OS) {
|
||||||
|
os.initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
os_get_render_bounds :: proc(os: ^OS) -> (width, height: u32) {
|
||||||
|
rect := js.get_bounding_client_rect("body")
|
||||||
|
return u32(rect.width), u32(rect.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface {
|
||||||
|
return wgpu.InstanceCreateSurface(
|
||||||
|
instance,
|
||||||
|
&wgpu.SurfaceDescriptor{
|
||||||
|
nextInChain = &wgpu.SurfaceDescriptorFromCanvasHTMLSelector{
|
||||||
|
sType = .SurfaceDescriptorFromCanvasHTMLSelector,
|
||||||
|
selector = "#wgpu-canvas",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file", export)
|
||||||
|
step :: proc(dt: f32) -> bool {
|
||||||
|
if !g_os.initialized {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
frame(dt)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file", fini)
|
||||||
|
os_fini :: proc() {
|
||||||
|
js.remove_window_event_listener(.Resize, nil, size_callback)
|
||||||
|
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
|
size_callback :: proc(e: js.Event) {
|
||||||
|
resize()
|
||||||
|
}
|
||||||
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" style="height: 100%;">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>WGPU WASM Triangle</title>
|
||||||
|
</head>
|
||||||
|
<body id="body" style="height: 100%; padding: 0; margin: 0; overflow: hidden;">
|
||||||
|
<canvas id="wgpu-canvas"></canvas>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="runtime.js"></script>
|
||||||
|
<script type="text/javascript" src="wgpu.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
const mem = new WebAssembly.Memory({ initial: 2000, maximum: 65536, shared: false });
|
||||||
|
const memInterface = new odin.WasmMemoryInterface();
|
||||||
|
memInterface.setMemory(mem);
|
||||||
|
|
||||||
|
const wgpuInterface = new odin.WebGPUInterface(memInterface);
|
||||||
|
|
||||||
|
odin.runWasm("triangle.wasm", null, { wgpu: wgpuInterface.getInterface() }, memInterface, /*intSize=8*/);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
//+build !linux
|
||||||
|
//+build !windows
|
||||||
|
//+build !darwin
|
||||||
|
package wgpu_glfw_glue
|
||||||
|
|
||||||
|
#panic("package wgpu/glfwglue is not supported on the current target")
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package wgpu_glfw_glue
|
||||||
|
|
||||||
|
import "vendor:glfw"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
import CA "vendor:darwin/QuartzCore"
|
||||||
|
|
||||||
|
GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.Surface {
|
||||||
|
ns_window := glfw.GetCocoaWindow(window)
|
||||||
|
ns_window->contentView()->setWantsLayer(true)
|
||||||
|
metal_layer := CA.MetalLayer_layer()
|
||||||
|
ns_window->contentView()->setLayer(metal_layer)
|
||||||
|
return wgpu.InstanceCreateSurface(
|
||||||
|
instance,
|
||||||
|
&wgpu.SurfaceDescriptor{
|
||||||
|
nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer{
|
||||||
|
chain = wgpu.ChainedStruct{
|
||||||
|
sType = .SurfaceDescriptorFromMetalLayer,
|
||||||
|
},
|
||||||
|
layer = rawptr(metal_layer),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
Vendored
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package wgpu_glfw_glue
|
||||||
|
|
||||||
|
import "vendor:glfw"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
|
||||||
|
// GLFW needs to be compiled with wayland support for this to work.
|
||||||
|
SUPPORT_WAYLAND :: #config(WGPU_GFLW_GLUE_SUPPORT_WAYLAND, false)
|
||||||
|
|
||||||
|
GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.Surface {
|
||||||
|
when SUPPORT_WAYLAND {
|
||||||
|
if glfw.GetPlatform() == glfw.PLATFORM_WAYLAND {
|
||||||
|
display := glfw.GetWaylandDisplay()
|
||||||
|
surface := glfw.GetWaylandWindow(window)
|
||||||
|
return wgpu.InstanceCreateSurface(
|
||||||
|
instance,
|
||||||
|
&wgpu.SurfaceDescriptor{
|
||||||
|
nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface{
|
||||||
|
chain = {
|
||||||
|
sType = .SurfaceDescriptorFromWaylandSurface,
|
||||||
|
},
|
||||||
|
display = display,
|
||||||
|
surface = surface,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display := glfw.GetX11Display()
|
||||||
|
window := glfw.GetX11Window(window)
|
||||||
|
return wgpu.InstanceCreateSurface(
|
||||||
|
instance,
|
||||||
|
&wgpu.SurfaceDescriptor{
|
||||||
|
nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow{
|
||||||
|
chain = {
|
||||||
|
sType = .SurfaceDescriptorFromXlibWindow,
|
||||||
|
},
|
||||||
|
display = display,
|
||||||
|
window = u64(window),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package wgpu_glfw_glue
|
||||||
|
|
||||||
|
import win "core:sys/windows"
|
||||||
|
|
||||||
|
import "vendor:glfw"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
|
||||||
|
GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.Surface {
|
||||||
|
hwnd := glfw.GetWin32Window(window)
|
||||||
|
hinstance := win.GetModuleHandleW(nil)
|
||||||
|
return wgpu.InstanceCreateSurface(
|
||||||
|
instance,
|
||||||
|
&wgpu.SurfaceDescriptor{
|
||||||
|
nextInChain = &wgpu.SurfaceDescriptorFromWindowsHWND{
|
||||||
|
chain = wgpu.ChainedStruct{
|
||||||
|
sType = .SurfaceDescriptorFromWindowsHWND,
|
||||||
|
},
|
||||||
|
hinstance = rawptr(hinstance),
|
||||||
|
hwnd = rawptr(hwnd),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
Vendored
Vendored
+2916
File diff suppressed because it is too large
Load Diff
Vendored
+1636
File diff suppressed because it is too large
Load Diff
Vendored
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package wgpu
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
|
g_context: runtime.Context
|
||||||
|
|
||||||
|
@(private="file", init)
|
||||||
|
wgpu_init_allocator :: proc() {
|
||||||
|
if g_context.allocator.procedure == nil {
|
||||||
|
g_context = runtime.default_context()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file", export)
|
||||||
|
wgpu_alloc :: proc "contextless" (size: i32) -> [^]byte {
|
||||||
|
context = g_context
|
||||||
|
bytes, err := runtime.mem_alloc(int(size), 16)
|
||||||
|
assert(err == nil, "wgpu_alloc failed")
|
||||||
|
return raw_data(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file", export)
|
||||||
|
wgpu_free :: proc "contextless" (ptr: rawptr) {
|
||||||
|
context = g_context
|
||||||
|
assert(free(ptr) == nil, "wgpu_free failed")
|
||||||
|
}
|
||||||
Vendored
+75
@@ -0,0 +1,75 @@
|
|||||||
|
//+build !js
|
||||||
|
package wgpu
|
||||||
|
|
||||||
|
BINDINGS_VERSION :: [4]u8{0, 19, 4, 1}
|
||||||
|
BINDINGS_VERSION_STRING :: "0.19.4.1"
|
||||||
|
|
||||||
|
@(private="file", init)
|
||||||
|
wgpu_native_version_check :: proc() {
|
||||||
|
v := (transmute([4]u8)GetVersion()).wzyx
|
||||||
|
|
||||||
|
if v != BINDINGS_VERSION {
|
||||||
|
buf: [1024]byte
|
||||||
|
n := copy(buf[:], "wgpu-native version mismatch: ")
|
||||||
|
n += copy(buf[n:], "bindings are for version ")
|
||||||
|
n += copy(buf[n:], BINDINGS_VERSION_STRING)
|
||||||
|
n += copy(buf[n:], ", but a different version is linked")
|
||||||
|
panic(string(buf[:n]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(link_prefix="wgpu")
|
||||||
|
foreign {
|
||||||
|
@(link_name="wgpuGenerateReport")
|
||||||
|
RawGenerateReport :: proc(instance: Instance, report: ^GlobalReport) ---
|
||||||
|
@(link_name="wgpuInstanceEnumerateAdapters")
|
||||||
|
RawInstanceEnumerateAdapters :: proc(instance: Instance, /* NULLABLE */ options: /* const */ ^InstanceEnumerateAdapterOptions, adapters: [^]Adapter) -> uint ---
|
||||||
|
|
||||||
|
@(link_name="wgpuQueueSubmitForIndex")
|
||||||
|
RawQueueSubmitForIndex :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) -> SubmissionIndex ---
|
||||||
|
|
||||||
|
// Returns true if the queue is empty, or false if there are more queue submissions still in flight.
|
||||||
|
@(link_name="wgpuDevicePoll")
|
||||||
|
RawDevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex) -> b32 ---
|
||||||
|
|
||||||
|
SetLogCallback :: proc "odin" (callback: LogCallback) ---
|
||||||
|
|
||||||
|
SetLogLevel :: proc(level: LogLevel) ---
|
||||||
|
|
||||||
|
GetVersion :: proc() -> u32 ---
|
||||||
|
|
||||||
|
RenderPassEncoderSetPushConstants :: proc(encoder: RenderPassEncoder, stages: ShaderStageFlags, offset: u32, sizeBytes: u32, data: cstring) ---
|
||||||
|
|
||||||
|
RenderPassEncoderMultiDrawIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) ---
|
||||||
|
RenderPassEncoderMultiDrawIndexedIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) ---
|
||||||
|
|
||||||
|
RenderPassEncoderMultiDrawIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) ---
|
||||||
|
RenderPassEncoderMultiDrawIndexedIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) ---
|
||||||
|
|
||||||
|
ComputePassEncoderBeginPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder, querySet: QuerySet, queryIndex: u32) ---
|
||||||
|
ComputePassEncoderEndPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder) ---
|
||||||
|
RenderPassEncoderBeginPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder, querySet: QuerySet, queryIndex: u32) ---
|
||||||
|
RenderPassEncoderEndPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder) ---
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateReport :: proc(instance: Instance) -> (report: GlobalReport) {
|
||||||
|
RawGenerateReport(instance, &report)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceEnumerateAdapters :: proc(instance: Instance, options: ^InstanceEnumerateAdapterOptions = nil, allocator := context.allocator) -> (adapters: []Adapter) {
|
||||||
|
count := RawInstanceEnumerateAdapters(instance, options, nil)
|
||||||
|
adapters = make([]Adapter, count, allocator)
|
||||||
|
RawInstanceEnumerateAdapters(instance, options, raw_data(adapters))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueSubmitForIndex :: proc(queue: Queue, commands: []CommandBuffer) -> SubmissionIndex {
|
||||||
|
return RawQueueSubmitForIndex(queue, len(commands), raw_data(commands))
|
||||||
|
}
|
||||||
|
|
||||||
|
DevicePoll :: proc(device: Device, wait: b32) -> (wrappedSubmissionIndex: WrappedSubmissionIndex, ok: bool) {
|
||||||
|
ok = bool(RawDevicePoll(device, wait, &wrappedSubmissionIndex))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
Vendored
+212
@@ -0,0 +1,212 @@
|
|||||||
|
package wgpu
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
|
LogLevel :: enum i32 {
|
||||||
|
Off,
|
||||||
|
Error,
|
||||||
|
Warn,
|
||||||
|
Info,
|
||||||
|
Debug,
|
||||||
|
Trace,
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceBackend :: enum i32 {
|
||||||
|
Vulkan,
|
||||||
|
GL,
|
||||||
|
Metal,
|
||||||
|
DX12,
|
||||||
|
DX11,
|
||||||
|
BrowserWebGPU,
|
||||||
|
}
|
||||||
|
InstanceBackendFlags :: bit_set[InstanceBackend; Flags]
|
||||||
|
InstanceBackendFlags_All :: InstanceBackendFlags{}
|
||||||
|
InstanceBackendFlags_Primary :: InstanceBackendFlags{ .Vulkan, .Metal, .DX12, .BrowserWebGPU }
|
||||||
|
InstanceBackendFlags_Secondary :: InstanceBackendFlags{ .GL, .DX11 }
|
||||||
|
|
||||||
|
InstanceFlag :: enum i32 {
|
||||||
|
Debug,
|
||||||
|
Validation,
|
||||||
|
DiscardHalLabels,
|
||||||
|
}
|
||||||
|
InstanceFlags :: bit_set[InstanceFlag; Flags]
|
||||||
|
InstanceFlags_Default :: InstanceFlags{}
|
||||||
|
|
||||||
|
Dx12Compiler :: enum i32 {
|
||||||
|
Undefined,
|
||||||
|
Fxc,
|
||||||
|
Dxc,
|
||||||
|
}
|
||||||
|
|
||||||
|
Gles3MinorVersion :: enum i32 {
|
||||||
|
Automatic,
|
||||||
|
Version0,
|
||||||
|
Version1,
|
||||||
|
Version2,
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelineStatisticName :: enum i32 {
|
||||||
|
VertexShaderInvocations,
|
||||||
|
ClipperInvocations,
|
||||||
|
ClipperPrimitivesOut,
|
||||||
|
FragmentShaderInvocations,
|
||||||
|
ComputeShaderInvocations,
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
backends: InstanceBackendFlags,
|
||||||
|
flags: InstanceFlags,
|
||||||
|
dx12ShaderCompiler: Dx12Compiler,
|
||||||
|
gles3MinorVersion: Gles3MinorVersion,
|
||||||
|
dxilPath: cstring,
|
||||||
|
dxcPath: cstring,
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
tracePath: cstring,
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeLimits :: struct {
|
||||||
|
maxPushConstantSize: u32,
|
||||||
|
maxNonSamplerBindings: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
RequiredLimitsExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
limits: NativeLimits,
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportedLimitsExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
limits: NativeLimits,
|
||||||
|
}
|
||||||
|
|
||||||
|
PushConstantRange :: struct {
|
||||||
|
stages: ShaderStageFlags,
|
||||||
|
start: u32,
|
||||||
|
end: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelineLayoutExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
pushConstantRangeCount: uint,
|
||||||
|
pushConstantRanges: [^]PushConstantRange `fmt:"v,pushConstantRangeCount"`,
|
||||||
|
}
|
||||||
|
|
||||||
|
SubmissionIndex :: distinct u64
|
||||||
|
|
||||||
|
WrappedSubmissionIndex :: struct {
|
||||||
|
queue: Queue,
|
||||||
|
submissionIndex: SubmissionIndex,
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderDefine :: struct {
|
||||||
|
name: cstring,
|
||||||
|
value: cstring,
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderModuleGLSLDescriptor :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
stage: ShaderStage,
|
||||||
|
code: cstring,
|
||||||
|
defineCount: uint,
|
||||||
|
defines: [^]ShaderDefine `fmt:"v,defineCount"`,
|
||||||
|
}
|
||||||
|
|
||||||
|
RegistryReport :: struct {
|
||||||
|
numAllocated: uint,
|
||||||
|
numKeptFromUser: uint,
|
||||||
|
numReleasedFromUser: uint,
|
||||||
|
numErrors: uint,
|
||||||
|
elementSize: uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
HubReport :: struct {
|
||||||
|
adapters: RegistryReport,
|
||||||
|
devices: RegistryReport,
|
||||||
|
queues: RegistryReport,
|
||||||
|
pipelineLayouts: RegistryReport,
|
||||||
|
shaderModules: RegistryReport,
|
||||||
|
bindGroupLayouts: RegistryReport,
|
||||||
|
bindGroups: RegistryReport,
|
||||||
|
commandBuffers: RegistryReport,
|
||||||
|
renderBundles: RegistryReport,
|
||||||
|
renderPipelines: RegistryReport,
|
||||||
|
computePipelines: RegistryReport,
|
||||||
|
querySets: RegistryReport,
|
||||||
|
buffers: RegistryReport,
|
||||||
|
textures: RegistryReport,
|
||||||
|
textureViews: RegistryReport,
|
||||||
|
samplers: RegistryReport,
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalReport :: struct {
|
||||||
|
surfaces: RegistryReport,
|
||||||
|
backendType: BackendType,
|
||||||
|
vulkan: HubReport,
|
||||||
|
metal: HubReport,
|
||||||
|
dx12: HubReport,
|
||||||
|
gl: HubReport,
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceEnumerateAdapterOptions :: struct {
|
||||||
|
nextInChain: ^ChainedStruct,
|
||||||
|
backends: InstanceBackendFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
BindGroupEntryExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
buffers: [^]Buffer `fmt:"v,bufferCount"`,
|
||||||
|
bufferCount: uint,
|
||||||
|
samplers: [^]Sampler `fmt:"v,samplerCount"`,
|
||||||
|
samplerCount: uint,
|
||||||
|
textureViews: [^]TextureView `fmt:"v,textureViewCount"`,
|
||||||
|
textureViewCount: uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
BindGroupLayoutEntryExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
QuerySetDescriptorExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
pipelineStatistics: [^]PipelineStatisticName `fmt:"v,pipelineStatisticCount"`,
|
||||||
|
pipelineStatisticCount: uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfaceConfigurationExtras :: struct {
|
||||||
|
using chain: ChainedStruct,
|
||||||
|
desiredMaximumFrameLatency: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
LogCallback :: #type proc "odin" (level: LogLevel, message: cstring)
|
||||||
|
|
||||||
|
// Wrappers
|
||||||
|
|
||||||
|
ConvertOdinToWGPULogLevel :: proc(level: runtime.Logger_Level) -> LogLevel {
|
||||||
|
switch {
|
||||||
|
case level < .Debug: return .Trace
|
||||||
|
case level < .Info: return .Debug
|
||||||
|
case level < .Warning: return .Info
|
||||||
|
case level < .Error: return .Warn
|
||||||
|
case: return .Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertWGPUToOdinLogLevel :: proc(level: LogLevel) -> runtime.Logger_Level {
|
||||||
|
switch level {
|
||||||
|
case .Off, .Trace, .Debug: return .Debug
|
||||||
|
case .Info: return .Info
|
||||||
|
case .Warn: return .Warning
|
||||||
|
case .Error: return .Error
|
||||||
|
case: return .Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertLogLevel :: proc {
|
||||||
|
ConvertOdinToWGPULogLevel,
|
||||||
|
ConvertWGPUToOdinLogLevel,
|
||||||
|
}
|
||||||
Vendored
+3
@@ -24,6 +24,9 @@ Cursor :: XID
|
|||||||
Colormap :: XID
|
Colormap :: XID
|
||||||
GContext :: XID
|
GContext :: XID
|
||||||
|
|
||||||
|
RRCrtc :: XID
|
||||||
|
RROutput :: XID
|
||||||
|
|
||||||
KeyCode :: u8
|
KeyCode :: u8
|
||||||
|
|
||||||
/* ---- X11/Xlib.h ---------------------------------------------------------*/
|
/* ---- X11/Xlib.h ---------------------------------------------------------*/
|
||||||
|
|||||||
Reference in New Issue
Block a user