vulkan/wsi: use buffer-image code-path on Windows

This means we no longer map optimal-tiling images in order to display
them on screen, but instead copy via a buffer, which is guaranteed to
linearize.

Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12210>
This commit is contained in:
Erik Faye-Lund 2021-07-19 15:34:01 +02:00 committed by Marge Bot
parent 2e8c119531
commit 5c5243adb7
1 changed files with 40 additions and 25 deletions

View File

@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include "vk_format.h"
#include "vk_instance.h"
#include "vk_physical_device.h"
#include "vk_util.h"
@ -305,31 +306,32 @@ select_memory_type(const struct wsi_device *wsi,
unreachable("No memory type found");
}
static uint32_t
select_image_memory_type(const struct wsi_device *wsi,
uint32_t type_bits)
{
return select_memory_type(wsi,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
type_bits);
}
static uint32_t
select_buffer_memory_type(const struct wsi_device *wsi,
uint32_t type_bits)
{
return select_memory_type(wsi,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
type_bits);
}
static VkResult
wsi_create_win32_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image)
{
const struct wsi_device *wsi = chain->wsi;
VkResult result;
VkMemoryRequirements reqs;
wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs);
const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.image = image->image,
.buffer = VK_NULL_HANDLE,
};
const VkMemoryAllocateInfo memory_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &memory_dedicated_info,
.allocationSize = reqs.size,
.memoryTypeIndex = select_memory_type(wsi, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
reqs.memoryTypeBits),
};
result = wsi->AllocateMemory(chain->device, &memory_info,
&chain->alloc, &image->memory);
VkResult result =
wsi_create_buffer_image_mem(chain, info, image, 0, false);
if (result != VK_SUCCESS)
return result;
@ -342,24 +344,31 @@ wsi_create_win32_image_mem(const struct wsi_swapchain *chain,
wsi->GetImageSubresourceLayout(chain->device, image->image,
&image_subresource, &image_layout);
image->num_planes = 1;
image->sizes[0] = reqs.size;
image->row_pitches[0] = image_layout.rowPitch;
image->offsets[0] = 0;
return VK_SUCCESS;
}
#define WSI_WIN32_LINEAR_STRIDE_ALIGN 256
static VkResult
wsi_configure_win32_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
struct wsi_image_info *info)
{
VkResult result = wsi_configure_image(chain, pCreateInfo, 0, info);
VkResult result =
wsi_configure_buffer_image(chain, pCreateInfo, info);
if (result != VK_SUCCESS)
return result;
info->create_mem = wsi_create_win32_image_mem;
info->select_image_memory_type = select_image_memory_type;
info->select_buffer_memory_type = select_buffer_memory_type;
const uint32_t cpp = vk_format_get_blocksize(info->create.format);
info->linear_stride = ALIGN_POT(info->create.extent.width * cpp,
WSI_WIN32_LINEAR_STRIDE_ALIGN);
info->size_align = 4096;
return VK_SUCCESS;
}
@ -392,6 +401,7 @@ wsi_win32_image_init(VkDevice device_h,
const VkAllocationCallbacks *allocator,
struct wsi_win32_image *image)
{
assert(chain->base.use_buffer_blit);
VkResult result = wsi_create_image(&chain->base, &chain->base.image_info,
&image->base);
if (result != VK_SUCCESS)
@ -491,10 +501,12 @@ wsi_win32_queue_present(struct wsi_swapchain *drv_chain,
struct wsi_win32_image *image = &chain->images[image_index];
VkResult result;
assert(chain->base.use_buffer_blit);
char *ptr;
char *dptr = image->ppvBits;
result = chain->base.wsi->MapMemory(chain->base.device,
image->base.memory,
image->base.buffer.memory,
0, image->base.sizes[0], 0, (void**)&ptr);
for (unsigned h = 0; h < chain->extent.height; h++) {
@ -507,7 +519,7 @@ wsi_win32_queue_present(struct wsi_swapchain *drv_chain,
else
result = VK_ERROR_MEMORY_MAP_FAILED;
chain->base.wsi->UnmapMemory(chain->base.device, image->base.memory);
chain->base.wsi->UnmapMemory(chain->base.device, image->base.buffer.memory);
if (result != VK_SUCCESS)
chain->status = result;
@ -562,6 +574,9 @@ wsi_win32_surface_create_swapchain(
chain->surface = surface;
assert(wsi_device->sw);
chain->base.use_buffer_blit = true;
result = wsi_configure_win32_image(&chain->base, create_info,
&chain->base.image_info);
if (result != VK_SUCCESS) {