aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan/renderer_vulkan.cpp
diff options
context:
space:
mode:
authorMrPurple666 <antoniosacramento666usa@gmail.com>2025-04-12 03:20:42 -0300
committerMrPurple666 <antoniosacramento666usa@gmail.com>2025-04-12 22:54:32 -0300
commit2a793d610d2a245fec7d3e4a6a100e0b26418cc1 (patch)
treefbce826fe0feff2c475cbcafec8f6be628d02d3a /src/video_core/renderer_vulkan/renderer_vulkan.cpp
parent38737f26e51bba30d96772b00df6a34d1a28ab7b (diff)
RenderVulkan Experiments: DO-NOT-MERGE: Introduce functionality to frame interpolation
The functionality acts much more like a real-time downscale since the FSR1 used by Yuzu is not compatible with a real interpolation and is just upscale and downscale.
Diffstat (limited to 'src/video_core/renderer_vulkan/renderer_vulkan.cpp')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp65
1 files changed, 61 insertions, 4 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 6948682ef1..d5058fdd89 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -172,13 +172,70 @@ class BooleanSetting {
}
void RendererVulkan::InterpolateFrames(Frame* prev_frame, Frame* interpolated_frame) {
- if (prev_frame && interpolated_frame) {
- *interpolated_frame = std::move(*prev_frame); // Use move assignment to avoid copy issues
+ if (!prev_frame || !interpolated_frame || !prev_frame->image || !interpolated_frame->image) {
+ return;
+ }
+
+ const auto& framebuffer_layout = render_window.GetFramebufferLayout();
+ // Fixed aggressive downscale (50%)
+ VkExtent2D dst_extent{
+ .width = framebuffer_layout.width / 2,
+ .height = framebuffer_layout.height / 2
+ };
+
+ // Check if we need to recreate the destination frame
+ bool needs_recreation = true;
+ if (interpolated_frame->image_view) {
+ // Get image extent from framebuffer layout since we can't query it directly
+ needs_recreation = (framebuffer_layout.width / 2 != dst_extent.width) ||
+ (framebuffer_layout.height / 2 != dst_extent.height);
+ }
- // TODO: Implement actual interpolation logic here
+ if (needs_recreation) {
+ interpolated_frame->image = CreateWrappedImage(memory_allocator, dst_extent, swapchain.GetImageViewFormat());
+ interpolated_frame->image_view = CreateWrappedImageView(device, interpolated_frame->image, swapchain.GetImageViewFormat());
+ interpolated_frame->framebuffer = blit_swapchain.CreateFramebuffer(
+ Layout::FramebufferLayout{dst_extent.width, dst_extent.height},
+ *interpolated_frame->image_view,
+ swapchain.GetImageViewFormat());
}
+
+ scheduler.RequestOutsideRenderPassOperationContext();
+ scheduler.Record([&](vk::CommandBuffer cmdbuf) {
+ // Transition images to transfer layouts
+ TransitionImageLayout(cmdbuf, *prev_frame->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
+ TransitionImageLayout(cmdbuf, *interpolated_frame->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+
+ // Perform the downscale blit
+ VkImageBlit blit_region{};
+ blit_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
+ blit_region.srcOffsets[0] = {0, 0, 0};
+ blit_region.srcOffsets[1] = {
+ static_cast<int32_t>(framebuffer_layout.width),
+ static_cast<int32_t>(framebuffer_layout.height),
+ 1
+ };
+ blit_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
+ blit_region.dstOffsets[0] = {0, 0, 0};
+ blit_region.dstOffsets[1] = {
+ static_cast<int32_t>(dst_extent.width),
+ static_cast<int32_t>(dst_extent.height),
+ 1
+ };
+
+ // Using the wrapper's BlitImage with proper parameters
+ cmdbuf.BlitImage(
+ *prev_frame->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ *interpolated_frame->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ blit_region, VK_FILTER_LINEAR
+ );
+
+ // Transition back to general layout
+ TransitionImageLayout(cmdbuf, *prev_frame->image, VK_IMAGE_LAYOUT_GENERAL);
+ TransitionImageLayout(cmdbuf, *interpolated_frame->image, VK_IMAGE_LAYOUT_GENERAL);
+ });
}
- #endif
+#endif
void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebuffers) {
#ifdef __ANDROID__