From 5778ba230dbe3cfd32cee7cbcfe725ea4ded4f9d Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 3 Apr 2026 20:28:37 -0700 Subject: [PATCH] fix(diagnostics): add sub-phase markers inside Renderer::beginFrame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AMD RADV crash is renderPhase=beginFrame with faultAddr=(nil) — a NULL pointer dereference somewhere in the pre-pass chain. Add granular markers (bf:ubo, bf:minimap, bf:worldmap, bf:preview, bf:shadow, bf:reflection, bf:renderpass) to pinpoint the exact call. --- src/rendering/renderer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index 7ebb7f2c..eedffe1e 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -1,3 +1,5 @@ +extern volatile const char* g_crashRenderPhase; + #include "rendering/renderer.hpp" #include "rendering/camera.hpp" #include "rendering/camera_controller.hpp" @@ -836,6 +838,7 @@ void Renderer::beginFrame() { if (postProcessPipeline_ && camera) postProcessPipeline_->applyJitter(camera.get()); // Update per-frame UBO with current camera/lighting state + g_crashRenderPhase = "bf:ubo"; updatePerFrameUBO(); // GPU crash diagnostic: skip all pre-passes to isolate crash source @@ -844,6 +847,7 @@ void Renderer::beginFrame() { if (!skipPrePasses) { // --- Off-screen pre-passes (before main render pass) --- // Minimap composite (renders 3x3 tile grid into 768x768 render target) + g_crashRenderPhase = "bf:minimap"; if (minimap && minimap->isEnabled() && camera) { glm::vec3 minimapCenter = camera->getPosition(); if (cameraController && cameraController->isThirdPerson()) @@ -851,11 +855,13 @@ void Renderer::beginFrame() { minimap->compositePass(currentCmd, minimapCenter); } // World map composite (renders zone tiles into 1024x768 render target) + g_crashRenderPhase = "bf:worldmap"; if (worldMap) { worldMap->compositePass(currentCmd); } // Character preview composite passes + g_crashRenderPhase = "bf:preview"; for (auto* preview : activePreviews_) { if (preview && preview->isModelLoaded()) { preview->compositePass(currentCmd, vkCtx->getCurrentFrame()); @@ -863,15 +869,18 @@ void Renderer::beginFrame() { } // Shadow pre-pass (before main render pass) + g_crashRenderPhase = "bf:shadow"; if (shadowsEnabled && shadowDepthImage[0] != VK_NULL_HANDLE) { renderShadowPass(); } // Water reflection pre-pass (renders scene from mirrored camera into 512x512 texture) + g_crashRenderPhase = "bf:reflection"; renderReflectionPass(); } // !skipPrePasses // --- Begin render pass --- + g_crashRenderPhase = "bf:renderpass"; // Select framebuffer: PP off-screen target or swapchain (§4.3 — PostProcessPipeline) VkRenderPassBeginInfo rpInfo{}; rpInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;