feat(render3d): Vulkan in the game's window on Windows
- gpu_select takes Vulkan for a window on Windows; gvk_init asks for VK_KHR_surface, VK_KHR_win32_surface and VK_KHR_swapchain when the renderer will present. A window elsewhere stays on OpenGL with the reason. - gvk_open opens the window without a GL context and makes the screen images at its client area; gvk_swap_make builds the swapchain on the Win32 surface (FIFO with vsync, mailbox or immediate without) and rebuilds it when it is out of date, suboptimal or the window changes size. - gvk_present blits the screen image into the acquired swapchain image, flipped (the screen keeps OpenGL's bottom-up rows), and presents it. - Samplers pointed at a texture unit with u_i and then fed by binding units - the actors do this - read that unit's texture; on Vulkan they drew with the white stand-in (the tent, the log, the chair, the workbench). - gl.ll carries a weak win_gl_drawable for headless macOS builds. On the RTX 3070 Ti the windowed build runs the valley through Vulkan at 3840x2160 with the HUD and the frame-rate readout (16 fps: every upload still waits on the frame, and buffers are host-visible). The headless Vulkan frame is unchanged; OpenGL frames byte-identical at the five viewpoints with 59 self-tests passing. The actor fix is compiled and OpenGL-verified, not yet seen on the PC; blades at the grass's middle distance still draw black on Vulkan. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
66940f9c0a
commit
1b7408c6a1
4 changed files with 254 additions and 19 deletions
|
|
@ -52,8 +52,9 @@ function gpu_select() -> int {
|
|||
if gpu_wanted == 0 { gpu_wanted = GPU_GL }
|
||||
gpu_kind = GPU_GL
|
||||
if gpu_wanted == GPU_VK {
|
||||
# headless for now: the swapchain on the game's window is the next milestone
|
||||
if is_windowed() { gpu_fallback_reason = "the Vulkan window is not built yet" }
|
||||
# a window needs a surface, and only the Win32 one is built
|
||||
gvk_want_surface = is_windowed()
|
||||
if is_windowed() and Os.platform() != "windows" { gpu_fallback_reason = "the Vulkan window is built for Windows only" }
|
||||
else if not gvk_init() { gpu_fallback_reason = gvk_why }
|
||||
else if not gvk_manifest() { gpu_fallback_reason = "the renderer's SPIR-V manifest is missing" }
|
||||
else { gpu_kind = GPU_VK }
|
||||
|
|
@ -228,10 +229,10 @@ function gpu_query_result(id: int, out: words) -> bool {
|
|||
}
|
||||
|
||||
# ---- the context --------------------------------------------------------------------
|
||||
function gpu_open(w: int, h: int, title: string) -> bool { if gpu_kind == GPU_VK { return gvk_open(w, h) }; return gl_open(w, h, title) }
|
||||
function gpu_vsync(on: int) -> void { if gpu_kind == GPU_VK { return }; gl_vsync(on) }
|
||||
function gpu_open(w: int, h: int, title: string) -> bool { if gpu_kind == GPU_VK { return gvk_open(w, h, title) }; return gl_open(w, h, title) }
|
||||
function gpu_vsync(on: int) -> void { if gpu_kind == GPU_VK { gvk_vsync = on != 0; if gvk_swap != 0 { gvk_swap_stale = true }; return }; gl_vsync(on) }
|
||||
function gpu_renderer_name() -> string { if gpu_kind == GPU_VK { return `{gvk_device_name} (Vulkan)` }; return gl_get_string(GL_RENDERER) }
|
||||
function gpu_resize_check() -> bool { if gpu_kind == GPU_VK { return false }; let r = gl_resize_check(); gpu_glcheck_after("the resize check"); return r }
|
||||
function gpu_resize_check() -> bool { if gpu_kind == GPU_VK { return gvk_resize_check() }; let r = gl_resize_check(); gpu_glcheck_after("the resize check"); return r }
|
||||
# the finished frame: presented to the window, or (headless) the GPU's work finished
|
||||
function gpu_present() -> void { if gpu_kind == GPU_VK { gvk_present(); return }; Gl.swap() }
|
||||
# the frame as it will be presented, to a binary PPM with the top row first; before gpu_present
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue