mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-07 22:29:48 +00:00
[vulkan] Re-adjusting ASTC resolve (#4250)
This is an adjustment made due to problems caused by my ASTC changes some pr's earlier; added sanity to decoded blocks, removes the inconditional storage view for ASTC formats (verified against MaxwellToVk logic), added support to VK_EXT_astc_decode_mode which will ensure a better way to resolve RGFA16/RGFA32 on tilers, simplified ASTC HDR decoding into LDR valid formats. This fixes some issues with SteamDeck, Fire Emblem: Engage washed colors and other problems related to ASTC. _Special Thanks_ 1.- Meowly The Smol (@Gidoly) 2.- @simply0001 for the actual idea on the redundant storage views on the transcoded ASTC path. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4250
This commit is contained in:
@@ -144,11 +144,6 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
||||
info.size.depth == 1;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool WillUseWidenedAstcFormat(const Device& device, const ImageInfo& info) {
|
||||
return WillUseAcceleratedAstcDecode(device, info) &&
|
||||
!VideoCore::Surface::IsPixelFormatSRGB(info.format);
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageCreateInfo MakeImageCreateInfo(const Device& device, const ImageInfo& info,
|
||||
std::optional<VkFormat> format_override = {}) {
|
||||
auto format_info =
|
||||
@@ -269,6 +264,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsLdrAstcFormat(VkFormat format) {
|
||||
return format >= VK_FORMAT_ASTC_4x4_UNORM_BLOCK && format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageAspectFlags ImageViewAspectMask(const VideoCommon::ImageViewInfo& info) {
|
||||
if (info.IsRenderTarget()) {
|
||||
return ImageAspectMask(info.format);
|
||||
@@ -1780,12 +1779,7 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
|
||||
: VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), scheduler{&runtime_.scheduler},
|
||||
runtime{&runtime_},
|
||||
original_image(MakeImage(runtime_.device, runtime_.memory_allocator, info,
|
||||
WillUseWidenedAstcFormat(runtime_.device, info)
|
||||
? std::span<const VkFormat>{}
|
||||
: runtime->ViewFormats(info.format),
|
||||
WillUseWidenedAstcFormat(runtime_.device, info)
|
||||
? std::make_optional(VK_FORMAT_R32G32B32A32_SFLOAT)
|
||||
: std::nullopt)),
|
||||
runtime->ViewFormats(info.format))),
|
||||
aspect_mask(ImageAspectMask(info.format)) {
|
||||
if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
|
||||
switch (Settings::values.accelerate_astc.GetValue()) {
|
||||
@@ -1812,13 +1806,9 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
|
||||
}
|
||||
current_image = &Image::original_image;
|
||||
storage_image_views.resize(info.resources.levels);
|
||||
if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported() &&
|
||||
Settings::values.astc_recompression.GetValue() ==
|
||||
Settings::AstcRecompression::Uncompressed) {
|
||||
if (WillUseAcceleratedAstcDecode(runtime->device, info)) {
|
||||
const auto& device = runtime->device.GetLogical();
|
||||
const VkFormat storage_format = WillUseWidenedAstcFormat(runtime->device, info)
|
||||
? VK_FORMAT_R32G32B32A32_SFLOAT
|
||||
: VK_FORMAT_A8B8G8R8_UNORM_PACK32;
|
||||
const VkFormat storage_format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
|
||||
for (s32 level = 0; level < info.resources.levels; ++level) {
|
||||
storage_image_views[level] =
|
||||
MakeStorageView(device, level, *original_image, storage_format);
|
||||
@@ -2204,9 +2194,7 @@ VkImageView Image::StorageImageView(s32 level) noexcept {
|
||||
auto format_info =
|
||||
MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, true, info.format);
|
||||
if (WillUseAcceleratedAstcDecode(runtime->device, info)) {
|
||||
format_info.format = WillUseWidenedAstcFormat(runtime->device, info)
|
||||
? VK_FORMAT_R32G32B32A32_SFLOAT
|
||||
: VK_FORMAT_A8B8G8R8_UNORM_PACK32;
|
||||
format_info.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
|
||||
}
|
||||
view = MakeStorageView(runtime->device.GetLogical(), level, *(this->*current_image),
|
||||
format_info.format);
|
||||
@@ -2382,11 +2370,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
SanitizeDepthStencilSwizzle(swizzle, device->SupportsDepthStencilSwizzleOne());
|
||||
}
|
||||
}
|
||||
uses_widened_astc_format = WillUseWidenedAstcFormat(*device, image.info);
|
||||
auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
|
||||
if (uses_widened_astc_format) {
|
||||
format_info.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
}
|
||||
if (device->ApiVersion() >= VK_API_VERSION_1_3) {
|
||||
const VkFormatProperties3 properties3 =
|
||||
device->GetPhysical().GetFormatProperties3(format_info.format);
|
||||
@@ -2404,9 +2388,18 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
.pNext = nullptr,
|
||||
.usage = clamped_view_usage,
|
||||
};
|
||||
const VkImageViewASTCDecodeModeEXT astc_decode_mode{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT,
|
||||
.pNext = &image_view_usage,
|
||||
.decodeMode = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
};
|
||||
const void* view_next = &image_view_usage;
|
||||
if (device->IsExtAstcDecodeModeSupported() && IsLdrAstcFormat(format_info.format)) {
|
||||
view_next = &astc_decode_mode;
|
||||
}
|
||||
const VkImageViewCreateInfo create_info{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = &image_view_usage,
|
||||
.pNext = view_next,
|
||||
.flags = 0,
|
||||
.image = image.Handle(),
|
||||
.viewType = VkImageViewType{},
|
||||
@@ -2531,9 +2524,6 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
|
||||
if (image_format == Shader::ImageFormat::Typeless) {
|
||||
if (!typeless_storage_view) {
|
||||
auto info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
|
||||
if (uses_widened_astc_format) {
|
||||
info.format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
}
|
||||
typeless_storage_view = MakeView(info.format, VK_IMAGE_ASPECT_COLOR_BIT, texture_type);
|
||||
}
|
||||
return *typeless_storage_view;
|
||||
|
||||
@@ -436,7 +436,6 @@ private:
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
u32 buffer_size = 0;
|
||||
|
||||
bool uses_widened_astc_format = false;
|
||||
bool supports_depth_comparison = false;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user