From 84923a04651b7e8667009028a5339c96e3749562 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 21 Mar 2016 10:02:00 +0100 Subject: [PATCH] Vulkan: Tighten up pipeline barrier usage. Lots of memory barriers used with TOP_OF_PIPE which is not valid. --- cores/libretro-test-vulkan/libretro-test.c | 4 +-- gfx/common/vulkan_common.c | 42 ++++++++++++++++------ gfx/drivers/vulkan.c | 18 +++++----- gfx/drivers_shader/shader_vulkan.cpp | 6 ++-- 4 files changed, 45 insertions(+), 25 deletions(-) diff --git a/cores/libretro-test-vulkan/libretro-test.c b/cores/libretro-test-vulkan/libretro-test.c index 898e0dcf21..64da2eea93 100644 --- a/cores/libretro-test-vulkan/libretro-test.c +++ b/cores/libretro-test-vulkan/libretro-test.c @@ -186,7 +186,7 @@ static void vulkan_test_render(void) VkImageMemoryBarrier prepare_rendering = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; prepare_rendering.srcAccessMask = 0; - prepare_rendering.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + prepare_rendering.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; prepare_rendering.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; prepare_rendering.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; prepare_rendering.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -704,7 +704,7 @@ static void context_destroy(void) static bool retro_init_hw_context(void) { hw_render.context_type = RETRO_HW_CONTEXT_VULKAN; - hw_render.version_major = VK_API_VERSION; + hw_render.version_major = VK_MAKE_VERSION(1, 0, 6); hw_render.version_minor = 0; hw_render.context_reset = context_reset; hw_render.context_destroy = context_destroy; diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index babe5d312d..d9bbc9ccea 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -135,7 +135,7 @@ void vulkan_copy_staging_to_dynamic(vk_t *vk, VkCommandBuffer cmd, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT); memset(®ion, 0, sizeof(region)); region.extent.width = dynamic->width; @@ -445,14 +445,14 @@ struct vk_texture vulkan_create_texture(vk_t *vk, vulkan_image_layout_transition(vk, staging, tmp.image, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT); vulkan_image_layout_transition(vk, staging, tex.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT); memset(®ion, 0, sizeof(region)); region.extent.width = width; @@ -473,7 +473,7 @@ struct vk_texture vulkan_create_texture(vk_t *vk, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); VKFUNC(vkEndCommandBuffer)(staging); submit_info.commandBufferCount = 1; @@ -553,15 +553,35 @@ void vulkan_transition_texture(vk_t *vk, struct vk_texture *texture) /* Transition to GENERAL layout for linear streamed textures. * We're using linear textures here, so only * GENERAL layout is supported. + * If we're already in GENERAL, add a host -> shader read memory barrier + * to invalidate texture caches. */ - if (texture->layout != VK_IMAGE_LAYOUT_PREINITIALIZED) + if (texture->layout != VK_IMAGE_LAYOUT_PREINITIALIZED && + texture->layout != VK_IMAGE_LAYOUT_GENERAL) return; - vulkan_image_layout_transition(vk, vk->cmd, texture->image, - texture->layout, VK_IMAGE_LAYOUT_GENERAL, - VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + switch (texture->type) + { + case VULKAN_TEXTURE_STREAMED: + vulkan_image_layout_transition(vk, vk->cmd, texture->image, + texture->layout, VK_IMAGE_LAYOUT_GENERAL, + VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + break; + + case VULKAN_TEXTURE_STAGING: + vulkan_image_layout_transition(vk, vk->cmd, texture->image, + texture->layout, VK_IMAGE_LAYOUT_GENERAL, + VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT); + break; + + default: + retro_assert(0 && "Attempting to transition invalid texture type.\n"); + break; + } texture->layout = VK_IMAGE_LAYOUT_GENERAL; } diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 3a1e19ac7e..6c028f2c1c 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -1335,7 +1335,7 @@ static void vulkan_readback(vk_t *vk) VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT); VKFUNC(vkCmdCopyImage)(vk->cmd, vk->chain->backbuffer.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, @@ -1527,12 +1527,12 @@ static bool vulkan_frame(void *data, const void *frame, rp_info.clearValueCount = 1; rp_info.pClearValues = &clear_value; - /* Prepare backbuffer for rendering */ + /* Prepare backbuffer for rendering. We don't use WSI semaphores here. */ vulkan_image_layout_transition(vk, vk->cmd, chain->backbuffer.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); /* Begin render pass and set up viewport */ VKFUNC(vkCmdBeginRenderPass)(vk->cmd, &rp_info, VK_SUBPASS_CONTENTS_INLINE); @@ -1613,10 +1613,10 @@ static bool vulkan_frame(void *data, const void *frame, chain->backbuffer.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - VK_ACCESS_TRANSFER_READ_BIT, - VK_ACCESS_MEMORY_READ_BIT, + 0, + 0, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); vk->readback.pending = false; } @@ -1628,9 +1628,9 @@ static bool vulkan_frame(void *data, const void *frame, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_ACCESS_MEMORY_READ_BIT, + 0, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); } retro_perf_start(&end_cmd); diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index ccd84d3822..129ac29be7 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -1074,9 +1074,9 @@ void Pass::build_commands( framebuffer->get_image(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_ACCESS_SHADER_READ_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); VkRenderPassBeginInfo rp_info = {