mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Merge pull request #3969 from elvodqa/master
Add `sdl2glue` to `vendor:wgpu` package
This commit is contained in:
Vendored
+8
-1
@@ -37,13 +37,20 @@ The bindings work on both `-target:js_wasm32` and `-target:js_wasm64p32`.
|
|||||||
## GLFW Glue
|
## GLFW Glue
|
||||||
|
|
||||||
There is an inner package `glfwglue` that can be used to glue together WGPU and GLFW.
|
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`.
|
It exports one procedure `GetSurface(wgpu.Instance, glfw.WindowHandle) -> wgpu.Surface`.
|
||||||
The procedure will call the needed target specific procedures and return a surface configured
|
The procedure will call the needed target specific procedures and return a surface configured
|
||||||
for the given window.
|
for the given window.
|
||||||
|
|
||||||
Do note that wgpu does not require GLFW, you can use native windows or another windowing library too.
|
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.
|
For that you can take inspiration from `glfwglue` on glueing them together.
|
||||||
|
|
||||||
|
## SDL2 Glue
|
||||||
|
|
||||||
|
There is an inner package `sdl2glue` that can be used to glue together WGPU and SDL2.
|
||||||
|
It exports one procedure `GetSurface(wgpu.Instance, ^sdl2.Window) -> wgpu.Surface`.
|
||||||
|
The procedure will call the needed target specific procedures and return a surface configured
|
||||||
|
for the given window.
|
||||||
|
|
||||||
### Wayland
|
### Wayland
|
||||||
|
|
||||||
GLFW supports Wayland from version 3.4 onwards and only if it is compiled with `-DGLFW_EXPOSE_NATIVE_WAYLAND`.
|
GLFW supports Wayland from version 3.4 onwards and only if it is compiled with `-DGLFW_EXPOSE_NATIVE_WAYLAND`.
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ PAGE_SIZE := 65536
|
|||||||
INITIAL_MEMORY_BYTES := $(shell expr $(INITIAL_MEMORY_PAGES) \* $(PAGE_SIZE))
|
INITIAL_MEMORY_BYTES := $(shell expr $(INITIAL_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||||
MAX_MEMORY_BYTES := $(shell expr $(MAX_MEMORY_PAGES) \* $(PAGE_SIZE))
|
MAX_MEMORY_BYTES := $(shell expr $(MAX_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||||
|
|
||||||
web/triangle.wasm: $(FILES) ../wgpu.js ../../wasm/js/runtime.js
|
web/triangle.wasm: $(FILES) ../../wgpu.js ../../../wasm/js/runtime.js
|
||||||
odin build . \
|
odin build . \
|
||||||
-target:js_wasm32 -out:web/triangle.wasm -o:size \
|
-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)"
|
-extra-linker-flags:"--export-table --import-memory --initial-memory=$(INITIAL_MEMORY_BYTES) --max-memory=$(MAX_MEMORY_BYTES)"
|
||||||
|
|
||||||
cp ../wgpu.js web/wgpu.js
|
cp ../../wgpu.js web/wgpu.js
|
||||||
cp ../../wasm/js/runtime.js web/runtime.js
|
cp ../../../wasm/js/runtime.js web/runtime.js
|
||||||
@@ -8,5 +8,5 @@ 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%"
|
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 "..\..\wgpu.js" "web\wgpu.js"
|
||||||
copy "..\..\wasm\js\runtime.js" "web\runtime.js"
|
copy "..\..\..\wasm\js\runtime.js" "web\runtime.js"
|
||||||
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
+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()
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
//+build !js
|
||||||
|
package vendor_wgpu_example_triangle
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
import "vendor:sdl2"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
import "vendor:wgpu/sdl2glue"
|
||||||
|
|
||||||
|
OS :: struct {
|
||||||
|
window: ^sdl2.Window,
|
||||||
|
}
|
||||||
|
|
||||||
|
os_init :: proc(os: ^OS) {
|
||||||
|
sdl_flags := sdl2.InitFlags{.VIDEO, .JOYSTICK, .GAMECONTROLLER, .EVENTS}
|
||||||
|
if res := sdl2.Init(sdl_flags); res != 0 {
|
||||||
|
fmt.eprintfln("ERROR: Failed to initialize SDL: [%s]", sdl2.GetError())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
window_flags: sdl2.WindowFlags = {.SHOWN, .ALLOW_HIGHDPI, .RESIZABLE}
|
||||||
|
os.window = sdl2.CreateWindow(
|
||||||
|
"WGPU Native Triangle",
|
||||||
|
sdl2.WINDOWPOS_CENTERED,
|
||||||
|
sdl2.WINDOWPOS_CENTERED,
|
||||||
|
960,
|
||||||
|
540,
|
||||||
|
window_flags,
|
||||||
|
)
|
||||||
|
if os.window == nil {
|
||||||
|
fmt.eprintfln("ERROR: Failed to create the SDL Window: [%s]", sdl2.GetError())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sdl2.AddEventWatch(size_callback, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
os_run :: proc(os: ^OS) {
|
||||||
|
now := sdl2.GetPerformanceCounter()
|
||||||
|
last : u64
|
||||||
|
dt: f32
|
||||||
|
main_loop: for {
|
||||||
|
last = now
|
||||||
|
now = sdl2.GetPerformanceCounter()
|
||||||
|
dt = f32((now - last) * 1000) / f32(sdl2.GetPerformanceFrequency())
|
||||||
|
|
||||||
|
e: sdl2.Event
|
||||||
|
|
||||||
|
for sdl2.PollEvent(&e) {
|
||||||
|
#partial switch (e.type) {
|
||||||
|
case .QUIT:
|
||||||
|
break main_loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame(dt)
|
||||||
|
}
|
||||||
|
|
||||||
|
sdl2.DestroyWindow(os.window)
|
||||||
|
sdl2.Quit()
|
||||||
|
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
os_get_render_bounds :: proc(os: ^OS) -> (width, height: u32) {
|
||||||
|
iw, ih: c.int
|
||||||
|
sdl2.GetWindowSize(os.window, &iw, &ih)
|
||||||
|
return u32(iw), u32(ih)
|
||||||
|
}
|
||||||
|
|
||||||
|
os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface {
|
||||||
|
return sdl2glue.GetSurface(instance, os.window)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
|
size_callback :: proc "c" (userdata: rawptr, event: ^sdl2.Event) -> c.int {
|
||||||
|
if event.type == .WINDOWEVENT {
|
||||||
|
if event.window.event == .SIZE_CHANGED || event.window.event == .RESIZED {
|
||||||
|
resize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
+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_sdl2_glue
|
||||||
|
|
||||||
|
#panic("package wgpu/sdl2glue is not supported on the current target")
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package wgpu_sdl2_glue
|
||||||
|
|
||||||
|
import "vendor:sdl2"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
import CA "vendor:darwin/QuartzCore"
|
||||||
|
import NS "core:sys/darwin/Foundation"
|
||||||
|
|
||||||
|
GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
|
||||||
|
window_info: sdl2.SysWMinfo
|
||||||
|
sdl2.GetWindowWMInfo(window, &window_info)
|
||||||
|
ns_window := cast(^NS.Window)window_info.info.cocoa.window
|
||||||
|
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
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package wgpu_sdl2_glue
|
||||||
|
|
||||||
|
import "vendor:sdl2"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
|
||||||
|
GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
|
||||||
|
window_info: sdl2.SysWMinfo
|
||||||
|
sdl2.GetWindowWMInfo(window, &window_info)
|
||||||
|
if window_info.subsystem == .WAYLAND {
|
||||||
|
display := window_info.info.wl.display
|
||||||
|
surface := window_info.info.wl.surface
|
||||||
|
return wgpu.InstanceCreateSurface(
|
||||||
|
instance,
|
||||||
|
&wgpu.SurfaceDescriptor{
|
||||||
|
nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface{
|
||||||
|
chain = {
|
||||||
|
sType = .SurfaceDescriptorFromWaylandSurface,
|
||||||
|
},
|
||||||
|
display = display,
|
||||||
|
surface = surface,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else if window_info.subsystem == .X11 {
|
||||||
|
display := window_info.info.x11.display
|
||||||
|
window := window_info.info.x11.window
|
||||||
|
return wgpu.InstanceCreateSurface(
|
||||||
|
instance,
|
||||||
|
&wgpu.SurfaceDescriptor{
|
||||||
|
nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow{
|
||||||
|
chain = {
|
||||||
|
sType = .SurfaceDescriptorFromXlibWindow,
|
||||||
|
},
|
||||||
|
display = display,
|
||||||
|
window = u64(window),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
panic("wgpu sdl2 glue: unsupported platform, expected Wayland or X11")
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package wgpu_sdl2_glue
|
||||||
|
|
||||||
|
import win "core:sys/windows"
|
||||||
|
|
||||||
|
import "vendor:sdl2"
|
||||||
|
import "vendor:wgpu"
|
||||||
|
|
||||||
|
GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
|
||||||
|
window_info: sdl2.SysWMinfo
|
||||||
|
sdl2.GetWindowWMInfo(window, &window_info)
|
||||||
|
hwnd := window_info.info.win.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),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user