From 4b388950e338d496cee4474a89ba25275fe32f94 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 2 Oct 2026 06:33:53 -0400 Subject: [PATCH] [Fix] (DirectVulkan): decline draws from storeless buffers and sample with defaults when a texture's sampler CSO is gone, as DirectGLES does --- .../DirectVulkan/Renderer/UniformManager.cpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp index c117f468..b5badf83 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp @@ -293,11 +293,22 @@ namespace MobileGL::MG_Backend::DirectVulkan { } else { auto samplerHandle = state.BoundSamplerStates[unit]; if (MG_Pipe::MGPipeHandleIsNull(samplerHandle)) samplerHandle = record.Params.BuiltinSampler; - if (MG_Pipe::MGPipeHandleIsNull(samplerHandle) || samplerHandle.Slot >= state.SamplerCsos.size()) - WireDescriptorFatal("sampler-record"); - const auto& sampler = state.SamplerCsos[samplerHandle.Slot]; - if (!sampler.Live || sampler.Gen != samplerHandle.Gen) WireDescriptorFatal("sampler-record-generation"); - out.sampler = m_samplerManager->GetOrCreateSamplerFromParameters(sampler.Params, + // A texture's built-in sampler CSO can be missing or gone while the texture still names + // it: sampler CSOs are content-addressed and recycled at capacity, and the texture's + // record is only re-pointed by its next set_texture_params (a texture whose params never + // crossed names none at all). Sample with GL's default parameters rather than end the + // session - the DirectGLES arm declines the push in both cases. + using SamplerCsoRecord = std::decay_t; + static const decltype(SamplerCsoRecord::Params) kDefaultSamplerParams{}; + const Bool known = !MG_Pipe::MGPipeHandleIsNull(samplerHandle) && + samplerHandle.Slot < state.SamplerCsos.size(); + const SamplerCsoRecord* sampler = known ? &state.SamplerCsos[samplerHandle.Slot] : nullptr; + const Bool stale = sampler == nullptr || !sampler->Live || sampler->Gen != samplerHandle.Gen; + if (stale) { + MGLOG_E_ONCE("Magma wire: sampler CSO {%u, %u} named by texture unit %u is missing or no longer " + "live; sampling with default parameters", samplerHandle.Slot, samplerHandle.Gen, unit); + } + out.sampler = m_samplerManager->GetOrCreateSamplerFromParameters(stale ? kDefaultSamplerParams : sampler->Params, static_cast(record.Desc.InternalFormat), domain == SamplerNumericDomain::SignedInteger || domain == SamplerNumericDomain::UnsignedInteger, levels);