From 96818a297c123845fb59371eb3b64f824e4800cc Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Sun, 7 Aug 2016 01:09:15 +0200 Subject: [PATCH] Vulkan: Fix validation errors with OriginalHistory. For some reason, OriginalHistory blit happened inside a render pass. Also add more TRANSFER_SRC_BIT caps to images as they might have to be copied to history. --- gfx/common/vulkan_common.c | 7 +++++-- gfx/drivers/vulkan.c | 5 +++++ gfx/drivers_shader/shader_vulkan.cpp | 26 ++++++++++++++++++++------ gfx/drivers_shader/shader_vulkan.h | 2 ++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 2bba8d71e6..453604cb4d 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -350,12 +350,15 @@ struct vk_texture vulkan_create_texture(vk_t *vk, case VULKAN_TEXTURE_DYNAMIC: retro_assert(!initial && "Dynamic textures must not have initial data.\n"); info.tiling = VK_IMAGE_TILING_OPTIMAL; - info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT; info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; break; case VULKAN_TEXTURE_STREAMED: - info.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT; info.tiling = VK_IMAGE_TILING_LINEAR; info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; break; diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 15d31308f9..9ca4867836 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -1789,6 +1789,11 @@ static bool vulkan_frame(void *data, const void *frame, /* End the render pass. We're done rendering to backbuffer now. */ vkCmdEndRenderPass(vk->cmd); + /* End the filter chain frame. + * This must happen outside a render pass. + */ + vulkan_filter_chain_end_frame(vk->filter_chain, vk->cmd); + if (vk->readback.pending || vk->readback.streamed) { /* We cannot safely read back from an image which diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 250aff8f6e..50e32f4d06 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -559,6 +559,7 @@ struct vulkan_filter_chain void build_offscreen_passes(VkCommandBuffer cmd, const VkViewport &vp); void build_viewport_pass(VkCommandBuffer cmd, const VkViewport &vp, const float *mvp); + void end_frame(VkCommandBuffer cmd); void set_frame_count(uint64_t count); void set_frame_count_period(unsigned pass, unsigned period); @@ -1085,6 +1086,18 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu swap(original_history.front(), tmp); } +void vulkan_filter_chain::end_frame(VkCommandBuffer cmd) +{ + // If we need to keep old frames, copy it after fragment is complete. + // TODO: We can improve pipelining by figuring out which pass is the last that reads from + // the history and dispatch the copy earlier. + if (!original_history.empty()) + { + DeferredDisposer disposer(deferred_calls[current_sync_index]); + update_history(disposer, cmd); + } +} + void vulkan_filter_chain::build_viewport_pass( VkCommandBuffer cmd, const VkViewport &vp, const float *mvp) { @@ -1128,12 +1141,6 @@ void vulkan_filter_chain::build_viewport_pass( passes.back()->build_commands(disposer, cmd, original, source, vp, mvp); - // If we need to keep old frames, copy it after fragment is complete. - // TODO: We can improve pipelining by figuring out which pass is the last that reads from - // the history and dispatch the copy earlier. - if (!original_history.empty()) - update_history(disposer, cmd); - // For feedback FBOs, swap current and previous. for (auto &pass : passes) pass->end_frame(); @@ -3188,3 +3195,10 @@ void vulkan_filter_chain_build_viewport_pass( chain->build_viewport_pass(cmd, *vp, mvp); } +void vulkan_filter_chain_end_frame( + vulkan_filter_chain_t *chain, + VkCommandBuffer cmd) +{ + chain->end_frame(cmd); +} + diff --git a/gfx/drivers_shader/shader_vulkan.h b/gfx/drivers_shader/shader_vulkan.h index 4ebe7b27cd..12bf7123aa 100644 --- a/gfx/drivers_shader/shader_vulkan.h +++ b/gfx/drivers_shader/shader_vulkan.h @@ -149,6 +149,8 @@ void vulkan_filter_chain_build_offscreen_passes(vulkan_filter_chain_t *chain, VkCommandBuffer cmd, const VkViewport *vp); void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain, VkCommandBuffer cmd, const VkViewport *vp, const float *mvp); +void vulkan_filter_chain_end_frame(vulkan_filter_chain_t *chain, + VkCommandBuffer cmd); vulkan_filter_chain_t *vulkan_filter_chain_create_default( const struct vulkan_filter_chain_create_info *info,