aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2025-07-26 05:58:04 +0200
committercrueter <crueter@eden-emu.dev>2025-07-26 05:58:04 +0200
commitc7c2ed7b46b82ce1fe85a45b32a8fe9de72d3abb (patch)
treeded87b0794aed8905ed1021fe387c83a8c734baf /src
parentac675c52966f656dd308346b982393199d32ead3 (diff)
[vk] copy incompatible alpha patch 1.5(2) (#123)
Avoid copy size incompatible textures and reinterpret it instead. Uses existing logic to properly re-interpret to a compatible texture. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/123 Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp13
-rw-r--r--src/video_core/surface.cpp32
-rw-r--r--src/video_core/surface.h2
4 files changed, 55 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 33b90a1ec9..92992c1ee7 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -518,6 +518,14 @@ void RasterizerVulkan::DispatchCompute() {
}
const std::array<u32, 3> dim{qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z};
scheduler.RequestOutsideRenderPassOperationContext();
+ static constexpr VkMemoryBarrier READ_BARRIER{
+ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+ .pNext = nullptr,
+ .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
+ .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
+ };
+ scheduler.Record([](vk::CommandBuffer cmdbuf) { cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
+ 0, READ_BARRIER); });
scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); });
}
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 022a9ae572..6272d6231a 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -38,6 +38,7 @@ using VideoCommon::ImageInfo;
using VideoCommon::ImageType;
using VideoCommon::SubresourceRange;
using VideoCore::Surface::BytesPerBlock;
+using VideoCore::Surface::HasAlpha;
using VideoCore::Surface::IsPixelFormatASTC;
using VideoCore::Surface::IsPixelFormatInteger;
using VideoCore::Surface::SurfaceType;
@@ -1323,6 +1324,7 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im
case PixelFormat::D32_FLOAT_S8_UINT:
case PixelFormat::Invalid:
default:
+ LOG_ERROR(Render_Vulkan, "Unimplemented texture conversion from {} to {} format type", src_view.format, dst_view.format);
break;
}
}
@@ -1364,6 +1366,17 @@ bool TextureCacheRuntime::IsFormatScalable(PixelFormat format) {
void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
std::span<const VideoCommon::ImageCopy> copies) {
+ // As per the size-compatible formats section of vulkan, copy manually via ReinterpretImage
+ // these images that aren't size-compatible
+ if (HasAlpha(src.info.format) != HasAlpha(dst.info.format) ||
+ BytesPerBlock(src.info.format) != BytesPerBlock(dst.info.format)) {
+ auto oneCopy = VideoCommon::ImageCopy{
+ .src_offset = VideoCommon::Offset3D(0, 0, 0),
+ .dst_offset = VideoCommon::Offset3D(0, 0, 0),
+ .extent = dst.info.size
+ };
+ return ReinterpretImage(dst, src, std::span{&oneCopy, 1});
+ }
boost::container::small_vector<VkImageCopy, 16> vk_copies(copies.size());
const VkImageAspectFlags aspect_mask = dst.AspectMask();
ASSERT(aspect_mask == src.AspectMask());
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index 9055b1b929..c791bfa4e4 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -237,6 +237,38 @@ SurfaceType GetFormatType(PixelFormat pixel_format) {
return SurfaceType::Invalid;
}
+bool HasAlpha(PixelFormat pixel_format) {
+ switch (pixel_format) {
+ case PixelFormat::A8B8G8R8_UNORM:
+ case PixelFormat::A8B8G8R8_SNORM:
+ case PixelFormat::A8B8G8R8_SINT:
+ case PixelFormat::A8B8G8R8_UINT:
+ case PixelFormat::A1R5G5B5_UNORM:
+ case PixelFormat::A2B10G10R10_UNORM:
+ case PixelFormat::A2B10G10R10_UINT:
+ case PixelFormat::A2R10G10B10_UNORM:
+ case PixelFormat::A1B5G5R5_UNORM:
+ case PixelFormat::A5B5G5R1_UNORM:
+ case PixelFormat::R16G16B16A16_FLOAT:
+ case PixelFormat::R16G16B16A16_UNORM:
+ case PixelFormat::R16G16B16A16_SNORM:
+ case PixelFormat::R16G16B16A16_SINT:
+ case PixelFormat::R16G16B16A16_UINT:
+ case PixelFormat::R32G32B32A32_UINT:
+ case PixelFormat::BC1_RGBA_UNORM:
+ case PixelFormat::B8G8R8A8_UNORM:
+ case PixelFormat::R32G32B32A32_FLOAT:
+ case PixelFormat::R32G32B32A32_SINT:
+ case PixelFormat::A8B8G8R8_SRGB:
+ case PixelFormat::B8G8R8A8_SRGB:
+ case PixelFormat::BC1_RGBA_SRGB:
+ case PixelFormat::A4B4G4R4_UNORM:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool IsPixelFormatASTC(PixelFormat format) {
switch (format) {
case PixelFormat::ASTC_2D_4X4_UNORM:
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index ec9cd2fbf0..4ccb24f27d 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -503,6 +503,8 @@ PixelFormat PixelFormatFromGPUPixelFormat(Service::android::PixelFormat format);
SurfaceType GetFormatType(PixelFormat pixel_format);
+bool HasAlpha(PixelFormat pixel_format);
+
bool IsPixelFormatASTC(PixelFormat format);
bool IsPixelFormatBCn(PixelFormat format);