From 2eecc18dc7a9cdb10662c68b9cd77a1fc5e3b5df Mon Sep 17 00:00:00 2001 From: avan Date: Mon, 3 Aug 2026 02:40:06 +0800 Subject: [PATCH] Reject texture descriptors with unmapped addresses Fix an "Invalid texture format 0x25A5A (sRGB: True)" error that occurs when running OCTOPATH TRAVELER 0. The game may leave texture descriptor heap entries filled with 0x5A. Interpreting such uninitialized entries as valid texture descriptors produces an invalid format and causes texture creation to proceed with garbage descriptor data. Validate the texture address before decoding the descriptor. Descriptors with a zero or unmapped address are marked as invalid and skipped. The invalid state is cleared when the corresponding texture pool entry is modified, allowing the descriptor to be evaluated again. --- src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs | 10 ++++++++++ src/Ryujinx.Graphics.Vulkan/TextureArray.cs | 13 +++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs index fd9a1e83b..431042c9c 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs @@ -185,6 +185,16 @@ namespace Ryujinx.Graphics.Gpu.Image if (texture == null) { + // A pool index may point at an uninitialized guest heap slot. Validate the + // descriptor address before decoding format, dimensions, or layout fields. + ulong address = descriptor.UnpackAddress(); + + if (address == 0 || !_channel.MemoryManager.IsMapped(address)) + { + _invalidMap.Set(id); + return ref descriptor; + } + if (_invalidMap.IsSet(id)) { return ref descriptor; diff --git a/src/Ryujinx.Graphics.Vulkan/TextureArray.cs b/src/Ryujinx.Graphics.Vulkan/TextureArray.cs index 2511f5711..8971e1eb9 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureArray.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureArray.cs @@ -54,6 +54,12 @@ namespace Ryujinx.Graphics.Vulkan public void SetSamplers(int index, ISampler[] samplers) { + // Buffer textures use VkBufferView descriptors and do not have samplers. + if (_isBuffer) + { + return; + } + for (int i = 0; i < samplers.Length; i++) { ISampler sampler = samplers[i]; @@ -109,6 +115,13 @@ namespace Ryujinx.Graphics.Vulkan public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags) { + // Texture-buffer arrays contain buffer views rather than image TextureStorage refs. + // Buffer synchronization is handled when BufferManager binds their storage. + if (_isBuffer) + { + return; + } + HashSet storages = _storages; if (storages == null)