[Textures] Normalize 1D TICs that use layers to 1DArray; (#274)
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 Reviewed-on: #274 Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev> Co-authored-by: wildcard <wildcard@eden-emu.dev> Co-committed-by: wildcard <wildcard@eden-emu.dev>
This commit is contained in:
parent
77b3f159af
commit
12f5a96f01
2 changed files with 129 additions and 107 deletions
|
@ -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-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -48,68 +51,73 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
|
||||||
config.texture_type != TextureType::Texture2DNoMipmap) {
|
config.texture_type != TextureType::Texture2DNoMipmap) {
|
||||||
ASSERT(!config.IsPitchLinear());
|
ASSERT(!config.IsPitchLinear());
|
||||||
}
|
}
|
||||||
switch (config.texture_type) {
|
//Normalize so that the 1D that actually uses layers is treated as 1DArray
|
||||||
case TextureType::Texture1D:
|
TextureType tex_type = config.texture_type;
|
||||||
ASSERT(config.BaseLayer() == 0);
|
if (tex_type == TextureType::Texture1D &&
|
||||||
type = ImageType::e1D;
|
(config.Depth() > 1 || config.BaseLayer() != 0)) {
|
||||||
size.width = config.Width();
|
tex_type = TextureType::Texture1DArray;
|
||||||
resources.layers = 1;
|
}
|
||||||
break;
|
switch (tex_type) {
|
||||||
case TextureType::Texture1DArray:
|
case TextureType::Texture1D:
|
||||||
UNIMPLEMENTED_IF(config.BaseLayer() != 0);
|
ASSERT(config.BaseLayer() == 0);
|
||||||
type = ImageType::e1D;
|
type = ImageType::e1D;
|
||||||
size.width = config.Width();
|
size.width = config.Width();
|
||||||
resources.layers = config.Depth();
|
resources.layers = 1;
|
||||||
break;
|
break;
|
||||||
case TextureType::Texture2D:
|
case TextureType::Texture1DArray:
|
||||||
case TextureType::Texture2DNoMipmap:
|
type = ImageType::e1D;
|
||||||
ASSERT(config.Depth() == 1);
|
size.width = config.Width();
|
||||||
type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D;
|
resources.layers = config.BaseLayer() + config.Depth();
|
||||||
rescaleable = !config.IsPitchLinear();
|
break;
|
||||||
size.width = config.Width();
|
case TextureType::Texture2D:
|
||||||
size.height = config.Height();
|
case TextureType::Texture2DNoMipmap:
|
||||||
resources.layers = config.BaseLayer() + 1;
|
ASSERT(config.Depth() == 1);
|
||||||
break;
|
type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D;
|
||||||
case TextureType::Texture2DArray:
|
rescaleable = !config.IsPitchLinear();
|
||||||
type = ImageType::e2D;
|
size.width = config.Width();
|
||||||
rescaleable = true;
|
size.height = config.Height();
|
||||||
size.width = config.Width();
|
resources.layers = config.BaseLayer() + 1;
|
||||||
size.height = config.Height();
|
break;
|
||||||
resources.layers = config.BaseLayer() + config.Depth();
|
case TextureType::Texture2DArray:
|
||||||
break;
|
type = ImageType::e2D;
|
||||||
case TextureType::TextureCubemap:
|
rescaleable = true;
|
||||||
ASSERT(config.Depth() == 1);
|
size.width = config.Width();
|
||||||
type = ImageType::e2D;
|
size.height = config.Height();
|
||||||
size.width = config.Width();
|
resources.layers = config.BaseLayer() + config.Depth();
|
||||||
size.height = config.Height();
|
break;
|
||||||
resources.layers = config.BaseLayer() + 6;
|
case TextureType::TextureCubemap:
|
||||||
break;
|
ASSERT(config.Depth() == 1);
|
||||||
case TextureType::TextureCubeArray:
|
type = ImageType::e2D;
|
||||||
UNIMPLEMENTED_IF(config.load_store_hint != 0);
|
size.width = config.Width();
|
||||||
type = ImageType::e2D;
|
size.height = config.Height();
|
||||||
size.width = config.Width();
|
resources.layers = config.BaseLayer() + 6;
|
||||||
size.height = config.Height();
|
break;
|
||||||
resources.layers = config.BaseLayer() + config.Depth() * 6;
|
case TextureType::TextureCubeArray:
|
||||||
break;
|
UNIMPLEMENTED_IF(config.load_store_hint != 0);
|
||||||
case TextureType::Texture3D:
|
type = ImageType::e2D;
|
||||||
ASSERT(config.BaseLayer() == 0);
|
size.width = config.Width();
|
||||||
type = ImageType::e3D;
|
size.height = config.Height();
|
||||||
size.width = config.Width();
|
resources.layers = config.BaseLayer() + config.Depth() * 6;
|
||||||
size.height = config.Height();
|
break;
|
||||||
size.depth = config.Depth();
|
case TextureType::Texture3D:
|
||||||
resources.layers = 1;
|
ASSERT(config.BaseLayer() == 0);
|
||||||
break;
|
type = ImageType::e3D;
|
||||||
case TextureType::Texture1DBuffer:
|
size.width = config.Width();
|
||||||
type = ImageType::Buffer;
|
size.height = config.Height();
|
||||||
size.width = config.Width();
|
size.depth = config.Depth();
|
||||||
resources.layers = 1;
|
resources.layers = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
case TextureType::Texture1DBuffer:
|
||||||
ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
|
type = ImageType::Buffer;
|
||||||
break;
|
size.width = config.Width();
|
||||||
|
resources.layers = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (num_samples > 1) {
|
if (num_samples > 1) {
|
||||||
size.width *= NumSamplesX(config.msaa_mode);
|
size.width *= NumSamplesX(config.msaa_mode);
|
||||||
size.height *= NumSamplesY(config.msaa_mode);
|
size.height *= NumSamplesY(config.msaa_mode);
|
||||||
}
|
}
|
||||||
if (type != ImageType::Linear) {
|
if (type != ImageType::Linear) {
|
||||||
|
@ -118,7 +126,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
|
||||||
maybe_unaligned_layer_stride = CalculateLayerSize(*this);
|
maybe_unaligned_layer_stride = CalculateLayerSize(*this);
|
||||||
rescaleable &= (block.depth == 0) && resources.levels == 1;
|
rescaleable &= (block.depth == 0) && resources.levels == 1;
|
||||||
rescaleable &= size.height > RescaleHeightThreshold ||
|
rescaleable &= size.height > RescaleHeightThreshold ||
|
||||||
GetFormatType(format) != SurfaceType::ColorTexture;
|
GetFormatType(format) != SurfaceType::ColorTexture;
|
||||||
downscaleable = size.height > DownscaleHeightThreshold;
|
downscaleable = size.height > DownscaleHeightThreshold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -27,53 +30,64 @@ constexpr u8 RENDER_TARGET_SWIZZLE = std::numeric_limits<u8>::max();
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
ImageViewInfo::ImageViewInfo(const TICEntry& config, s32 base_layer) noexcept
|
ImageViewInfo::ImageViewInfo(const TICEntry& config, s32 base_layer) noexcept
|
||||||
: format{PixelFormatFromTIC(config)}, x_source{CastSwizzle(config.x_source)},
|
: format{PixelFormatFromTIC(config)},
|
||||||
y_source{CastSwizzle(config.y_source)}, z_source{CastSwizzle(config.z_source)},
|
x_source{CastSwizzle(config.x_source)},
|
||||||
w_source{CastSwizzle(config.w_source)} {
|
y_source{CastSwizzle(config.y_source)},
|
||||||
range.base = SubresourceBase{
|
z_source{CastSwizzle(config.z_source)},
|
||||||
.level = static_cast<s32>(config.res_min_mip_level),
|
w_source{CastSwizzle(config.w_source)} {
|
||||||
.layer = base_layer,
|
range.base = SubresourceBase{
|
||||||
};
|
.level = static_cast<s32>(config.res_min_mip_level),
|
||||||
range.extent.levels = config.res_max_mip_level - config.res_min_mip_level + 1;
|
.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::TextureCubeArray:
|
||||||
case TextureType::Texture1D:
|
type = ImageViewType::CubeArray;
|
||||||
ASSERT(config.Height() == 1);
|
range.extent.layers = config.Depth() * 6;
|
||||||
ASSERT(config.Depth() == 1);
|
break;
|
||||||
type = ImageViewType::e1D;
|
|
||||||
break;
|
case TextureType::Texture1DBuffer:
|
||||||
case TextureType::Texture2D:
|
type = ImageViewType::Buffer;
|
||||||
case TextureType::Texture2DNoMipmap:
|
break;
|
||||||
ASSERT(config.Depth() == 1);
|
|
||||||
type = config.normalized_coords ? ImageViewType::e2D : ImageViewType::Rect;
|
default:
|
||||||
break;
|
ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
|
||||||
case TextureType::Texture3D:
|
break;
|
||||||
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<int>(config.texture_type.Value()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageViewInfo::ImageViewInfo(ImageViewType type_, PixelFormat format_,
|
ImageViewInfo::ImageViewInfo(ImageViewType type_, PixelFormat format_,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue