From c2234b4ae2582dd42d5221747be250ec94edaba4 Mon Sep 17 00:00:00 2001 From: Bixthefin <114880614+Bixthefin@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:08:30 +0100 Subject: [PATCH] [texture_cache] Implement alpha copies and put barrier in compute stages --- .gdbinit | 0 src/video_core/host_shaders/CMakeLists.txt | 4 ++ .../host_shaders/convert_abgr8_to_r8.frag | 19 +++++ .../convert_b10gr11f_to_abgr8.frag | 19 +++++ .../host_shaders/convert_bgra8_to_s8d24.frag | 17 +++++ .../host_shaders/convert_r8_to_abgr8.frag | 20 ++++++ src/video_core/renderer_vulkan/blit_image.cpp | 72 +++++++++++++++++-- src/video_core/renderer_vulkan/blit_image.h | 18 +++++ .../renderer_vulkan/vk_rasterizer.cpp | 8 +++ .../renderer_vulkan/vk_texture_cache.cpp | 24 ++++++- src/video_core/surface.cpp | 32 +++++++++ src/video_core/surface.h | 2 + src/video_core/texture_cache/texture_cache.h | 7 +- 13 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 .gdbinit create mode 100644 src/video_core/host_shaders/convert_abgr8_to_r8.frag create mode 100644 src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag create mode 100644 src/video_core/host_shaders/convert_bgra8_to_s8d24.frag create mode 100644 src/video_core/host_shaders/convert_r8_to_abgr8.frag diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 688e10d2e4..1849c35b21 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -21,8 +21,12 @@ set(SHADER_FILES convert_abgr8_srgb_to_d24s8.frag convert_abgr8_to_d24s8.frag convert_abgr8_to_d32f.frag + convert_r8_to_abgr8.frag + convert_abgr8_to_r8.frag convert_d32f_to_abgr8.frag convert_d24s8_to_abgr8.frag + convert_bgra8_to_s8d24.frag + convert_b10gr11f_to_abgr8.frag convert_depth_to_float.frag convert_float_to_depth.frag convert_msaa_to_non_msaa.comp diff --git a/src/video_core/host_shaders/convert_abgr8_to_r8.frag b/src/video_core/host_shaders/convert_abgr8_to_r8.frag new file mode 100644 index 0000000000..f76a42db9c --- /dev/null +++ b/src/video_core/host_shaders/convert_abgr8_to_r8.frag @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout(binding = 0) uniform sampler2D tex; + +layout(location = 0) out float color; + +layout(push_constant) uniform PushConstants { + uniform vec2 tex_scale; + uniform vec2 tex_offset; +}; + +void main() { + vec2 coord = gl_FragCoord.xy / tex_scale * textureSize(tex, 0); + vec4 fetch = texelFetch(tex, ivec2(coord), 0); + color = fetch.r; +} diff --git a/src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag b/src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag new file mode 100644 index 0000000000..f3ac16da20 --- /dev/null +++ b/src/video_core/host_shaders/convert_b10gr11f_to_abgr8.frag @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout(binding = 0) uniform sampler2D tex; + +layout(push_constant) uniform PushConstants { + uniform vec2 tex_scale; + uniform vec2 tex_offset; +}; + +layout(location = 0) out vec4 color; + +void main() { + vec2 coord = gl_FragCoord.xy / tex_scale * textureSize(tex, 0); + vec4 fetch = texelFetch(tex, ivec2(coord), 0); + color = vec4(fetch.rgb, 1.0); +} \ No newline at end of file diff --git a/src/video_core/host_shaders/convert_bgra8_to_s8d24.frag b/src/video_core/host_shaders/convert_bgra8_to_s8d24.frag new file mode 100644 index 0000000000..8aae0481a4 --- /dev/null +++ b/src/video_core/host_shaders/convert_bgra8_to_s8d24.frag @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 +#extension GL_ARB_shader_stencil_export : require + +layout(binding = 0) uniform sampler2D color_texture; + +void main() { + ivec2 coord = ivec2(gl_FragCoord.xy); + uvec4 color = uvec4(texelFetch(color_texture, coord, 0).bgra * (exp2(8) - 1.0f)); + uvec4 bytes = color << uvec4(24, 16, 8, 0); + uint depth_stencil_unorm = bytes.x | bytes.y | bytes.z | bytes.w; + + gl_FragDepth = float(depth_stencil_unorm >> 24) / (exp2(24.0) - 1.0f); + gl_FragStencilRefARB = int(depth_stencil_unorm & 0x00FFFFFFu); +} diff --git a/src/video_core/host_shaders/convert_r8_to_abgr8.frag b/src/video_core/host_shaders/convert_r8_to_abgr8.frag new file mode 100644 index 0000000000..ad96ea36ed --- /dev/null +++ b/src/video_core/host_shaders/convert_r8_to_abgr8.frag @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout(binding = 0) uniform sampler2D tex; + +layout(push_constant) uniform PushConstants { + uniform vec2 tex_scale; + uniform vec2 tex_offset; +}; + +layout(location = 0) out vec4 color; + +void main() { + vec2 coord = gl_FragCoord.xy / tex_scale * textureSize(tex, 0); + float red = texelFetch(tex, ivec2(coord), 0).r; + color = vec4(1.0, red, red, red); +} + diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index f2bf5a3228..a36198eb5b 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp @@ -11,8 +11,11 @@ #include "video_core/host_shaders/convert_abgr8_to_d32f_frag_spv.h" #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_d32f_to_abgr8_frag_spv.h" +#include "video_core/host_shaders/convert_r8_to_abgr8_frag_spv.h" #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" +#include "video_core/host_shaders/convert_b10gr11f_to_abgr8_frag_spv.h" +#include "video_core/host_shaders/convert_bgra8_to_s8d24_frag_spv.h" #include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h" #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" @@ -29,6 +32,7 @@ #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/host_shaders/convert_abgr8_srgb_to_d24s8_frag_spv.h" +#include "video_core/host_shaders/convert_abgr8_to_r8_frag_spv.h" #include "video_core/host_shaders/convert_rgba8_to_bgra8_frag_spv.h" #include "video_core/host_shaders/convert_yuv420_to_rgb_comp_spv.h" #include "video_core/host_shaders/convert_rgb_to_yuv420_comp_spv.h" @@ -385,6 +389,17 @@ VkExtent2D GetConversionExtent(const ImageView& src_image_view) { }; } +VkExtent2D GetConversionExtent(const Framebuffer* framebuffer) { + const auto& resolution = Settings::values.resolution_info; + const bool is_rescaled = framebuffer->IsRescaled(); + u32 width = framebuffer->RenderArea().width; + u32 height = framebuffer->RenderArea().height; + return VkExtent2D{ + .width = is_rescaled ? resolution.ScaleUp(width) : width, + .height = is_rescaled ? resolution.ScaleUp(height) : height, + }; +} + void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayout target_layout, VkImageLayout source_layout = VK_IMAGE_LAYOUT_GENERAL) { constexpr VkFlags flags{VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | @@ -442,13 +457,17 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, descriptor_pool.Allocator(*one_texture_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<1>)}, two_textures_descriptor_allocator{ descriptor_pool.Allocator(*two_textures_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<2>)}, + push_constant_range({ + PUSH_CONSTANT_RANGE, + PUSH_CONSTANT_RANGE + }), one_texture_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo( one_texture_set_layout.address(), - PUSH_CONSTANT_RANGE))), + push_constant_range))), two_textures_pipeline_layout( device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo( two_textures_set_layout.address(), - PUSH_CONSTANT_RANGE))), + push_constant_range))), clear_color_pipeline_layout(device.GetLogical().CreatePipelineLayout(PipelineLayoutCreateInfo( nullptr, PUSH_CONSTANT_RANGE))), full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)), @@ -461,10 +480,14 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), convert_abgr8_to_d32f_frag(BuildShader(device, CONVERT_ABGR8_TO_D32F_FRAG_SPV)), + convert_abgr8_to_r8_frag(BuildShader(device, CONVERT_ABGR8_TO_R8_FRAG_SPV)), + convert_r8_to_abgr8_frag(BuildShader(device, CONVERT_R8_TO_ABGR8_FRAG_SPV)), convert_d32f_to_abgr8_frag(BuildShader(device, CONVERT_D32F_TO_ABGR8_FRAG_SPV)), convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)), convert_abgr8_srgb_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_SRGB_TO_D24S8_FRAG_SPV)), + convert_b10gr11f_to_abgr8_frag(BuildShader(device, CONVERT_B10GR11F_TO_ABGR8_FRAG_SPV)), + convert_bgra8_to_s8d24_frag(BuildShader(device, CONVERT_BGRA8_TO_S8D24_FRAG_SPV)), convert_rgba_to_bgra_frag(BuildShader(device, CONVERT_RGBA8_TO_BGRA8_FRAG_SPV)), convert_yuv420_to_rgb_comp(BuildShader(device, CONVERT_YUV420_TO_RGB_COMP_SPV)), convert_rgb_to_yuv420_comp(BuildShader(device, CONVERT_RGB_TO_YUV420_COMP_SPV)), @@ -588,6 +611,20 @@ void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view); } +void BlitImageHelper::ConvertR8ToABGR8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineColorTargetEx(convert_r8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), + convert_r8_to_abgr8_frag); + Convert(*convert_r8_to_abgr8_pipeline, dst_framebuffer, src_image_view); +} + +void BlitImageHelper::ConvertABGR8ToR8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineColorTargetEx(convert_abgr8_to_r8_pipeline, dst_framebuffer->RenderPass(), + convert_abgr8_to_r8_frag); + Convert(*convert_abgr8_to_r8_pipeline, dst_framebuffer, src_image_view); +} + void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view) { ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), @@ -631,6 +668,21 @@ void BlitImageHelper::ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer Convert(*convert_abgr8_srgb_to_d24s8_pipeline, dst_framebuffer, src_image_view); } +void BlitImageHelper::ConvertB10GR11ToABGR8(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineDepthTargetEx(convert_b10gr11f_to_abgr8_pipeline, + dst_framebuffer->RenderPass(), + convert_b10gr11f_to_abgr8_frag); + Convert(*convert_b10gr11f_to_abgr8_pipeline, dst_framebuffer, src_image_view); +} + +void BlitImageHelper::ConvertBGRA8ToS8D24(const Framebuffer* dst_framebuffer, + const ImageView& src_image_view) { + ConvertPipelineDepthTargetEx(convert_bgra8_to_s8d24_pipeline, dst_framebuffer->RenderPass(), + convert_bgra8_to_s8d24_frag); + Convert(*convert_bgra8_to_s8d24_pipeline, dst_framebuffer, src_image_view); +} + void BlitImageHelper::ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask, const std::array& clear_color, const Region2D& dst_region) { @@ -684,10 +736,10 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb const VkPipelineLayout layout = *one_texture_pipeline_layout; const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); const VkSampler sampler = *nearest_sampler; - const VkExtent2D extent = GetConversionExtent(src_image_view); + const VkExtent2D extent = GetConversionExtent(dst_framebuffer); scheduler.RequestRenderpass(dst_framebuffer); - scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) { + scheduler.Record([pipeline, layout, sampler, src_view, extent, this, dst_framebuffer](vk::CommandBuffer cmdbuf) { const VkOffset2D offset{ .x = 0, .y = 0, @@ -704,9 +756,16 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb .offset = offset, .extent = extent, }; - const PushConstants push_constants{ + /*const PushConstants push_constants_vertex{ .tex_scale = {viewport.width, viewport.height}, .tex_offset = {0.0f, 0.0f}, + };*/ + const PushConstants push_constants_frag{ + .tex_scale = { + static_cast(dst_framebuffer->RenderArea().width), + static_cast(dst_framebuffer->RenderArea().height) + }, + .tex_offset = {0.0f, 0.0f}, }; const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); @@ -717,7 +776,8 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb nullptr); cmdbuf.SetViewport(0, viewport); cmdbuf.SetScissor(0, scissor); - cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); + cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants_frag); + cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, push_constants_frag); cmdbuf.Draw(3, 1, 0, 0); }); scheduler.InvalidateState(); diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 3d400be6a9..bf3bed9ed4 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h @@ -65,6 +65,10 @@ public: void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ConvertR8ToABGR8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + + void ConvertABGR8ToR8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); void ConvertABGR8SRGBToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); @@ -77,6 +81,10 @@ public: void ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); + void ConvertB10GR11ToABGR8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + + void ConvertBGRA8ToS8D24(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); + void ClearColor(const Framebuffer* dst_framebuffer, u8 color_mask, const std::array& clear_color, const Region2D& dst_region); @@ -131,6 +139,7 @@ private: vk::DescriptorSetLayout two_textures_set_layout; DescriptorAllocator one_texture_descriptor_allocator; DescriptorAllocator two_textures_descriptor_allocator; + std::vector push_constant_range; vk::PipelineLayout one_texture_pipeline_layout; vk::PipelineLayout two_textures_pipeline_layout; vk::PipelineLayout clear_color_pipeline_layout; @@ -144,10 +153,15 @@ private: vk::ShaderModule convert_float_to_depth_frag; vk::ShaderModule convert_abgr8_to_d24s8_frag; vk::ShaderModule convert_abgr8_to_d32f_frag; + vk::ShaderModule convert_abgr8_to_r8_frag; + vk::ShaderModule convert_r8_to_abgr8_frag; vk::ShaderModule convert_d32f_to_abgr8_frag; vk::ShaderModule convert_d24s8_to_abgr8_frag; vk::ShaderModule convert_s8d24_to_abgr8_frag; + vk::ShaderModule convert_s8d24_to_bgra8_frag; vk::ShaderModule convert_abgr8_srgb_to_d24s8_frag; + vk::ShaderModule convert_b10gr11f_to_abgr8_frag; + vk::ShaderModule convert_bgra8_to_s8d24_frag; vk::ShaderModule convert_rgba_to_bgra_frag; vk::ShaderModule convert_yuv420_to_rgb_comp; vk::ShaderModule convert_rgb_to_yuv420_comp; @@ -176,7 +190,11 @@ private: vk::Pipeline convert_d32f_to_abgr8_pipeline; vk::Pipeline convert_d24s8_to_abgr8_pipeline; vk::Pipeline convert_s8d24_to_abgr8_pipeline; + vk::Pipeline convert_r8_to_abgr8_pipeline; + vk::Pipeline convert_abgr8_to_r8_pipeline; vk::Pipeline convert_abgr8_srgb_to_d24s8_pipeline; + vk::Pipeline convert_bgra8_to_s8d24_pipeline; + vk::Pipeline convert_b10gr11f_to_abgr8_pipeline; vk::Pipeline convert_rgba_to_bgra_pipeline; vk::Pipeline convert_yuv420_to_rgb_pipeline; vk::Pipeline convert_rgb_to_yuv420_pipeline; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 0243693049..51e45d0809 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 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..e3bf2ddd46 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1219,8 +1219,27 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view); } break; - + case PixelFormat::R8_UNORM: + if (src_view.format == PixelFormat::A8B8G8R8_UNORM) { + return blit_image_helper.ConvertABGR8ToR8(dst, src_view); + } + break; case PixelFormat::A8B8G8R8_UNORM: + if (src_view.format == PixelFormat::R8_UNORM) { + return blit_image_helper.ConvertR8ToABGR8(dst, src_view); + } + if (src_view.format == PixelFormat::B10G11R11_FLOAT) { + return blit_image_helper.ConvertB10GR11ToABGR8(dst, src_view); + } + if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { + return blit_image_helper.ConvertS8D24ToABGR8(dst, src_view); + } + break; + case PixelFormat::S8_UINT_D24_UNORM: + if (src_view.format == PixelFormat::B8G8R8A8_UNORM) { + return blit_image_helper.ConvertBGRA8ToS8D24(dst, src_view); + } + break; case PixelFormat::A8B8G8R8_SNORM: case PixelFormat::A8B8G8R8_SINT: case PixelFormat::A8B8G8R8_UINT: @@ -1232,7 +1251,6 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im case PixelFormat::A2R10G10B10_UNORM: case PixelFormat::A1B5G5R5_UNORM: case PixelFormat::A5B5G5R1_UNORM: - case PixelFormat::R8_UNORM: case PixelFormat::R8_SNORM: case PixelFormat::R8_SINT: case PixelFormat::R8_UINT: @@ -1319,12 +1337,12 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im case PixelFormat::D16_UNORM: case PixelFormat::X8_D24_UNORM: case PixelFormat::S8_UINT: - case PixelFormat::S8_UINT_D24_UNORM: case PixelFormat::D32_FLOAT_S8_UINT: case PixelFormat::Invalid: default: break; } + LOG_WARNING(Render_Vulkan, "Unimplemented texture conversion from {} to {} format type", src_view.format, dst_view.format); } VkFormat TextureCacheRuntime::GetSupportedFormat(VkFormat requested_format, 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); diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6c733fe902..f1693948ae 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -26,6 +26,7 @@ namespace VideoCommon { using Tegra::Texture::TICEntry; using Tegra::Texture::TSCEntry; using VideoCore::Surface::GetFormatType; +using VideoCore::Surface::HasAlpha; using VideoCore::Surface::PixelFormat; using VideoCore::Surface::SurfaceType; using namespace Common::Literals; @@ -2398,7 +2399,7 @@ void TextureCache

::CopyImage(ImageId dst_id, ImageId src_id, std::vector::CopyImage(ImageId dst_id, ImageId src_id, std::vector