Vulkan in fred - #7697
Open
The-E wants to merge 8 commits into
Open
Vulkan in fred#7697The-E wants to merge 8 commits into
The-E wants to merge 8 commits into
Conversation
This was referenced Aug 7, 2026
Closed
The-E
force-pushed
the
vulkan-in-fred
branch
2 times, most recently
from
August 20, 2026 14:35
6f6dd5a to
a8bb085
Compare
The-E
force-pushed
the
vulkan-in-fred
branch
2 times, most recently
from
August 29, 2026 09:17
81e0cc5 to
68b8365
Compare
The-E
force-pushed
the
vulkan-in-fred
branch
from
September 6, 2026 06:31
a999e99 to
fa8fad0
Compare
The-E
force-pushed
the
vulkan-in-fred
branch
from
September 10, 2026 17:46
fa8fad0 to
93f1001
Compare
This commit introduces `gr_end_offscreen_frame()` to manage per-frame state recycling for renders that skip `gr_flip()`. It adds generation-based sub-allocation tracking in `VulkanBuffer` to prevent stale memory access after allocator rewinds. Improves resource management, resolves memory growth issues in non-flipping workflows (e.g., qtFRED briefing map), and ensures consistent handling of uniform segments and descriptor pools. Integrate Vulkan render backend in qtFRED with updated rendering workflows, multi-target support, and enhanced resource lifecycle management.
… always display _something_
bindDescriptorSet took a bare const uint32_t*, and the number of entries vkCmdBindDescriptorSets would read off it came from the set layout, not from the caller -- so a caller passing too few was undetectable and read past the end of its own array. Every call site got the length right by convention: either a *_DYNAMIC_OFFSET_COUNT-sized array or the writer's storage. Take ArrayView<uint32_t> instead, which the subsystem already has for exactly this (VulkanConstants.h, used three lines away in bindSets), and assert size >= getDynamicOffsetCount(). DescriptorWriter::dynamicOffsets() returns a view for the same reason. No call site needed touching -- both the fixed-size arrays and the writer's std::array convert implicitly, which is the argument for the type. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Multi-viewport support introduced a real new concept -- a presentable
surface and everything sized to it -- but gave it nowhere to live. The
struct sat in VulkanRenderer.h and its lifecycle in VulkanRendererSetup.cpp
next to unrelated instance/physical-device/logical-device bring-up, which
pushed that file from 1217 to 1420 lines and VulkanRenderer.cpp past 1000
for the first time.
Move VulkanSurfaceHandle, VulkanPresentTarget and FrameSyncPoint into
VulkanPresentTarget.h, and everything that builds or tears one down into
VulkanPresentTarget.cpp: the surface, swap chain, depth/composition
resources, framebuffers, per-target sync objects, and the choose* helpers
that only createSwapChain/recreateSwapChain ever used. This is the split
VulkanRenderFrame.{h,cpp} already sets the precedent for.
checkSwapChainSupport stops being anonymous-namespace: it is now shared
between the target path and isDeviceUnsuitable, which stays behind with
device selection.
Pure code movement, no behavior change -- verified by diffing the line
multiset of the three original files against all five afterwards. Also
drops a now-dead SDL3/SDL_vulkan.h include, orphaned when the surface
calls moved behind os::VulkanSurfaceProvider.
VulkanRendererSetup.cpp 1420 -> 935 (master: 1217)
VulkanRenderer.cpp 1015 -> 806 (master: 956)
VulkanRenderer.h 787 -> 656 (master: 488)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
VulkanDrawManager grew a third hand-rolled memoization cache with the shadow pass, each one a key struct plus a set handle plus a valid flag, each with its own comparison, its own store, and its own line in resetFrameStats() and invalidateDrawStateCaches(). Three copies of a pattern is where "did we forget to invalidate one" stops being answerable by reading. Fold them into MemoizedDescriptorSet<Inputs, Payload>. The payload is a parameter because the shadow pass memoizes all three of its sets against a single key while applyMaterial memoizes one set per key; that grouping is now expressed as a ShadowSets struct rather than three parallel members. store() refuses an incomplete payload, which is slightly stronger than what it replaces: allocateFrameSet() returns a null handle on pool exhaustion and the Assert() catching it is gone in release builds, so the old code could cache a null set and hand it to every later draw. The old read-time null check covered Material and PerDraw but not the shadow sets at all. The Global set's cache is deliberately left alone -- it is a dirty-flag shape with no key struct and does not fit. Verified in-mission: peak descriptor sets/frame 144 -> 139 with zero descriptor-pool growth, i.e. the cache still hits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…location handling. Unified Vulkan buffer management with `getVkBufferForBinding` to handle outlived streaming bindings safely. Eliminated `clearPendingUniformBindings` to prevent premature state cleanup. Introduced `isFrameAllocCurrent` tracking to avoid stale memory access across frames, ensuring consistent fallback to placeholder buffers for deleted or recycled allocations. Updated descriptor writes and shadow cascades to rely on these safeguards. Fixed various out-of-lifecycle issues in deferred rendering paths and external consumers like qtFRED.
Introduced fallback shadow map textures and samplers for `sampler2DArrayShadow` bindings. Implemented `createFallbackShadowTexture` to generate depth-format fallback textures cleared to the far plane for undefined sampling scenarios. Updated descriptor manager to handle depth-comparison bindings, ensuring correct default behavior when no shadow map is bound. Enhanced lifecycle management for shadow samplers and views.
The rebase onto master brought in "Add Vulkan + Wayland init logic for OpenXR" (a73e256). Two of its conflicts went to the upstream side, which put back code that this branch had moved or deleted: - VulkanRenderer.cpp and VulkanRendererSetup.cpp got a second copy of every function that "Give the present target its own home" moved into VulkanPresentTarget.cpp, and a second copy of the surface-format, present-mode and extent helpers. - The renderer got its m_swapChain* members back, and the frame loop read them again instead of the current target. Several of them no longer existed, so the branch did not compile. - gr_vulkan.cpp got back the OpenXR stubs and stub_use_viewport, which the function pointer table no longer points at. Delete the duplicates and point every reader back at the current target. The render extent is a new concept from that commit, not a leftover: it is the size the engine draws at, which -window_res (and therefore -vr) keeps apart from the window size. Give each present target its own renderExtent so the distinction survives the refactor. The main target follows the upstream rule and keeps the value captured before the window existed; qtFRED's extra viewports draw at their own swap chain extent, because useViewport() resizes gr_screen to whichever one is current. Let each target measure its own window as well, so a surface that reports no extent (Wayland) sizes qtFRED's second window from that window and not from the main one. Keep one accessor for the current target's presented size: getSwapChainExtent() now answers what getCurrentTargetExtent() did, which the upstream commit had duplicated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SdYEgS3eTvxWbjkQQp7yvM
The-E
force-pushed
the
vulkan-in-fred
branch
from
September 14, 2026 16:36
93f1001 to
42b9ef7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Recreated from #7673 as part of the stack
master ← #7652 ← #7653 ← #7671 ← this(moved to a same-repo branch sogh stack linkcan register a real GitHub Stack). See #7673 for original review history.Adds vulkan support to qtFRED. Based on the qtFRED post-processing PR and should be merged after that PR.