From a935f197423ae0b5dcdeb7adeecea94f3974f9fd Mon Sep 17 00:00:00 2001 From: wildcard Date: Sun, 17 Aug 2025 09:10:30 +0200 Subject: [PATCH 1/3] [Textures] Normalize 1D TICs that use layers to 1DArray; Some TIC entries are tagged Texture1D but actually use array layers so previously it was marked as simple 1D and hence the assert, this fixes the said issue(Depth > 1 or baseLayer != 0). Games fixed- God Eater 3 --- src/video_core/texture_cache/image_info.cpp | 127 +++++++++--------- .../texture_cache/image_view_info.cpp | 103 +++++++------- 2 files changed, 123 insertions(+), 107 deletions(-) diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 135dd64de3..5664767914 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -48,68 +48,73 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { config.texture_type != TextureType::Texture2DNoMipmap) { ASSERT(!config.IsPitchLinear()); } - switch (config.texture_type) { - case TextureType::Texture1D: - ASSERT(config.BaseLayer() == 0); - type = ImageType::e1D; - size.width = config.Width(); - resources.layers = 1; - break; - case TextureType::Texture1DArray: - UNIMPLEMENTED_IF(config.BaseLayer() != 0); - type = ImageType::e1D; - size.width = config.Width(); - resources.layers = config.Depth(); - break; - case TextureType::Texture2D: - case TextureType::Texture2DNoMipmap: - ASSERT(config.Depth() == 1); - type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D; - rescaleable = !config.IsPitchLinear(); - size.width = config.Width(); - size.height = config.Height(); - resources.layers = config.BaseLayer() + 1; - break; - case TextureType::Texture2DArray: - type = ImageType::e2D; - rescaleable = true; - size.width = config.Width(); - size.height = config.Height(); - resources.layers = config.BaseLayer() + config.Depth(); - break; - case TextureType::TextureCubemap: - ASSERT(config.Depth() == 1); - type = ImageType::e2D; - size.width = config.Width(); - size.height = config.Height(); - resources.layers = config.BaseLayer() + 6; - break; - case TextureType::TextureCubeArray: - UNIMPLEMENTED_IF(config.load_store_hint != 0); - type = ImageType::e2D; - size.width = config.Width(); - size.height = config.Height(); - resources.layers = config.BaseLayer() + config.Depth() * 6; - break; - case TextureType::Texture3D: - ASSERT(config.BaseLayer() == 0); - type = ImageType::e3D; - size.width = config.Width(); - size.height = config.Height(); - size.depth = config.Depth(); - resources.layers = 1; - break; - case TextureType::Texture1DBuffer: - type = ImageType::Buffer; - size.width = config.Width(); - resources.layers = 1; - break; - default: - ASSERT_MSG(false, "Invalid texture_type={}", static_cast(config.texture_type.Value())); - break; + //Normalize so that the 1D that actually uses layers is treated as 1DArray + TextureType tex_type = config.texture_type; + if (tex_type == TextureType::Texture1D && + (config.Depth() > 1 || config.BaseLayer() != 0)) { + tex_type = TextureType::Texture1DArray; + } + switch (tex_type) { + case TextureType::Texture1D: + ASSERT(config.BaseLayer() == 0); + type = ImageType::e1D; + size.width = config.Width(); + resources.layers = 1; + break; + case TextureType::Texture1DArray: + type = ImageType::e1D; + size.width = config.Width(); + resources.layers = config.BaseLayer() + config.Depth(); + break; + case TextureType::Texture2D: + case TextureType::Texture2DNoMipmap: + ASSERT(config.Depth() == 1); + type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D; + rescaleable = !config.IsPitchLinear(); + size.width = config.Width(); + size.height = config.Height(); + resources.layers = config.BaseLayer() + 1; + break; + case TextureType::Texture2DArray: + type = ImageType::e2D; + rescaleable = true; + size.width = config.Width(); + size.height = config.Height(); + resources.layers = config.BaseLayer() + config.Depth(); + break; + case TextureType::TextureCubemap: + ASSERT(config.Depth() == 1); + type = ImageType::e2D; + size.width = config.Width(); + size.height = config.Height(); + resources.layers = config.BaseLayer() + 6; + break; + case TextureType::TextureCubeArray: + UNIMPLEMENTED_IF(config.load_store_hint != 0); + type = ImageType::e2D; + size.width = config.Width(); + size.height = config.Height(); + resources.layers = config.BaseLayer() + config.Depth() * 6; + break; + case TextureType::Texture3D: + ASSERT(config.BaseLayer() == 0); + type = ImageType::e3D; + size.width = config.Width(); + size.height = config.Height(); + size.depth = config.Depth(); + resources.layers = 1; + break; + case TextureType::Texture1DBuffer: + type = ImageType::Buffer; + size.width = config.Width(); + resources.layers = 1; + break; + default: + ASSERT_MSG(false, "Invalid texture_type={}", static_cast(config.texture_type.Value())); + break; } if (num_samples > 1) { - size.width *= NumSamplesX(config.msaa_mode); + size.width *= NumSamplesX(config.msaa_mode); size.height *= NumSamplesY(config.msaa_mode); } if (type != ImageType::Linear) { @@ -118,7 +123,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { maybe_unaligned_layer_stride = CalculateLayerSize(*this); rescaleable &= (block.depth == 0) && resources.levels == 1; rescaleable &= size.height > RescaleHeightThreshold || - GetFormatType(format) != SurfaceType::ColorTexture; + GetFormatType(format) != SurfaceType::ColorTexture; downscaleable = size.height > DownscaleHeightThreshold; } } diff --git a/src/video_core/texture_cache/image_view_info.cpp b/src/video_core/texture_cache/image_view_info.cpp index f478851473..6ba49c0661 100644 --- a/src/video_core/texture_cache/image_view_info.cpp +++ b/src/video_core/texture_cache/image_view_info.cpp @@ -27,53 +27,64 @@ constexpr u8 RENDER_TARGET_SWIZZLE = std::numeric_limits::max(); } // Anonymous namespace ImageViewInfo::ImageViewInfo(const TICEntry& config, s32 base_layer) noexcept - : format{PixelFormatFromTIC(config)}, x_source{CastSwizzle(config.x_source)}, - y_source{CastSwizzle(config.y_source)}, z_source{CastSwizzle(config.z_source)}, - w_source{CastSwizzle(config.w_source)} { - range.base = SubresourceBase{ - .level = static_cast(config.res_min_mip_level), - .layer = base_layer, - }; - range.extent.levels = config.res_max_mip_level - config.res_min_mip_level + 1; + : format{PixelFormatFromTIC(config)}, + x_source{CastSwizzle(config.x_source)}, + y_source{CastSwizzle(config.y_source)}, + z_source{CastSwizzle(config.z_source)}, + w_source{CastSwizzle(config.w_source)} { + range.base = SubresourceBase{ + .level = static_cast(config.res_min_mip_level), + .layer = base_layer, + }; + range.extent.levels = config.res_max_mip_level - config.res_min_mip_level + 1; + TextureType tex_type = config.texture_type; + //normalize 1D texture with many layers + if (tex_type == TextureType::Texture1D && + (config.Depth() > 1 || base_layer != 0)) { + tex_type = TextureType::Texture1DArray; + } + switch (tex_type) { + case TextureType::Texture1D: + ASSERT(config.Height() == 1); + ASSERT(config.Depth() == 1); + type = ImageViewType::e1D; + break; + case TextureType::Texture1DArray: + ASSERT(config.Height() == 1); + type = ImageViewType::e1DArray; + range.extent.layers = config.Depth(); + break; + case TextureType::Texture2D: + case TextureType::Texture2DNoMipmap: + ASSERT(config.Depth() == 1); + type = config.normalized_coords ? ImageViewType::e2D : ImageViewType::Rect; + break; + case TextureType::Texture2DArray: + type = ImageViewType::e2DArray; + range.extent.layers = config.Depth(); + break; + case TextureType::Texture3D: + type = ImageViewType::e3D; + break; + case TextureType::TextureCubemap: + ASSERT(config.Depth() == 1); + type = ImageViewType::Cube; + range.extent.layers = 6; + break; - switch (config.texture_type) { - case TextureType::Texture1D: - ASSERT(config.Height() == 1); - ASSERT(config.Depth() == 1); - type = ImageViewType::e1D; - break; - case TextureType::Texture2D: - case TextureType::Texture2DNoMipmap: - ASSERT(config.Depth() == 1); - type = config.normalized_coords ? ImageViewType::e2D : ImageViewType::Rect; - break; - case TextureType::Texture3D: - type = ImageViewType::e3D; - break; - case TextureType::TextureCubemap: - ASSERT(config.Depth() == 1); - type = ImageViewType::Cube; - range.extent.layers = 6; - break; - case TextureType::Texture1DArray: - type = ImageViewType::e1DArray; - range.extent.layers = config.Depth(); - break; - case TextureType::Texture2DArray: - type = ImageViewType::e2DArray; - range.extent.layers = config.Depth(); - break; - case TextureType::Texture1DBuffer: - type = ImageViewType::Buffer; - break; - case TextureType::TextureCubeArray: - type = ImageViewType::CubeArray; - range.extent.layers = config.Depth() * 6; - break; - default: - ASSERT_MSG(false, "Invalid texture_type={}", static_cast(config.texture_type.Value())); - break; - } + case TextureType::TextureCubeArray: + type = ImageViewType::CubeArray; + range.extent.layers = config.Depth() * 6; + break; + + case TextureType::Texture1DBuffer: + type = ImageViewType::Buffer; + break; + + default: + ASSERT_MSG(false, "Invalid texture_type={}", static_cast(config.texture_type.Value())); + break; + } } ImageViewInfo::ImageViewInfo(ImageViewType type_, PixelFormat format_, -- 2.39.5 From 58addd03a627c63747f83f71240f5594b67e6165 Mon Sep 17 00:00:00 2001 From: wildcard Date: Sun, 17 Aug 2025 13:20:02 +0200 Subject: [PATCH 2/3] Update src/video_core/texture_cache/image_info.cpp --- src/video_core/texture_cache/image_info.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 5664767914..df01b4ed8a 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -- 2.39.5 From f1602285201f66e163c6538c8913ead54b873255 Mon Sep 17 00:00:00 2001 From: wildcard Date: Sun, 17 Aug 2025 13:20:46 +0200 Subject: [PATCH 3/3] Update src/video_core/texture_cache/image_view_info.cpp --- src/video_core/texture_cache/image_view_info.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video_core/texture_cache/image_view_info.cpp b/src/video_core/texture_cache/image_view_info.cpp index 6ba49c0661..0766a3b79a 100644 --- a/src/video_core/texture_cache/image_view_info.cpp +++ b/src/video_core/texture_cache/image_view_info.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -- 2.39.5