From f8fa41d4bfec5bbe7dfb944b586ec7e660b910f6 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 5 Jun 2022 00:20:26 +1000 Subject: [PATCH] VulkanHostDisplay: Upload textures in init command buffer --- pcsx2/Frontend/VulkanHostDisplay.cpp | 123 ++++++++++++++++----------- 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/pcsx2/Frontend/VulkanHostDisplay.cpp b/pcsx2/Frontend/VulkanHostDisplay.cpp index 05aff63c1c..2bc09a65e3 100644 --- a/pcsx2/Frontend/VulkanHostDisplay.cpp +++ b/pcsx2/Frontend/VulkanHostDisplay.cpp @@ -54,13 +54,25 @@ VulkanHostDisplay::~VulkanHostDisplay() pxAssertRel(!m_swap_chain, "Swap chain should have been destroyed by now"); } -HostDisplay::RenderAPI VulkanHostDisplay::GetRenderAPI() const { return HostDisplay::RenderAPI::Vulkan; } +HostDisplay::RenderAPI VulkanHostDisplay::GetRenderAPI() const +{ + return HostDisplay::RenderAPI::Vulkan; +} -void* VulkanHostDisplay::GetRenderDevice() const { return nullptr; } +void* VulkanHostDisplay::GetRenderDevice() const +{ + return nullptr; +} -void* VulkanHostDisplay::GetRenderContext() const { return nullptr; } +void* VulkanHostDisplay::GetRenderContext() const +{ + return nullptr; +} -void* VulkanHostDisplay::GetRenderSurface() const { return m_swap_chain.get(); } +void* VulkanHostDisplay::GetRenderSurface() const +{ + return m_swap_chain.get(); +} bool VulkanHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi) { @@ -87,8 +99,8 @@ bool VulkanHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi) } WindowInfo wi_copy(new_wi); - VkSurfaceKHR surface = Vulkan::SwapChain::CreateVulkanSurface( - g_vulkan_context->GetVulkanInstance(), g_vulkan_context->GetPhysicalDevice(), &wi_copy); + VkSurfaceKHR surface = + Vulkan::SwapChain::CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), g_vulkan_context->GetPhysicalDevice(), &wi_copy); if (surface == VK_NULL_HANDLE) { Console.Error("Failed to create new surface for swap chain"); @@ -121,11 +133,20 @@ void VulkanHostDisplay::ResizeRenderWindow(s32 new_window_width, s32 new_window_ m_window_info = m_swap_chain->GetWindowInfo(); } -bool VulkanHostDisplay::SupportsFullscreen() const { return false; } +bool VulkanHostDisplay::SupportsFullscreen() const +{ + return false; +} -bool VulkanHostDisplay::IsFullscreen() { return false; } +bool VulkanHostDisplay::IsFullscreen() +{ + return false; +} -bool VulkanHostDisplay::SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) { return false; } +bool VulkanHostDisplay::SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) +{ + return false; +} HostDisplay::AdapterAndModeList VulkanHostDisplay::GetAdapterAndModeList() { @@ -147,27 +168,24 @@ std::string VulkanHostDisplay::GetDriverInfo() const if (g_vulkan_context->GetOptionalExtensions().vk_khr_driver_properties) { const VkPhysicalDeviceDriverProperties& props = g_vulkan_context->GetDeviceDriverProperties(); - ret = StringUtil::StdStringFromFormat( - "Driver %u.%u.%u\nVulkan %u.%u.%u\nConformance Version %u.%u.%u.%u\n%s\n%s\n%s", + ret = StringUtil::StdStringFromFormat("Driver %u.%u.%u\nVulkan %u.%u.%u\nConformance Version %u.%u.%u.%u\n%s\n%s\n%s", VK_VERSION_MAJOR(driver_version), VK_VERSION_MINOR(driver_version), VK_VERSION_PATCH(driver_version), VK_API_VERSION_MAJOR(api_version), VK_API_VERSION_MINOR(api_version), VK_API_VERSION_PATCH(api_version), - props.conformanceVersion.major, props.conformanceVersion.minor, props.conformanceVersion.subminor, props.conformanceVersion.patch, - props.driverInfo, props.driverName, - g_vulkan_context->GetDeviceProperties().deviceName); + props.conformanceVersion.major, props.conformanceVersion.minor, props.conformanceVersion.subminor, + props.conformanceVersion.patch, props.driverInfo, props.driverName, g_vulkan_context->GetDeviceProperties().deviceName); } else { - ret = StringUtil::StdStringFromFormat( - "Driver %u.%u.%u\nVulkan %u.%u.%u\n%s", - VK_VERSION_MAJOR(driver_version), VK_VERSION_MINOR(driver_version), VK_VERSION_PATCH(driver_version), - VK_API_VERSION_MAJOR(api_version), VK_API_VERSION_MINOR(api_version), VK_API_VERSION_PATCH(api_version), - g_vulkan_context->GetDeviceProperties().deviceName); + ret = StringUtil::StdStringFromFormat("Driver %u.%u.%u\nVulkan %u.%u.%u\n%s", VK_VERSION_MAJOR(driver_version), + VK_VERSION_MINOR(driver_version), VK_VERSION_PATCH(driver_version), VK_API_VERSION_MAJOR(api_version), + VK_API_VERSION_MINOR(api_version), VK_API_VERSION_PATCH(api_version), g_vulkan_context->GetDeviceProperties().deviceName); } return ret; } -static bool UploadBufferToTexture(Vulkan::Texture* texture, u32 width, u32 height, const void* data, u32 data_stride) +static bool UploadBufferToTexture( + Vulkan::Texture* texture, VkCommandBuffer cmdbuf, u32 width, u32 height, const void* data, u32 data_stride) { const u32 tight_stride = Vulkan::Util::GetTexelSize(texture->GetFormat()) * width; const u32 tight_size = tight_stride * height; @@ -182,18 +200,19 @@ static bool UploadBufferToTexture(Vulkan::Texture* texture, u32 width, u32 heigh Console.WriteLn("Failed to allocate %u bytes in stream buffer for UploadBufferToTexture()", tight_size); return false; } + cmdbuf = g_vulkan_context->GetCurrentInitCommandBuffer(); } const u32 buf_offset = buf.GetCurrentOffset(); StringUtil::StrideMemCpy(buf.GetCurrentHostPointer(), tight_stride, data, data_stride, tight_stride, height); buf.CommitMemory(tight_size); - texture->UpdateFromBuffer( - g_vulkan_context->GetCurrentCommandBuffer(), 0, 0, 0, 0, width, height, width, buf.GetBuffer(), buf_offset); + texture->UpdateFromBuffer(cmdbuf, 0, 0, 0, 0, width, height, width, buf.GetBuffer(), buf_offset); return true; } -std::unique_ptr VulkanHostDisplay::CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic /* = false */) +std::unique_ptr VulkanHostDisplay::CreateTexture( + u32 width, u32 height, const void* data, u32 data_stride, bool dynamic /* = false */) { static constexpr VkFormat vk_format = VK_FORMAT_R8G8B8A8_UNORM; static constexpr VkImageUsageFlags usage = @@ -203,11 +222,11 @@ std::unique_ptr VulkanHostDisplay::CreateTexture(u32 width, if (!texture.Create(width, height, 1, 1, vk_format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage)) return {}; - texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + texture.TransitionToLayout(g_vulkan_context->GetCurrentInitCommandBuffer(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); if (data) { - if (!UploadBufferToTexture(&texture, width, height, data, data_stride)) + if (!UploadBufferToTexture(&texture, g_vulkan_context->GetCurrentInitCommandBuffer(), width, height, data, data_stride)) return {}; } else @@ -215,20 +234,18 @@ std::unique_ptr VulkanHostDisplay::CreateTexture(u32 width, // clear it instead so we don't read uninitialized data (and keep the validation layer happy!) static constexpr VkClearColorValue ccv = {}; static constexpr VkImageSubresourceRange isr = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}; - vkCmdClearColorImage( - g_vulkan_context->GetCurrentCommandBuffer(), texture.GetImage(), texture.GetLayout(), &ccv, 1u, &isr); + vkCmdClearColorImage(g_vulkan_context->GetCurrentInitCommandBuffer(), texture.GetImage(), texture.GetLayout(), &ccv, 1u, &isr); } - texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + texture.TransitionToLayout(g_vulkan_context->GetCurrentInitCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); return std::make_unique(std::move(texture)); } -void VulkanHostDisplay::UpdateTexture( - HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride) +void VulkanHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride) { - UploadBufferToTexture( - &static_cast(texture)->GetTexture(), width, height, data, data_stride); + UploadBufferToTexture(&static_cast(texture)->GetTexture(), g_vulkan_context->GetCurrentCommandBuffer(), + width, height, data, data_stride); } void VulkanHostDisplay::SetVSync(VsyncMode mode) @@ -248,9 +265,8 @@ bool VulkanHostDisplay::CreateRenderDevice( // debug_device = true; WindowInfo local_wi(wi); - if (!Vulkan::Context::Create( - adapter_name, &local_wi, &m_swap_chain, GetPreferredPresentModeForVsyncMode(vsync), - threaded_presentation, debug_device, debug_device)) + if (!Vulkan::Context::Create(adapter_name, &local_wi, &m_swap_chain, GetPreferredPresentModeForVsyncMode(vsync), threaded_presentation, + debug_device, debug_device)) { Console.Error("Failed to create Vulkan context"); m_window_info = {}; @@ -269,9 +285,15 @@ bool VulkanHostDisplay::InitializeRenderDevice(std::string_view shader_cache_dir return true; } -bool VulkanHostDisplay::HasRenderDevice() const { return static_cast(g_vulkan_context); } +bool VulkanHostDisplay::HasRenderDevice() const +{ + return static_cast(g_vulkan_context); +} -bool VulkanHostDisplay::HasRenderSurface() const { return static_cast(m_swap_chain); } +bool VulkanHostDisplay::HasRenderSurface() const +{ + return static_cast(m_swap_chain); +} bool VulkanHostDisplay::CreateImGuiContext() { @@ -301,9 +323,15 @@ void VulkanHostDisplay::DestroyRenderDevice() Vulkan::Context::Destroy(); } -bool VulkanHostDisplay::MakeRenderContextCurrent() { return true; } +bool VulkanHostDisplay::MakeRenderContextCurrent() +{ + return true; +} -bool VulkanHostDisplay::DoneRenderContextCurrent() { return true; } +bool VulkanHostDisplay::DoneRenderContextCurrent() +{ + return true; +} bool VulkanHostDisplay::BeginPresent(bool frame_skip) { @@ -356,15 +384,13 @@ bool VulkanHostDisplay::BeginPresent(bool frame_skip) swap_chain_texture.TransitionToLayout(cmdbuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); const VkClearValue clear_value = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; - const VkRenderPassBeginInfo rp = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, - m_swap_chain->GetClearRenderPass(), m_swap_chain->GetCurrentFramebuffer(), - {{0, 0}, {swap_chain_texture.GetWidth(), swap_chain_texture.GetHeight()}}, 1u, &clear_value}; + const VkRenderPassBeginInfo rp = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, m_swap_chain->GetClearRenderPass(), + m_swap_chain->GetCurrentFramebuffer(), {{0, 0}, {swap_chain_texture.GetWidth(), swap_chain_texture.GetHeight()}}, 1u, &clear_value}; vkCmdBeginRenderPass(g_vulkan_context->GetCurrentCommandBuffer(), &rp, VK_SUBPASS_CONTENTS_INLINE); - const VkViewport vp{0.0f, 0.0f, static_cast(swap_chain_texture.GetWidth()), - static_cast(swap_chain_texture.GetHeight()), 0.0f, 1.0f}; - const VkRect2D scissor{ - {0, 0}, {static_cast(swap_chain_texture.GetWidth()), static_cast(swap_chain_texture.GetHeight())}}; + const VkViewport vp{ + 0.0f, 0.0f, static_cast(swap_chain_texture.GetWidth()), static_cast(swap_chain_texture.GetHeight()), 0.0f, 1.0f}; + const VkRect2D scissor{{0, 0}, {static_cast(swap_chain_texture.GetWidth()), static_cast(swap_chain_texture.GetHeight())}}; vkCmdSetViewport(g_vulkan_context->GetCurrentCommandBuffer(), 0, 1, &vp); vkCmdSetScissor(g_vulkan_context->GetCurrentCommandBuffer(), 0, 1, &scissor); return true; @@ -379,9 +405,8 @@ void VulkanHostDisplay::EndPresent() vkCmdEndRenderPass(g_vulkan_context->GetCurrentCommandBuffer()); m_swap_chain->GetCurrentTexture().TransitionToLayout(cmdbuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); - g_vulkan_context->SubmitCommandBuffer(m_swap_chain->GetImageAvailableSemaphore(), - m_swap_chain->GetRenderingFinishedSemaphore(), m_swap_chain->GetSwapChain(), - m_swap_chain->GetCurrentImageIndex(), !m_swap_chain->IsPresentModeSynchronizing()); + g_vulkan_context->SubmitCommandBuffer(m_swap_chain->GetImageAvailableSemaphore(), m_swap_chain->GetRenderingFinishedSemaphore(), + m_swap_chain->GetSwapChain(), m_swap_chain->GetCurrentImageIndex(), !m_swap_chain->IsPresentModeSynchronizing()); g_vulkan_context->MoveToNextCommandBuffer(); }