From 124d9b57d663d8379f1477ae02a8f47da7c8cbe6 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 6 Dec 2018 11:38:30 +0100 Subject: [PATCH] Vulkan: Fix blue/red flip when using HW rendered cores with history. Was using frontend format of BGRA8 when core was RGBA8, with blind vkCmdCopyImage. Fix is to use the same format as core is pushing to history buffer. --- gfx/drivers/vulkan.c | 4 ++++ gfx/drivers_shader/shader_vulkan.cpp | 16 ++++++++++------ gfx/drivers_shader/shader_vulkan.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 140dbff7b7..09769b1b0a 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -1742,6 +1742,9 @@ static bool vulkan_frame(void *data, const void *frame, input.view = vk->hw.image->image_view; input.layout = vk->hw.image->image_layout; + /* The format can change on a whim. */ + input.format = vk->hw.image->create_info.format; + if (frame) { input.width = frame_width; @@ -1769,6 +1772,7 @@ static bool vulkan_frame(void *data, const void *frame, input.layout = tex->layout; input.width = tex->width; input.height = tex->height; + input.format = VK_FORMAT_UNDEFINED; /* It's already configured. */ } vulkan_filter_chain_set_input_texture((vulkan_filter_chain_t*)vk->filter_chain, &input); diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 57559d3258..cc587083d4 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -210,9 +210,10 @@ class Framebuffer Framebuffer(Framebuffer&&) = delete; void operator=(Framebuffer&&) = delete; - void set_size(DeferredDisposer &disposer, const Size2D &size); + void set_size(DeferredDisposer &disposer, const Size2D &size, VkFormat format = VK_FORMAT_UNDEFINED); const Size2D &get_size() const { return size; } + VkFormat get_format() const { return format; } VkImage get_image() const { return image; } VkImageView get_view() const { return view; } VkFramebuffer get_framebuffer() const { return framebuffer; } @@ -1009,9 +1010,10 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu swap(back, tmp); if (input_texture.width != tmp->get_size().width || - input_texture.height != tmp->get_size().height) + input_texture.height != tmp->get_size().height || + (input_texture.format != VK_FORMAT_UNDEFINED && input_texture.format != tmp->get_format())) { - tmp->set_size(disposer, { input_texture.width, input_texture.height }); + tmp->set_size(disposer, { input_texture.width, input_texture.height }, input_texture.format); } tmp->copy(cmd, input_texture.image, src_layout); @@ -2422,12 +2424,14 @@ void Framebuffer::init_framebuffer() vkCreateFramebuffer(device, &info, nullptr, &framebuffer); } -void Framebuffer::set_size(DeferredDisposer &disposer, const Size2D &size) +void Framebuffer::set_size(DeferredDisposer &disposer, const Size2D &size, VkFormat format) { this->size = size; + if (format != VK_FORMAT_UNDEFINED) + this->format = format; - RARCH_LOG("[Vulkan filter chain]: Updating framebuffer size %u x %u.\n", - size.width, size.height); + RARCH_LOG("[Vulkan filter chain]: Updating framebuffer size %u x %u (format: %u).\n", + size.width, size.height, (unsigned)this->format); { // The current framebuffers, etc, might still be in use diff --git a/gfx/drivers_shader/shader_vulkan.h b/gfx/drivers_shader/shader_vulkan.h index 79ac7f2d8f..7c7e07ad91 100644 --- a/gfx/drivers_shader/shader_vulkan.h +++ b/gfx/drivers_shader/shader_vulkan.h @@ -53,6 +53,7 @@ struct vulkan_filter_chain_texture VkImageLayout layout; unsigned width; unsigned height; + VkFormat format; }; enum vulkan_filter_chain_scale