mirror of https://github.com/PCSX2/pcsx2.git
VulkanHostDisplay: Upload textures in init command buffer
This commit is contained in:
parent
b74c65cc7c
commit
f8fa41d4bf
|
@ -54,13 +54,25 @@ VulkanHostDisplay::~VulkanHostDisplay()
|
||||||
pxAssertRel(!m_swap_chain, "Swap chain should have been destroyed by now");
|
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)
|
bool VulkanHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
||||||
{
|
{
|
||||||
|
@ -87,8 +99,8 @@ bool VulkanHostDisplay::ChangeRenderWindow(const WindowInfo& new_wi)
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowInfo wi_copy(new_wi);
|
WindowInfo wi_copy(new_wi);
|
||||||
VkSurfaceKHR surface = Vulkan::SwapChain::CreateVulkanSurface(
|
VkSurfaceKHR surface =
|
||||||
g_vulkan_context->GetVulkanInstance(), g_vulkan_context->GetPhysicalDevice(), &wi_copy);
|
Vulkan::SwapChain::CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), g_vulkan_context->GetPhysicalDevice(), &wi_copy);
|
||||||
if (surface == VK_NULL_HANDLE)
|
if (surface == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
Console.Error("Failed to create new surface for swap chain");
|
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();
|
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()
|
HostDisplay::AdapterAndModeList VulkanHostDisplay::GetAdapterAndModeList()
|
||||||
{
|
{
|
||||||
|
@ -147,27 +168,24 @@ std::string VulkanHostDisplay::GetDriverInfo() const
|
||||||
if (g_vulkan_context->GetOptionalExtensions().vk_khr_driver_properties)
|
if (g_vulkan_context->GetOptionalExtensions().vk_khr_driver_properties)
|
||||||
{
|
{
|
||||||
const VkPhysicalDeviceDriverProperties& props = g_vulkan_context->GetDeviceDriverProperties();
|
const VkPhysicalDeviceDriverProperties& props = g_vulkan_context->GetDeviceDriverProperties();
|
||||||
ret = StringUtil::StdStringFromFormat(
|
ret = StringUtil::StdStringFromFormat("Driver %u.%u.%u\nVulkan %u.%u.%u\nConformance Version %u.%u.%u.%u\n%s\n%s\n%s",
|
||||||
"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_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),
|
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.conformanceVersion.major, props.conformanceVersion.minor, props.conformanceVersion.subminor,
|
||||||
props.driverInfo, props.driverName,
|
props.conformanceVersion.patch, props.driverInfo, props.driverName, g_vulkan_context->GetDeviceProperties().deviceName);
|
||||||
g_vulkan_context->GetDeviceProperties().deviceName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = StringUtil::StdStringFromFormat(
|
ret = StringUtil::StdStringFromFormat("Driver %u.%u.%u\nVulkan %u.%u.%u\n%s", VK_VERSION_MAJOR(driver_version),
|
||||||
"Driver %u.%u.%u\nVulkan %u.%u.%u\n%s",
|
VK_VERSION_MINOR(driver_version), VK_VERSION_PATCH(driver_version), VK_API_VERSION_MAJOR(api_version),
|
||||||
VK_VERSION_MAJOR(driver_version), VK_VERSION_MINOR(driver_version), VK_VERSION_PATCH(driver_version),
|
VK_API_VERSION_MINOR(api_version), VK_API_VERSION_PATCH(api_version), g_vulkan_context->GetDeviceProperties().deviceName);
|
||||||
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;
|
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_stride = Vulkan::Util::GetTexelSize(texture->GetFormat()) * width;
|
||||||
const u32 tight_size = tight_stride * height;
|
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);
|
Console.WriteLn("Failed to allocate %u bytes in stream buffer for UploadBufferToTexture()", tight_size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
cmdbuf = g_vulkan_context->GetCurrentInitCommandBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 buf_offset = buf.GetCurrentOffset();
|
const u32 buf_offset = buf.GetCurrentOffset();
|
||||||
StringUtil::StrideMemCpy(buf.GetCurrentHostPointer(), tight_stride, data, data_stride, tight_stride, height);
|
StringUtil::StrideMemCpy(buf.GetCurrentHostPointer(), tight_stride, data, data_stride, tight_stride, height);
|
||||||
buf.CommitMemory(tight_size);
|
buf.CommitMemory(tight_size);
|
||||||
|
|
||||||
texture->UpdateFromBuffer(
|
texture->UpdateFromBuffer(cmdbuf, 0, 0, 0, 0, width, height, width, buf.GetBuffer(), buf_offset);
|
||||||
g_vulkan_context->GetCurrentCommandBuffer(), 0, 0, 0, 0, width, height, width, buf.GetBuffer(), buf_offset);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HostDisplayTexture> VulkanHostDisplay::CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic /* = false */)
|
std::unique_ptr<HostDisplayTexture> 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 VkFormat vk_format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
static constexpr VkImageUsageFlags usage =
|
static constexpr VkImageUsageFlags usage =
|
||||||
|
@ -203,11 +222,11 @@ std::unique_ptr<HostDisplayTexture> 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))
|
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 {};
|
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 (data)
|
||||||
{
|
{
|
||||||
if (!UploadBufferToTexture(&texture, width, height, data, data_stride))
|
if (!UploadBufferToTexture(&texture, g_vulkan_context->GetCurrentInitCommandBuffer(), width, height, data, data_stride))
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -215,20 +234,18 @@ std::unique_ptr<HostDisplayTexture> VulkanHostDisplay::CreateTexture(u32 width,
|
||||||
// clear it instead so we don't read uninitialized data (and keep the validation layer happy!)
|
// clear it instead so we don't read uninitialized data (and keep the validation layer happy!)
|
||||||
static constexpr VkClearColorValue ccv = {};
|
static constexpr VkClearColorValue ccv = {};
|
||||||
static constexpr VkImageSubresourceRange isr = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
|
static constexpr VkImageSubresourceRange isr = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
|
||||||
vkCmdClearColorImage(
|
vkCmdClearColorImage(g_vulkan_context->GetCurrentInitCommandBuffer(), texture.GetImage(), texture.GetLayout(), &ccv, 1u, &isr);
|
||||||
g_vulkan_context->GetCurrentCommandBuffer(), 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<VulkanHostDisplayTexture>(std::move(texture));
|
return std::make_unique<VulkanHostDisplayTexture>(std::move(texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHostDisplay::UpdateTexture(
|
void VulkanHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride)
|
||||||
HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride)
|
|
||||||
{
|
{
|
||||||
UploadBufferToTexture(
|
UploadBufferToTexture(&static_cast<VulkanHostDisplayTexture*>(texture)->GetTexture(), g_vulkan_context->GetCurrentCommandBuffer(),
|
||||||
&static_cast<VulkanHostDisplayTexture*>(texture)->GetTexture(), width, height, data, data_stride);
|
width, height, data, data_stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanHostDisplay::SetVSync(VsyncMode mode)
|
void VulkanHostDisplay::SetVSync(VsyncMode mode)
|
||||||
|
@ -248,9 +265,8 @@ bool VulkanHostDisplay::CreateRenderDevice(
|
||||||
// debug_device = true;
|
// debug_device = true;
|
||||||
|
|
||||||
WindowInfo local_wi(wi);
|
WindowInfo local_wi(wi);
|
||||||
if (!Vulkan::Context::Create(
|
if (!Vulkan::Context::Create(adapter_name, &local_wi, &m_swap_chain, GetPreferredPresentModeForVsyncMode(vsync), threaded_presentation,
|
||||||
adapter_name, &local_wi, &m_swap_chain, GetPreferredPresentModeForVsyncMode(vsync),
|
debug_device, debug_device))
|
||||||
threaded_presentation, debug_device, debug_device))
|
|
||||||
{
|
{
|
||||||
Console.Error("Failed to create Vulkan context");
|
Console.Error("Failed to create Vulkan context");
|
||||||
m_window_info = {};
|
m_window_info = {};
|
||||||
|
@ -269,9 +285,15 @@ bool VulkanHostDisplay::InitializeRenderDevice(std::string_view shader_cache_dir
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::HasRenderDevice() const { return static_cast<bool>(g_vulkan_context); }
|
bool VulkanHostDisplay::HasRenderDevice() const
|
||||||
|
{
|
||||||
|
return static_cast<bool>(g_vulkan_context);
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::HasRenderSurface() const { return static_cast<bool>(m_swap_chain); }
|
bool VulkanHostDisplay::HasRenderSurface() const
|
||||||
|
{
|
||||||
|
return static_cast<bool>(m_swap_chain);
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanHostDisplay::CreateImGuiContext()
|
bool VulkanHostDisplay::CreateImGuiContext()
|
||||||
{
|
{
|
||||||
|
@ -301,9 +323,15 @@ void VulkanHostDisplay::DestroyRenderDevice()
|
||||||
Vulkan::Context::Destroy();
|
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)
|
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);
|
swap_chain_texture.TransitionToLayout(cmdbuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
const VkClearValue clear_value = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
|
const VkClearValue clear_value = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
|
||||||
const VkRenderPassBeginInfo rp = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
|
const VkRenderPassBeginInfo rp = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, m_swap_chain->GetClearRenderPass(),
|
||||||
m_swap_chain->GetClearRenderPass(), m_swap_chain->GetCurrentFramebuffer(),
|
m_swap_chain->GetCurrentFramebuffer(), {{0, 0}, {swap_chain_texture.GetWidth(), swap_chain_texture.GetHeight()}}, 1u, &clear_value};
|
||||||
{{0, 0}, {swap_chain_texture.GetWidth(), swap_chain_texture.GetHeight()}}, 1u, &clear_value};
|
|
||||||
vkCmdBeginRenderPass(g_vulkan_context->GetCurrentCommandBuffer(), &rp, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(g_vulkan_context->GetCurrentCommandBuffer(), &rp, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
const VkViewport vp{0.0f, 0.0f, static_cast<float>(swap_chain_texture.GetWidth()),
|
const VkViewport vp{
|
||||||
static_cast<float>(swap_chain_texture.GetHeight()), 0.0f, 1.0f};
|
0.0f, 0.0f, static_cast<float>(swap_chain_texture.GetWidth()), static_cast<float>(swap_chain_texture.GetHeight()), 0.0f, 1.0f};
|
||||||
const VkRect2D scissor{
|
const VkRect2D scissor{{0, 0}, {static_cast<u32>(swap_chain_texture.GetWidth()), static_cast<u32>(swap_chain_texture.GetHeight())}};
|
||||||
{0, 0}, {static_cast<u32>(swap_chain_texture.GetWidth()), static_cast<u32>(swap_chain_texture.GetHeight())}};
|
|
||||||
vkCmdSetViewport(g_vulkan_context->GetCurrentCommandBuffer(), 0, 1, &vp);
|
vkCmdSetViewport(g_vulkan_context->GetCurrentCommandBuffer(), 0, 1, &vp);
|
||||||
vkCmdSetScissor(g_vulkan_context->GetCurrentCommandBuffer(), 0, 1, &scissor);
|
vkCmdSetScissor(g_vulkan_context->GetCurrentCommandBuffer(), 0, 1, &scissor);
|
||||||
return true;
|
return true;
|
||||||
|
@ -379,9 +405,8 @@ void VulkanHostDisplay::EndPresent()
|
||||||
vkCmdEndRenderPass(g_vulkan_context->GetCurrentCommandBuffer());
|
vkCmdEndRenderPass(g_vulkan_context->GetCurrentCommandBuffer());
|
||||||
m_swap_chain->GetCurrentTexture().TransitionToLayout(cmdbuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
m_swap_chain->GetCurrentTexture().TransitionToLayout(cmdbuffer, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
|
|
||||||
g_vulkan_context->SubmitCommandBuffer(m_swap_chain->GetImageAvailableSemaphore(),
|
g_vulkan_context->SubmitCommandBuffer(m_swap_chain->GetImageAvailableSemaphore(), m_swap_chain->GetRenderingFinishedSemaphore(),
|
||||||
m_swap_chain->GetRenderingFinishedSemaphore(), m_swap_chain->GetSwapChain(),
|
m_swap_chain->GetSwapChain(), m_swap_chain->GetCurrentImageIndex(), !m_swap_chain->IsPresentModeSynchronizing());
|
||||||
m_swap_chain->GetCurrentImageIndex(), !m_swap_chain->IsPresentModeSynchronizing());
|
|
||||||
g_vulkan_context->MoveToNextCommandBuffer();
|
g_vulkan_context->MoveToNextCommandBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue