summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando S2021-12-18 07:09:58 +0100
committerGravatar GitHub2021-12-18 07:09:58 +0100
commit04b4f3b0510c2fe258bddf64552b60ead71d8db2 (patch)
treea93b6e36c1054fef1f67684d1cca09b090d30245 /src
parentMerge pull request #7570 from ameerj/favorites-expanded (diff)
parentvk_texture_cache: Add ABGR src format check for D24S8 conversions (diff)
downloadyuzu-04b4f3b0510c2fe258bddf64552b60ead71d8db2.tar.gz
yuzu-04b4f3b0510c2fe258bddf64552b60ead71d8db2.tar.xz
yuzu-04b4f3b0510c2fe258bddf64552b60ead71d8db2.zip
Merge pull request #7399 from ameerj/art-refactor
video_core: Refactoring post A.R.T. merge
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h2
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp50
-rw-r--r--src/video_core/renderer_vulkan/blit_image.cpp123
-rw-r--r--src/video_core/renderer_vulkan/blit_image.h30
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp37
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp34
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h8
-rw-r--r--src/video_core/texture_cache/texture_cache.h15
8 files changed, 147 insertions, 152 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 37d5e6a6b..dbf1df79c 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -92,7 +92,7 @@ public:
92 92
93 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); 93 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
94 94
95 void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled) { 95 void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
96 UNIMPLEMENTED(); 96 UNIMPLEMENTED();
97 } 97 }
98 98
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 28daacd82..f81c1b233 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -437,39 +437,29 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
437 437
438 glBindTextureUnit(0, fxaa_texture.handle); 438 glBindTextureUnit(0, fxaa_texture.handle);
439 } 439 }
440
441 // Set projection matrix
442 const std::array ortho_matrix = 440 const std::array ortho_matrix =
443 MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); 441 MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
444 442
445 GLuint fragment_handle; 443 const auto fragment_handle = [this]() {
446 const auto filter = Settings::values.scaling_filter.GetValue(); 444 switch (Settings::values.scaling_filter.GetValue()) {
447 switch (filter) { 445 case Settings::ScalingFilter::NearestNeighbor:
448 case Settings::ScalingFilter::NearestNeighbor: 446 case Settings::ScalingFilter::Bilinear:
449 fragment_handle = present_bilinear_fragment.handle; 447 return present_bilinear_fragment.handle;
450 break; 448 case Settings::ScalingFilter::Bicubic:
451 case Settings::ScalingFilter::Bilinear: 449 return present_bicubic_fragment.handle;
452 fragment_handle = present_bilinear_fragment.handle; 450 case Settings::ScalingFilter::Gaussian:
453 break; 451 return present_gaussian_fragment.handle;
454 case Settings::ScalingFilter::Bicubic: 452 case Settings::ScalingFilter::ScaleForce:
455 fragment_handle = present_bicubic_fragment.handle; 453 return present_scaleforce_fragment.handle;
456 break; 454 case Settings::ScalingFilter::Fsr:
457 case Settings::ScalingFilter::Gaussian: 455 LOG_WARNING(
458 fragment_handle = present_gaussian_fragment.handle; 456 Render_OpenGL,
459 break; 457 "FidelityFX Super Resolution is not supported in OpenGL, changing to ScaleForce");
460 case Settings::ScalingFilter::ScaleForce: 458 return present_scaleforce_fragment.handle;
461 fragment_handle = present_scaleforce_fragment.handle; 459 default:
462 break; 460 return present_bilinear_fragment.handle;
463 case Settings::ScalingFilter::Fsr: 461 }
464 LOG_WARNING( 462 }();
465 Render_OpenGL,
466 "FidelityFX FSR Super Sampling is not supported in OpenGL, changing to ScaleForce");
467 fragment_handle = present_scaleforce_fragment.handle;
468 break;
469 default:
470 fragment_handle = present_bilinear_fragment.handle;
471 break;
472 }
473 program_manager.BindPresentPrograms(present_vertex.handle, fragment_handle); 463 program_manager.BindPresentPrograms(present_vertex.handle, fragment_handle);
474 glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE, 464 glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE,
475 ortho_matrix.data()); 465 ortho_matrix.data());
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp
index 9a38b6b34..cd5995897 100644
--- a/src/video_core/renderer_vulkan/blit_image.cpp
+++ b/src/video_core/renderer_vulkan/blit_image.cpp
@@ -4,6 +4,7 @@
4 4
5#include <algorithm> 5#include <algorithm>
6 6
7#include "common/settings.h"
7#include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" 8#include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h"
8#include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" 9#include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h"
9#include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" 10#include "video_core/host_shaders/convert_depth_to_float_frag_spv.h"
@@ -335,6 +336,17 @@ void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Regi
335 cmdbuf.SetScissor(0, scissor); 336 cmdbuf.SetScissor(0, scissor);
336 cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); 337 cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants);
337} 338}
339
340VkExtent2D GetConversionExtent(const ImageView& src_image_view) {
341 const auto& resolution = Settings::values.resolution_info;
342 const bool is_rescaled = src_image_view.IsRescaled();
343 u32 width = src_image_view.size.width;
344 u32 height = src_image_view.size.height;
345 return VkExtent2D{
346 .width = is_rescaled ? resolution.ScaleUp(width) : width,
347 .height = is_rescaled ? resolution.ScaleUp(height) : height,
348 };
349}
338} // Anonymous namespace 350} // Anonymous namespace
339 351
340BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, 352BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_,
@@ -425,61 +437,52 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
425} 437}
426 438
427void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer, 439void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
428 const ImageView& src_image_view, u32 up_scale, 440 const ImageView& src_image_view) {
429 u32 down_shift) {
430 ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass()); 441 ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass());
431 Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); 442 Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view);
432} 443}
433 444
434void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, 445void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer,
435 const ImageView& src_image_view, u32 up_scale, 446 const ImageView& src_image_view) {
436 u32 down_shift) {
437 ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass()); 447 ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass());
438 Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); 448 Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view);
439} 449}
440 450
441void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer, 451void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer,
442 const ImageView& src_image_view, u32 up_scale, 452 const ImageView& src_image_view) {
443 u32 down_shift) {
444 ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass()); 453 ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass());
445 Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); 454 Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view);
446} 455}
447 456
448void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, 457void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
449 const ImageView& src_image_view, u32 up_scale, 458 const ImageView& src_image_view) {
450 u32 down_shift) {
451 ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass()); 459 ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass());
452 Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); 460 Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view);
453} 461}
454 462
455void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, 463void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
456 ImageView& src_image_view, u32 up_scale, u32 down_shift) { 464 const ImageView& src_image_view) {
457 ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), 465 ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
458 convert_abgr8_to_d24s8_frag, true); 466 convert_abgr8_to_d24s8_frag);
459 ConvertColor(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, 467 Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
460 down_shift);
461} 468}
462 469
463void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, 470void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
464 ImageView& src_image_view, u32 up_scale, u32 down_shift) { 471 ImageView& src_image_view) {
465 ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), 472 ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
466 convert_d24s8_to_abgr8_frag, false); 473 convert_d24s8_to_abgr8_frag);
467 ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view, up_scale, 474 ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view);
468 down_shift);
469} 475}
470 476
471void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, 477void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
472 const ImageView& src_image_view, u32 up_scale, u32 down_shift) { 478 const ImageView& src_image_view) {
473 const VkPipelineLayout layout = *one_texture_pipeline_layout; 479 const VkPipelineLayout layout = *one_texture_pipeline_layout;
474 const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); 480 const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
475 const VkSampler sampler = *nearest_sampler; 481 const VkSampler sampler = *nearest_sampler;
476 const VkExtent2D extent{ 482 const VkExtent2D extent = GetConversionExtent(src_image_view);
477 .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), 483
478 .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U),
479 };
480 scheduler.RequestRenderpass(dst_framebuffer); 484 scheduler.RequestRenderpass(dst_framebuffer);
481 scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift, 485 scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) {
482 this](vk::CommandBuffer cmdbuf) {
483 const VkOffset2D offset{ 486 const VkOffset2D offset{
484 .x = 0, 487 .x = 0,
485 .y = 0, 488 .y = 0,
@@ -563,18 +566,16 @@ void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_f
563} 566}
564 567
565void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, 568void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
566 ImageView& src_image_view, u32 up_scale, u32 down_shift) { 569 ImageView& src_image_view) {
567 const VkPipelineLayout layout = *two_textures_pipeline_layout; 570 const VkPipelineLayout layout = *two_textures_pipeline_layout;
568 const VkImageView src_depth_view = src_image_view.DepthView(); 571 const VkImageView src_depth_view = src_image_view.DepthView();
569 const VkImageView src_stencil_view = src_image_view.StencilView(); 572 const VkImageView src_stencil_view = src_image_view.StencilView();
570 const VkSampler sampler = *nearest_sampler; 573 const VkSampler sampler = *nearest_sampler;
571 const VkExtent2D extent{ 574 const VkExtent2D extent = GetConversionExtent(src_image_view);
572 .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), 575
573 .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U),
574 };
575 scheduler.RequestRenderpass(dst_framebuffer); 576 scheduler.RequestRenderpass(dst_framebuffer);
576 scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, up_scale, 577 scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent,
577 down_shift, this](vk::CommandBuffer cmdbuf) { 578 this](vk::CommandBuffer cmdbuf) {
578 const VkOffset2D offset{ 579 const VkOffset2D offset{
579 .x = 0, 580 .x = 0,
580 .y = 0, 581 .y = 0,
@@ -695,11 +696,14 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip
695 return *blit_depth_stencil_pipelines.back(); 696 return *blit_depth_stencil_pipelines.back();
696} 697}
697 698
698void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { 699void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass,
700 bool is_target_depth) {
699 if (pipeline) { 701 if (pipeline) {
700 return; 702 return;
701 } 703 }
702 const std::array stages = MakeStages(*full_screen_vert, *convert_depth_to_float_frag); 704 VkShaderModule frag_shader =
705 is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag;
706 const std::array stages = MakeStages(*full_screen_vert, frag_shader);
703 pipeline = device.GetLogical().CreateGraphicsPipeline({ 707 pipeline = device.GetLogical().CreateGraphicsPipeline({
704 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 708 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
705 .pNext = nullptr, 709 .pNext = nullptr,
@@ -712,8 +716,9 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend
712 .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, 716 .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
713 .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 717 .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
714 .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 718 .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
715 .pDepthStencilState = nullptr, 719 .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr,
716 .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, 720 .pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO
721 : &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
717 .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, 722 .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
718 .layout = *one_texture_pipeline_layout, 723 .layout = *one_texture_pipeline_layout,
719 .renderPass = renderpass, 724 .renderPass = renderpass,
@@ -723,37 +728,17 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend
723 }); 728 });
724} 729}
725 730
731void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
732 ConvertPipeline(pipeline, renderpass, false);
733}
734
726void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { 735void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
727 if (pipeline) { 736 ConvertPipeline(pipeline, renderpass, true);
728 return;
729 }
730 const std::array stages = MakeStages(*full_screen_vert, *convert_float_to_depth_frag);
731 pipeline = device.GetLogical().CreateGraphicsPipeline({
732 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
733 .pNext = nullptr,
734 .flags = 0,
735 .stageCount = static_cast<u32>(stages.size()),
736 .pStages = stages.data(),
737 .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
738 .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
739 .pTessellationState = nullptr,
740 .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
741 .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
742 .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
743 .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
744 .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO,
745 .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
746 .layout = *one_texture_pipeline_layout,
747 .renderPass = renderpass,
748 .subpass = 0,
749 .basePipelineHandle = VK_NULL_HANDLE,
750 .basePipelineIndex = 0,
751 });
752} 737}
753 738
754void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, 739void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
755 vk::ShaderModule& module, bool is_target_depth, 740 vk::ShaderModule& module, bool single_texture,
756 bool single_texture) { 741 bool is_target_depth) {
757 if (pipeline) { 742 if (pipeline) {
758 return; 743 return;
759 } 744 }
@@ -782,13 +767,13 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren
782} 767}
783 768
784void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, 769void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
785 vk::ShaderModule& module, bool single_texture) { 770 vk::ShaderModule& module) {
786 ConvertPipelineEx(pipeline, renderpass, module, false, single_texture); 771 ConvertPipelineEx(pipeline, renderpass, module, false, false);
787} 772}
788 773
789void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, 774void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
790 vk::ShaderModule& module, bool single_texture) { 775 vk::ShaderModule& module) {
791 ConvertPipelineEx(pipeline, renderpass, module, true, single_texture); 776 ConvertPipelineEx(pipeline, renderpass, module, true, true);
792} 777}
793 778
794} // namespace Vulkan 779} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h
index b1a717090..1d9f61a52 100644
--- a/src/video_core/renderer_vulkan/blit_image.h
+++ b/src/video_core/renderer_vulkan/blit_image.h
@@ -44,50 +44,46 @@ public:
44 const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, 44 const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter,
45 Tegra::Engines::Fermi2D::Operation operation); 45 Tegra::Engines::Fermi2D::Operation operation);
46 46
47 void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, 47 void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
48 u32 up_scale, u32 down_shift);
49 48
50 void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, 49 void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
51 u32 up_scale, u32 down_shift);
52 50
53 void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, 51 void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
54 u32 up_scale, u32 down_shift);
55 52
56 void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, 53 void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
57 u32 up_scale, u32 down_shift);
58 54
59 void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, 55 void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
60 u32 up_scale, u32 down_shift);
61 56
62 void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, 57 void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view);
63 u32 up_scale, u32 down_shift);
64 58
65private: 59private:
66 void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, 60 void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
67 const ImageView& src_image_view, u32 up_scale, u32 down_shift); 61 const ImageView& src_image_view);
68 62
69 void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, 63 void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
70 ImageView& src_image_view, u32 up_scale, u32 down_shift); 64 ImageView& src_image_view, u32 up_scale, u32 down_shift);
71 65
72 void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, 66 void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
73 ImageView& src_image_view, u32 up_scale, u32 down_shift); 67 ImageView& src_image_view);
74 68
75 [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); 69 [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key);
76 70
77 [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); 71 [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key);
78 72
73 void ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, bool is_target_depth);
74
79 void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); 75 void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass);
80 76
81 void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); 77 void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass);
82 78
83 void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, 79 void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
84 vk::ShaderModule& module, bool is_target_depth, bool single_texture); 80 vk::ShaderModule& module, bool single_texture, bool is_target_depth);
85 81
86 void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, 82 void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
87 vk::ShaderModule& module, bool single_texture); 83 vk::ShaderModule& module);
88 84
89 void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, 85 void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
90 vk::ShaderModule& module, bool single_texture); 86 vk::ShaderModule& module);
91 87
92 const Device& device; 88 const Device& device;
93 VKScheduler& scheduler; 89 VKScheduler& scheduler;
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 1e447e621..c71a1f44d 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -391,28 +391,23 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
391 .offset = {0, 0}, 391 .offset = {0, 0},
392 .extent = size, 392 .extent = size,
393 }; 393 };
394 const auto filter = Settings::values.scaling_filter.GetValue();
395 cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); 394 cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
396 switch (filter) { 395 auto graphics_pipeline = [this]() {
397 case Settings::ScalingFilter::NearestNeighbor: 396 switch (Settings::values.scaling_filter.GetValue()) {
398 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); 397 case Settings::ScalingFilter::NearestNeighbor:
399 break; 398 case Settings::ScalingFilter::Bilinear:
400 case Settings::ScalingFilter::Bilinear: 399 return *bilinear_pipeline;
401 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); 400 case Settings::ScalingFilter::Bicubic:
402 break; 401 return *bicubic_pipeline;
403 case Settings::ScalingFilter::Bicubic: 402 case Settings::ScalingFilter::Gaussian:
404 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bicubic_pipeline); 403 return *gaussian_pipeline;
405 break; 404 case Settings::ScalingFilter::ScaleForce:
406 case Settings::ScalingFilter::Gaussian: 405 return *scaleforce_pipeline;
407 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *gaussian_pipeline); 406 default:
408 break; 407 return *bilinear_pipeline;
409 case Settings::ScalingFilter::ScaleForce: 408 }
410 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *scaleforce_pipeline); 409 }();
411 break; 410 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline);
412 default:
413 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline);
414 break;
415 }
416 cmdbuf.SetViewport(0, viewport); 411 cmdbuf.SetViewport(0, viewport);
417 cmdbuf.SetScissor(0, scissor); 412 cmdbuf.SetScissor(0, scissor);
418 413
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 197cba8e3..1941170cb 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1057,37 +1057,37 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
1057 }); 1057 });
1058} 1058}
1059 1059
1060void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, 1060void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
1061 bool rescaled) {
1062 const u32 up_scale = rescaled ? resolution.up_scale : 1;
1063 const u32 down_shift = rescaled ? resolution.down_shift : 0;
1064 switch (dst_view.format) { 1061 switch (dst_view.format) {
1065 case PixelFormat::R16_UNORM: 1062 case PixelFormat::R16_UNORM:
1066 if (src_view.format == PixelFormat::D16_UNORM) { 1063 if (src_view.format == PixelFormat::D16_UNORM) {
1067 return blit_image_helper.ConvertD16ToR16(dst, src_view, up_scale, down_shift); 1064 return blit_image_helper.ConvertD16ToR16(dst, src_view);
1068 } 1065 }
1069 break; 1066 break;
1070 case PixelFormat::A8B8G8R8_UNORM: 1067 case PixelFormat::A8B8G8R8_UNORM:
1071 if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { 1068 if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) {
1072 return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift); 1069 return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view);
1073 } 1070 }
1074 break; 1071 break;
1075 case PixelFormat::R32_FLOAT: 1072 case PixelFormat::R32_FLOAT:
1076 if (src_view.format == PixelFormat::D32_FLOAT) { 1073 if (src_view.format == PixelFormat::D32_FLOAT) {
1077 return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift); 1074 return blit_image_helper.ConvertD32ToR32(dst, src_view);
1078 } 1075 }
1079 break; 1076 break;
1080 case PixelFormat::D16_UNORM: 1077 case PixelFormat::D16_UNORM:
1081 if (src_view.format == PixelFormat::R16_UNORM) { 1078 if (src_view.format == PixelFormat::R16_UNORM) {
1082 return blit_image_helper.ConvertR16ToD16(dst, src_view, up_scale, down_shift); 1079 return blit_image_helper.ConvertR16ToD16(dst, src_view);
1083 } 1080 }
1084 break; 1081 break;
1085 case PixelFormat::S8_UINT_D24_UNORM: 1082 case PixelFormat::S8_UINT_D24_UNORM:
1086 return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift); 1083 if (src_view.format == PixelFormat::A8B8G8R8_UNORM ||
1084 src_view.format == PixelFormat::B8G8R8A8_UNORM) {
1085 return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view);
1086 }
1087 break; 1087 break;
1088 case PixelFormat::D32_FLOAT: 1088 case PixelFormat::D32_FLOAT:
1089 if (src_view.format == PixelFormat::R32_FLOAT) { 1089 if (src_view.format == PixelFormat::R32_FLOAT) {
1090 return blit_image_helper.ConvertR32ToD32(dst, src_view, up_scale, down_shift); 1090 return blit_image_helper.ConvertR32ToD32(dst, src_view);
1091 } 1091 }
1092 break; 1092 break;
1093 default: 1093 default:
@@ -1329,6 +1329,10 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
1329 } 1329 }
1330} 1330}
1331 1331
1332bool Image::IsRescaled() const noexcept {
1333 return True(flags & ImageFlagBits::Rescaled);
1334}
1335
1332bool Image::ScaleUp(bool ignore) { 1336bool Image::ScaleUp(bool ignore) {
1333 if (True(flags & ImageFlagBits::Rescaled)) { 1337 if (True(flags & ImageFlagBits::Rescaled)) {
1334 return false; 1338 return false;
@@ -1469,7 +1473,8 @@ bool Image::BlitScaleHelper(bool scale_up) {
1469ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, 1473ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
1470 ImageId image_id_, Image& image) 1474 ImageId image_id_, Image& image)
1471 : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, 1475 : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device},
1472 image_handle{image.Handle()}, samples{ConvertSampleCount(image.info.num_samples)} { 1476 src_image{&image}, image_handle{image.Handle()},
1477 samples(ConvertSampleCount(image.info.num_samples)) {
1473 using Shader::TextureType; 1478 using Shader::TextureType;
1474 1479
1475 const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); 1480 const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info);
@@ -1607,6 +1612,13 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
1607 return *view; 1612 return *view;
1608} 1613}
1609 1614
1615bool ImageView::IsRescaled() const noexcept {
1616 if (!src_image) {
1617 return false;
1618 }
1619 return src_image->IsRescaled();
1620}
1621
1610vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { 1622vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) {
1611 return device->GetLogical().CreateImageView({ 1623 return device->GetLogical().CreateImageView({
1612 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1624 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 753e3e8a1..c592f2666 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -65,7 +65,7 @@ public:
65 65
66 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); 66 void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
67 67
68 void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled); 68 void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view);
69 69
70 bool CanAccelerateImageUpload(Image&) const noexcept { 70 bool CanAccelerateImageUpload(Image&) const noexcept {
71 return false; 71 return false;
@@ -139,6 +139,8 @@ public:
139 return std::exchange(initialized, true); 139 return std::exchange(initialized, true);
140 } 140 }
141 141
142 bool IsRescaled() const noexcept;
143
142 bool ScaleUp(bool ignore = false); 144 bool ScaleUp(bool ignore = false);
143 145
144 bool ScaleDown(bool ignore = false); 146 bool ScaleDown(bool ignore = false);
@@ -189,6 +191,8 @@ public:
189 [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, 191 [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type,
190 Shader::ImageFormat image_format); 192 Shader::ImageFormat image_format);
191 193
194 [[nodiscard]] bool IsRescaled() const noexcept;
195
192 [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { 196 [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept {
193 return *image_views[static_cast<size_t>(texture_type)]; 197 return *image_views[static_cast<size_t>(texture_type)];
194 } 198 }
@@ -222,6 +226,8 @@ private:
222 [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); 226 [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask);
223 227
224 const Device* device = nullptr; 228 const Device* device = nullptr;
229 const Image* src_image{};
230
225 std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; 231 std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views;
226 std::unique_ptr<StorageViews> storage_views; 232 std::unique_ptr<StorageViews> storage_views;
227 vk::ImageView depth_view; 233 vk::ImageView depth_view;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 5aaeb16ca..2e19fced2 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1855,9 +1855,20 @@ void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<Imag
1855 .height = std::min(dst_view.size.height, src_view.size.height), 1855 .height = std::min(dst_view.size.height, src_view.size.height),
1856 .depth = std::min(dst_view.size.depth, src_view.size.depth), 1856 .depth = std::min(dst_view.size.depth, src_view.size.depth),
1857 }; 1857 };
1858 UNIMPLEMENTED_IF(copy.extent != expected_size); 1858 const Extent3D scaled_extent = [is_rescaled, expected_size]() {
1859 if (!is_rescaled) {
1860 return expected_size;
1861 }
1862 const auto& resolution = Settings::values.resolution_info;
1863 return Extent3D{
1864 .width = resolution.ScaleUp(expected_size.width),
1865 .height = resolution.ScaleUp(expected_size.height),
1866 .depth = expected_size.depth,
1867 };
1868 }();
1869 UNIMPLEMENTED_IF(copy.extent != scaled_extent);
1859 1870
1860 runtime.ConvertImage(dst_framebuffer, dst_view, src_view, is_rescaled); 1871 runtime.ConvertImage(dst_framebuffer, dst_view, src_view);
1861 } 1872 }
1862} 1873}
1863 1874