GPU/Software: Reduce number of copies by one, enable 16-bit scanout

This commit is contained in:
Connor McLaughlin
2020-10-22 01:25:33 +10:00
parent beffbaee39
commit d3d881aa6b
20 changed files with 875 additions and 187 deletions

View File

@ -247,6 +247,60 @@ bool VulkanHostDisplay::DownloadTexture(const void* texture_handle, u32 x, u32 y
return true;
}
static constexpr std::array<VkFormat, static_cast<u32>(HostDisplayPixelFormat::Count)> s_display_pixel_format_mapping =
{{VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B5G6R5_UNORM_PACK16,
VK_FORMAT_A1R5G5B5_UNORM_PACK16}};
bool VulkanHostDisplay::SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const
{
const VkFormat vk_format = s_display_pixel_format_mapping[static_cast<u32>(format)];
if (vk_format == VK_FORMAT_UNDEFINED)
return false;
VkFormatProperties fp = {};
vkGetPhysicalDeviceFormatProperties(g_vulkan_context->GetPhysicalDevice(), vk_format, &fp);
const VkFormatFeatureFlags required = (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
return ((fp.optimalTilingFeatures & required) == required);
}
bool VulkanHostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
u32* out_pitch)
{
const VkFormat vk_format = s_display_pixel_format_mapping[static_cast<u32>(format)];
if (m_display_pixels_texture.GetWidth() < width || m_display_pixels_texture.GetHeight() < height ||
m_display_pixels_texture.GetFormat() != vk_format)
{
if (!m_display_pixels_texture.Create(width, height, 1, 1, vk_format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_VIEW_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT))
{
return false;
}
}
if ((m_upload_staging_texture.GetWidth() < width || m_upload_staging_texture.GetHeight() < height) &&
!m_upload_staging_texture.Create(Vulkan::StagingBuffer::Type::Upload, vk_format, width, height))
{
return false;
}
SetDisplayTexture(&m_display_pixels_texture, format, m_display_pixels_texture.GetWidth(),
m_display_pixels_texture.GetHeight(), 0, 0, width, height);
*out_buffer = m_upload_staging_texture.GetMappedPointer();
*out_pitch = m_upload_staging_texture.GetMappedStride();
return true;
}
void VulkanHostDisplay::EndSetDisplayPixels()
{
m_upload_staging_texture.CopyToTexture(0, 0, m_display_pixels_texture, 0, 0, 0, 0,
static_cast<u32>(m_display_texture_view_width),
static_cast<u32>(m_display_texture_view_height));
}
void VulkanHostDisplay::SetVSync(bool enabled)
{
if (!m_swap_chain)
@ -461,6 +515,7 @@ void VulkanHostDisplay::DestroyResources()
m_post_processing_chain.ClearStages();
#endif
m_display_pixels_texture.Destroy(false);
m_readback_staging_texture.Destroy(false);
m_upload_staging_texture.Destroy(false);