mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
graphics: broaden storage image and view format compatibility
This commit is contained in:
@@ -281,24 +281,26 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
|
||||
const auto tile = descriptor.TileMode();
|
||||
const bool is_2d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) &&
|
||||
descriptor.Depth() == 0;
|
||||
descriptor.Depth() == 0 && descriptor.BaseArray5() == 0;
|
||||
const bool is_2d_array =
|
||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray &&
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) &&
|
||||
descriptor.BaseArray5() <= descriptor.Depth();
|
||||
const bool is_3d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D &&
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D);
|
||||
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D) &&
|
||||
descriptor.BaseArray5() == 0;
|
||||
TileBlockLayout depth_block {};
|
||||
const auto depth_bpe = Prospero::RenderTargetBytesPerElement(descriptor.Format());
|
||||
const bool supported_depth_tile =
|
||||
tile == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && !resource.read &&
|
||||
!Prospero::IsFmaskTextureFormat(descriptor.Format()) && (is_2d || is_2d_array) &&
|
||||
TileGetBlockLayout(TileBlockFamily::Depth64KB, depth_bpe, depth_block);
|
||||
const bool supported_volume_tile =
|
||||
is_3d && tile == Prospero::GpuEnumValue(Prospero::TileMode::kStandard4KB);
|
||||
const bool supported_standard_tile =
|
||||
tile == Prospero::GpuEnumValue(Prospero::TileMode::kStandard4KB) &&
|
||||
TileIsStandard4KBTextureSupported(descriptor.Format());
|
||||
const bool supported_tile = tile == Prospero::GpuEnumValue(Prospero::TileMode::kLinear) ||
|
||||
tile == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) ||
|
||||
supported_depth_tile || supported_volume_tile;
|
||||
supported_depth_tile || supported_standard_tile;
|
||||
const bool supported_swizzle = IsValidImageSwizzle(descriptor.DstSelXYZW()) &&
|
||||
(descriptor.DstSelXYZW() == DstSel(4, 5, 6, 7) ||
|
||||
!resource.read);
|
||||
@@ -306,8 +308,7 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
|
||||
return (is_2d || is_2d_array || is_3d) && supported_tile && supported_mip_view &&
|
||||
descriptor.BaseLevel() == descriptor.LastLevel() &&
|
||||
descriptor.LastLevel() <= descriptor.MaxMip() && descriptor.MinLod() == 0 &&
|
||||
descriptor.BaseArray5() == 0 && supported_swizzle && descriptor.BCSwizzle() == 0 &&
|
||||
!descriptor.MsaaDepth();
|
||||
supported_swizzle && descriptor.BCSwizzle() == 0 && !descriptor.MsaaDepth();
|
||||
}
|
||||
|
||||
static bool IsSupportedStorageTextureEncoding(const ShaderTextureResource& descriptor) {
|
||||
@@ -320,9 +321,11 @@ static bool IsSupportedStorageTextureEncoding(const ShaderTextureResource& descr
|
||||
(static_cast<uint32_t>(descriptor.LastLevel()) << 16u) |
|
||||
(static_cast<uint32_t>(descriptor.TileMode()) << 20u) |
|
||||
(static_cast<uint32_t>(descriptor.Type()) << 28u);
|
||||
const uint32_t expected_field4 =
|
||||
descriptor.Depth() | (static_cast<uint32_t>(descriptor.BaseArray5()) << 16u);
|
||||
return (descriptor.fields[1] & field1_reserved_mask) == 0 &&
|
||||
(descriptor.fields[2] & field2_reserved_mask) == 0 &&
|
||||
descriptor.fields[3] == expected_field3 && descriptor.fields[4] == descriptor.Depth() &&
|
||||
descriptor.fields[3] == expected_field3 && descriptor.fields[4] == expected_field4 &&
|
||||
(descriptor.fields[5] & ~field5_max_mip_mask) == field5_expected;
|
||||
}
|
||||
|
||||
|
||||
@@ -466,35 +466,6 @@ IsSupportedDisplayRenderTargetTileMode(uint32_t tile_mode) noexcept {
|
||||
IsSupportedStandard64RenderTarget(info);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool IsRgba8SrgbReinterpretation(vk::Format cached,
|
||||
vk::Format requested) noexcept {
|
||||
switch (cached) {
|
||||
case vk::Format::eR8G8B8A8Unorm: return requested == vk::Format::eR8G8B8A8Srgb;
|
||||
case vk::Format::eR8G8B8A8Srgb: return requested == vk::Format::eR8G8B8A8Unorm;
|
||||
case vk::Format::eB8G8R8A8Unorm: return requested == vk::Format::eB8G8R8A8Srgb;
|
||||
case vk::Format::eB8G8R8A8Srgb: return requested == vk::Format::eB8G8R8A8Unorm;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool IsRgba16UintFloatReinterpretation(vk::Format cached,
|
||||
vk::Format requested) noexcept {
|
||||
switch (cached) {
|
||||
case vk::Format::eR16G16B16A16Sfloat: return requested == vk::Format::eR16G16B16A16Uint;
|
||||
case vk::Format::eR16G16B16A16Uint: return requested == vk::Format::eR16G16B16A16Sfloat;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool IsRgba8UnormUintReinterpretation(vk::Format cached,
|
||||
vk::Format requested) noexcept {
|
||||
switch (cached) {
|
||||
case vk::Format::eR8G8B8A8Unorm: return requested == vk::Format::eR8G8B8A8Uint;
|
||||
case vk::Format::eR8G8B8A8Uint: return requested == vk::Format::eR8G8B8A8Unorm;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool DecodePackedColorClear(vk::Format format, uint32_t packed,
|
||||
vk::ClearColorValue& clear) {
|
||||
vk::ClearColorValue next {};
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
namespace ImageViewOps {
|
||||
|
||||
[[nodiscard]] vk::ImageAspectFlags DepthAspectMask(vk::Format format);
|
||||
[[nodiscard]] bool FormatsCompatible(vk::Format base, vk::Format view) noexcept;
|
||||
} // namespace ImageViewOps
|
||||
|
||||
[[nodiscard]] inline bool IsValidImageSwizzle(uint32_t swizzle) noexcept {
|
||||
if ((swizzle & ~0xfffu) != 0) {
|
||||
return false;
|
||||
@@ -32,28 +38,6 @@ namespace Libs::Graphics {
|
||||
static_cast<int>(image_format), static_cast<int>(view_format), swizzle);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline vk::Format BgraToRgbaSampledViewFormat(vk::Format image_format) noexcept {
|
||||
switch (image_format) {
|
||||
case vk::Format::eB8G8R8A8Unorm: return vk::Format::eR8G8B8A8Unorm;
|
||||
case vk::Format::eB8G8R8A8Srgb: return vk::Format::eR8G8B8A8Srgb;
|
||||
case vk::Format::eA2R10G10B10UnormPack32: return vk::Format::eA2B10G10R10UnormPack32;
|
||||
default: return vk::Format::eUndefined;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool IsBgraToRgbaSampledView(vk::Format image_format,
|
||||
vk::Format view_format) noexcept {
|
||||
switch (image_format) {
|
||||
case vk::Format::eB8G8R8A8Unorm:
|
||||
case vk::Format::eB8G8R8A8Srgb:
|
||||
return view_format == vk::Format::eR8G8B8A8Unorm ||
|
||||
view_format == vk::Format::eR8G8B8A8Srgb;
|
||||
case vk::Format::eA2R10G10B10UnormPack32:
|
||||
return view_format == vk::Format::eA2B10G10R10UnormPack32;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline vk::Format BgraSrgbStorageViewFormat(vk::Format image_format) noexcept {
|
||||
return image_format == vk::Format::eB8G8R8A8Srgb ? vk::Format::eR8G8B8A8Unorm
|
||||
: vk::Format::eUndefined;
|
||||
@@ -72,18 +56,8 @@ namespace Libs::Graphics {
|
||||
[[nodiscard]] inline bool IsSupportedSampledColorView(vk::Format image_format,
|
||||
vk::Format view_format,
|
||||
uint32_t swizzle) noexcept {
|
||||
if (!IsValidImageSwizzle(swizzle)) {
|
||||
return false;
|
||||
}
|
||||
if (image_format == view_format || IsRgba8SrgbReinterpretation(image_format, view_format)) {
|
||||
return true;
|
||||
}
|
||||
if ((IsRgba16UintFloatReinterpretation(image_format, view_format) ||
|
||||
IsRgba8UnormUintReinterpretation(image_format, view_format)) &&
|
||||
swizzle == DstSel(4, 5, 6, 7)) {
|
||||
return true;
|
||||
}
|
||||
return IsBgraToRgbaSampledView(image_format, view_format) && swizzle == DstSel(6, 5, 4, 7);
|
||||
return IsValidImageSwizzle(swizzle) &&
|
||||
ImageViewOps::FormatsCompatible(image_format, view_format);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline uint32_t
|
||||
@@ -165,12 +139,6 @@ ValidateStorageImageResource(const ShaderRecompiler::IR::ImageResource& resource
|
||||
}
|
||||
}
|
||||
|
||||
namespace ImageViewOps {
|
||||
|
||||
[[nodiscard]] vk::ImageAspectFlags DepthAspectMask(vk::Format format);
|
||||
[[nodiscard]] bool FormatsCompatible(vk::Format base, vk::Format view) noexcept;
|
||||
} // namespace ImageViewOps
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
|
||||
#endif // EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_IMAGEVIEW_H_
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include <vulkan/vulkan_format_traits.hpp>
|
||||
|
||||
namespace Libs::Graphics {
|
||||
|
||||
@@ -486,7 +487,7 @@ void TextureCache::CopyImage(ImageId destination_id, ImageId source_id) {
|
||||
const bool direct_copy =
|
||||
source.backing.format == destination.backing.format ||
|
||||
(!source_depth && !dest_depth &&
|
||||
ImageViewOps::FormatsCompatible(source.backing.format, destination.backing.format));
|
||||
vk::blockSize(source.backing.format) == vk::blockSize(destination.backing.format));
|
||||
if (direct_copy) {
|
||||
destination.CopyImage(source);
|
||||
} else if (!CopyD16(destination, source)) {
|
||||
|
||||
Reference in New Issue
Block a user