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:
parent
2e8c119531
commit
5c5243adb7
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue