diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 50 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.cpp | 123 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.h | 30 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 37 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 34 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 8 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 15 |
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 | |||
| 340 | VkExtent2D 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 | ||
| 340 | BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, | 352 | BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, |
| @@ -425,61 +437,52 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, | |||
| 425 | } | 437 | } |
| 426 | 438 | ||
| 427 | void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer, | 439 | void 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 | ||
| 434 | void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, | 445 | void 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 | ||
| 441 | void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer, | 451 | void 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 | ||
| 448 | void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, | 457 | void 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 | ||
| 455 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, | 463 | void 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 | ||
| 463 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, | 470 | void 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 | ||
| 471 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 477 | void 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 | ||
| 565 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 568 | void 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 | ||
| 698 | void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | 699 | void 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 | ||
| 731 | void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | ||
| 732 | ConvertPipeline(pipeline, renderpass, false); | ||
| 733 | } | ||
| 734 | |||
| 726 | void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | 735 | void 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 | ||
| 754 | void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 739 | void 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 | ||
| 784 | void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 769 | void 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 | ||
| 789 | void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 774 | void 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 | ||
| 65 | private: | 59 | private: |
| 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 | ||
| 1060 | void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, | 1060 | void 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 | ||
| 1332 | bool Image::IsRescaled() const noexcept { | ||
| 1333 | return True(flags & ImageFlagBits::Rescaled); | ||
| 1334 | } | ||
| 1335 | |||
| 1332 | bool Image::ScaleUp(bool ignore) { | 1336 | bool 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) { | |||
| 1469 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | 1473 | ImageView::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 | ||
| 1615 | bool ImageView::IsRescaled() const noexcept { | ||
| 1616 | if (!src_image) { | ||
| 1617 | return false; | ||
| 1618 | } | ||
| 1619 | return src_image->IsRescaled(); | ||
| 1620 | } | ||
| 1621 | |||
| 1610 | vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { | 1622 | vk::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 | ||