[video_core] Improve texture rendering (#2830)
This fixes some edge cases and improves texture rendering, bringing it closer to specifications. This fixes many assertions that occur in some games, such as EOW. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2830 Reviewed-by: Maufeat <sahyno1996@gmail.com> Co-authored-by: MaranBr <maranbr@outlook.com> Co-committed-by: MaranBr <maranbr@outlook.com>
This commit is contained in:
parent
53bfd56b70
commit
73ebf59af7
|
|
@ -54,65 +54,81 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
|
|||
TextureType tex_type = config.texture_type;
|
||||
if (tex_type == TextureType::Texture1D && (config.Depth() > 1 || config.BaseLayer() != 0)) {
|
||||
tex_type = TextureType::Texture1DArray;
|
||||
} else if (tex_type == TextureType::Texture2D && (config.Depth() > 1 || config.BaseLayer() != 0)) {
|
||||
tex_type = TextureType::Texture2DArray;
|
||||
}
|
||||
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<int>(tex_type));
|
||||
break;
|
||||
case TextureType::Texture1D:
|
||||
ASSERT(config.BaseLayer() == 0);
|
||||
ASSERT(config.Depth() == 1);
|
||||
type = ImageType::e1D;
|
||||
size.width = config.Width();
|
||||
size.depth = 1;
|
||||
resources.layers = 1;
|
||||
break;
|
||||
case TextureType::Texture1DArray:
|
||||
ASSERT(config.Depth() > 0);
|
||||
ASSERT(config.BaseLayer() < config.Depth());
|
||||
type = ImageType::e1D;
|
||||
size.width = config.Width();
|
||||
size.depth = 1;
|
||||
resources.layers = config.Depth() - config.BaseLayer();
|
||||
break;
|
||||
case TextureType::Texture2D:
|
||||
case TextureType::Texture2DNoMipmap:
|
||||
ASSERT(config.BaseLayer() == 0);
|
||||
ASSERT(config.Depth() == 1);
|
||||
type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D;
|
||||
rescaleable = !config.IsPitchLinear();
|
||||
size.width = config.Width();
|
||||
size.height = config.Height();
|
||||
size.depth = 1;
|
||||
resources.layers = 1;
|
||||
break;
|
||||
case TextureType::Texture2DArray:
|
||||
ASSERT(config.Depth() > 0);
|
||||
ASSERT(config.BaseLayer() < config.Depth());
|
||||
type = ImageType::e2D;
|
||||
rescaleable = true;
|
||||
size.width = config.Width();
|
||||
size.height = config.Height();
|
||||
size.depth = 1;
|
||||
resources.layers = config.Depth() - config.BaseLayer();
|
||||
break;
|
||||
case TextureType::TextureCubemap:
|
||||
ASSERT(config.Depth() == 1);
|
||||
type = ImageType::e2D;
|
||||
size.width = config.Width();
|
||||
size.height = config.Height();
|
||||
size.depth = 1;
|
||||
resources.layers = 6;
|
||||
break;
|
||||
case TextureType::TextureCubeArray:
|
||||
UNIMPLEMENTED_IF(config.load_store_hint != 0);
|
||||
ASSERT(config.Depth() > 0);
|
||||
type = ImageType::e2D;
|
||||
size.width = config.Width();
|
||||
size.height = config.Height();
|
||||
size.depth = 1;
|
||||
resources.layers = (config.Depth() - config.BaseLayer()) * 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();
|
||||
size.depth = 1;
|
||||
resources.layers = 1;
|
||||
break;
|
||||
default:
|
||||
ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(tex_type));
|
||||
break;
|
||||
}
|
||||
if (num_samples > 1) {
|
||||
size.width *= NumSamplesX(config.msaa_mode);
|
||||
|
|
|
|||
|
|
@ -30,59 +30,73 @@ constexpr u8 RENDER_TARGET_SWIZZLE = (std::numeric_limits<u8>::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<s32>(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;
|
||||
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;
|
||||
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<int>(tex_type));
|
||||
break;
|
||||
}
|
||||
: 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<s32>(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;
|
||||
if (tex_type == TextureType::Texture1D && (config.Depth() > 1 || base_layer != 0)) {
|
||||
tex_type = TextureType::Texture1DArray;
|
||||
} else if (tex_type == TextureType::Texture2D && (config.Depth() > 1 || base_layer != 0)) {
|
||||
tex_type = TextureType::Texture2DArray;
|
||||
}
|
||||
switch (tex_type) {
|
||||
case TextureType::Texture1D:
|
||||
ASSERT(config.Height() == 1);
|
||||
ASSERT(config.Depth() == 1);
|
||||
ASSERT(base_layer == 0);
|
||||
type = ImageViewType::e1D;
|
||||
range.extent.layers = 1;
|
||||
break;
|
||||
case TextureType::Texture1DArray:
|
||||
ASSERT(config.Depth() > 0);
|
||||
ASSERT(static_cast<u32>(base_layer) < config.Depth());
|
||||
type = ImageViewType::e1DArray;
|
||||
range.extent.layers = config.Depth() - base_layer;
|
||||
break;
|
||||
case TextureType::Texture2D:
|
||||
case TextureType::Texture2DNoMipmap:
|
||||
ASSERT(config.Depth() == 1);
|
||||
ASSERT(base_layer == 0);
|
||||
type = config.normalized_coords ? ImageViewType::e2D : ImageViewType::Rect;
|
||||
range.extent.layers = 1;
|
||||
break;
|
||||
case TextureType::Texture2DArray:
|
||||
ASSERT(config.Depth() > 0);
|
||||
ASSERT(static_cast<u32>(base_layer) < config.Depth());
|
||||
type = ImageViewType::e2DArray;
|
||||
range.extent.layers = config.Depth() - base_layer;
|
||||
break;
|
||||
case TextureType::TextureCubemap:
|
||||
ASSERT(config.Depth() == 1);
|
||||
type = ImageViewType::Cube;
|
||||
range.extent.layers = 6;
|
||||
break;
|
||||
case TextureType::TextureCubeArray:
|
||||
ASSERT(config.Depth() > 0);
|
||||
ASSERT(static_cast<u32>(base_layer) < config.Depth());
|
||||
type = ImageViewType::CubeArray;
|
||||
range.extent.layers = (config.Depth() - base_layer) * 6;
|
||||
break;
|
||||
case TextureType::Texture3D:
|
||||
ASSERT(base_layer == 0);
|
||||
type = ImageViewType::e3D;
|
||||
range.extent.layers = 1;
|
||||
break;
|
||||
case TextureType::Texture1DBuffer:
|
||||
type = ImageViewType::Buffer;
|
||||
range.extent.layers = 1;
|
||||
break;
|
||||
default:
|
||||
ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(tex_type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ImageViewInfo::ImageViewInfo(ImageViewType type_, PixelFormat format_,
|
||||
|
|
|
|||
Loading…
Reference in New Issue