diff options
Diffstat (limited to 'lib/mesa/src/vulkan/wsi/wsi_common_win32.c')
-rw-r--r-- | lib/mesa/src/vulkan/wsi/wsi_common_win32.c | 262 |
1 files changed, 193 insertions, 69 deletions
diff --git a/lib/mesa/src/vulkan/wsi/wsi_common_win32.c b/lib/mesa/src/vulkan/wsi/wsi_common_win32.c index bef81028b..fa6f898e5 100644 --- a/lib/mesa/src/vulkan/wsi/wsi_common_win32.c +++ b/lib/mesa/src/vulkan/wsi/wsi_common_win32.c @@ -26,12 +26,9 @@ #include <stdio.h> #include <string.h> -#include "vk_format.h" -#include "vk_instance.h" -#include "vk_physical_device.h" #include "vk_util.h" -#include "wsi_common_entrypoints.h" #include "wsi_common_private.h" +#include "wsi_common_win32.h" #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size @@ -70,37 +67,30 @@ struct wsi_win32_swapchain { struct wsi_win32_image images[0]; }; -VKAPI_ATTR VkBool32 VKAPI_CALL -wsi_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex) +VkBool32 +wsi_win32_get_presentation_support(struct wsi_device *wsi_device) { return TRUE; } -VKAPI_ATTR VkResult VKAPI_CALL -wsi_CreateWin32SurfaceKHR(VkInstance _instance, - const VkWin32SurfaceCreateInfoKHR *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkSurfaceKHR *pSurface) +VkResult +wsi_create_win32_surface(VkInstance instance, + const VkAllocationCallbacks *allocator, + const VkWin32SurfaceCreateInfoKHR *create_info, + VkSurfaceKHR *surface_khr) { - VK_FROM_HANDLE(vk_instance, instance, _instance); - VkIcdSurfaceWin32 *surface; - - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR); - - surface = vk_zalloc2(&instance->alloc, pAllocator, sizeof(*surface), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + VkIcdSurfaceWin32 *surface = vk_zalloc(allocator, sizeof *surface, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (surface == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY; surface->base.platform = VK_ICD_WSI_PLATFORM_WIN32; - surface->hinstance = pCreateInfo->hinstance; - surface->hwnd = pCreateInfo->hwnd; - - *pSurface = VkIcdSurfaceBase_to_handle(&surface->base); + surface->hinstance = create_info->hinstance; + surface->hwnd = create_info->hwnd; + *surface_khr = VkIcdSurfaceBase_to_handle(&surface->base); return VK_SUCCESS; } @@ -116,24 +106,15 @@ wsi_win32_surface_get_support(VkIcdSurfaceBase *surface, } static VkResult -wsi_win32_surface_get_capabilities(VkIcdSurfaceBase *surf, +wsi_win32_surface_get_capabilities(VkIcdSurfaceBase *surface, struct wsi_device *wsi_device, VkSurfaceCapabilitiesKHR* caps) { - VkIcdSurfaceWin32 *surface = (VkIcdSurfaceWin32 *)surf; - - RECT win_rect; - if (!GetClientRect(surface->hwnd, &win_rect)) - return VK_ERROR_SURFACE_LOST_KHR; - caps->minImageCount = 1; /* There is no real maximum */ caps->maxImageCount = 0; - caps->currentExtent = (VkExtent2D) { - win_rect.right - win_rect.left, - win_rect.bottom - win_rect.top - }; + caps->currentExtent = (VkExtent2D) { UINT32_MAX, UINT32_MAX }; caps->minImageExtent = (VkExtent2D) { 1, 1 }; caps->maxImageExtent = (VkExtent2D) { wsi_device->maxImageDimension2D, @@ -153,8 +134,7 @@ wsi_win32_surface_get_capabilities(VkIcdSurfaceBase *surf, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; return VK_SUCCESS; } @@ -228,7 +208,7 @@ wsi_win32_surface_get_formats(VkIcdSurfaceBase *icd_surface, for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) { vk_outarray_append_typed(VkSurfaceFormatKHR, &out, f) { f->format = sorted_formats[i]; - f->colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + f->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; } } @@ -251,7 +231,7 @@ wsi_win32_surface_get_formats2(VkIcdSurfaceBase *icd_surface, vk_outarray_append_typed(VkSurfaceFormat2KHR, &out, f) { assert(f->sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR); f->surfaceFormat.format = sorted_formats[i]; - f->surfaceFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + f->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; } } @@ -301,16 +281,155 @@ wsi_win32_surface_get_present_rectangles(VkIcdSurfaceBase *surface, return vk_outarray_status(&out); } +static uint32_t +select_memory_type(const struct wsi_device *wsi, + VkMemoryPropertyFlags props, + uint32_t type_bits) +{ + for (uint32_t i = 0; i < wsi->memory_props.memoryTypeCount; i++) { + const VkMemoryType type = wsi->memory_props.memoryTypes[i]; + if ((type_bits & (1 << i)) && (type.propertyFlags & props) == props) + return i; + } + + unreachable("No memory type found"); +} + +VkResult +wsi_create_native_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + uint32_t num_modifier_lists, + const uint32_t *num_modifiers, + const uint64_t *const *modifiers, + struct wsi_image *image) +{ + const struct wsi_device *wsi = chain->wsi; + VkResult result; + + memset(image, 0, sizeof(*image)); + for (int i = 0; i < ARRAY_SIZE(image->fds); i++) + image->fds[i] = -1; + + VkImageCreateInfo image_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .flags = 0, + .imageType = VK_IMAGE_TYPE_2D, + .format = pCreateInfo->imageFormat, + .extent = { + .width = pCreateInfo->imageExtent.width, + .height = pCreateInfo->imageExtent.height, + .depth = 1, + }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = pCreateInfo->imageUsage, + .sharingMode = pCreateInfo->imageSharingMode, + .queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount, + .pQueueFamilyIndices = pCreateInfo->pQueueFamilyIndices, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + VkImageFormatListCreateInfoKHR image_format_list; + if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) { + image_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR; + + const VkImageFormatListCreateInfoKHR *format_list = + vk_find_struct_const(pCreateInfo->pNext, + IMAGE_FORMAT_LIST_CREATE_INFO_KHR); + +#ifndef NDEBUG + assume(format_list && format_list->viewFormatCount > 0); + bool format_found = false; + for (int i = 0; i < format_list->viewFormatCount; i++) + if (pCreateInfo->imageFormat == format_list->pViewFormats[i]) + format_found = true; + assert(format_found); +#endif + + image_format_list = *format_list; + image_format_list.pNext = NULL; + __vk_append_struct(&image_info, &image_format_list); + } + + + result = wsi->CreateImage(chain->device, &image_info, + &chain->alloc, &image->image); + if (result != VK_SUCCESS) + goto fail; + + VkMemoryRequirements reqs; + wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs); + + const struct wsi_memory_allocate_info memory_wsi_info = { + .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA, + .pNext = NULL, + .implicit_sync = true, + }; + const VkExportMemoryAllocateInfo memory_export_info = { + .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, + .pNext = &memory_wsi_info, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + const VkMemoryDedicatedAllocateInfo memory_dedicated_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = &memory_export_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_DEVICE_LOCAL_BIT, + reqs.memoryTypeBits), + }; + result = wsi->AllocateMemory(chain->device, &memory_info, + &chain->alloc, &image->memory); + if (result != VK_SUCCESS) + goto fail; + + result = wsi->BindImageMemory(chain->device, image->image, + image->memory, 0); + if (result != VK_SUCCESS) + goto fail; + + const VkImageSubresource image_subresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .arrayLayer = 0, + }; + VkSubresourceLayout image_layout; + 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; + +fail: + wsi_destroy_image(chain, image); + + return result; +} + static VkResult wsi_win32_image_init(VkDevice device_h, - struct wsi_win32_swapchain *chain, - const VkSwapchainCreateInfoKHR *create_info, - const VkAllocationCallbacks *allocator, - struct wsi_win32_image *image) + struct wsi_swapchain *drv_chain, + const VkSwapchainCreateInfoKHR *create_info, + 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); + struct wsi_win32_swapchain *chain = (struct wsi_win32_swapchain *) drv_chain; + + VkResult result = wsi_create_native_image(&chain->base, create_info, + 0, NULL, NULL, + &image->base); if (result != VK_SUCCESS) return result; @@ -345,10 +464,13 @@ wsi_win32_image_init(VkDevice device_h, } static void -wsi_win32_image_finish(struct wsi_win32_swapchain *chain, - const VkAllocationCallbacks *allocator, - struct wsi_win32_image *image) +wsi_win32_image_finish(struct wsi_swapchain *drv_chain, + const VkAllocationCallbacks *allocator, + struct wsi_win32_image *image) { + struct wsi_win32_swapchain *chain = + (struct wsi_win32_swapchain *) drv_chain; + DeleteDC(image->dc); if(image->bmp) DeleteObject(image->bmp); @@ -363,7 +485,7 @@ wsi_win32_swapchain_destroy(struct wsi_swapchain *drv_chain, (struct wsi_win32_swapchain *) drv_chain; for (uint32_t i = 0; i < chain->base.image_count; i++) - wsi_win32_image_finish(chain, allocator, &chain->images[i]); + wsi_win32_image_finish(drv_chain, allocator, &chain->images[i]); DeleteDC(chain->chain_dc); @@ -406,19 +528,30 @@ wsi_win32_queue_present(struct wsi_swapchain *drv_chain, struct wsi_win32_swapchain *chain = (struct wsi_win32_swapchain *) drv_chain; assert(image_index < chain->base.image_count); struct wsi_win32_image *image = &chain->images[image_index]; + VkResult result; - assert(chain->base.use_buffer_blit); - - char *ptr = image->base.cpu_map; + char *ptr; char *dptr = image->ppvBits; + result = chain->base.wsi->MapMemory(chain->base.device, + image->base.memory, + 0, 0, 0, (void**)&ptr); for (unsigned h = 0; h < chain->extent.height; h++) { memcpy(dptr, ptr, chain->extent.width * 4); dptr += image->bmp_row_pitch; ptr += image->base.row_pitches[0]; } - if (!StretchBlt(chain->chain_dc, 0, 0, chain->extent.width, chain->extent.height, image->dc, 0, 0, chain->extent.width, chain->extent.height, SRCCOPY)) - chain->status = VK_ERROR_MEMORY_MAP_FAILED; + if(StretchBlt(chain->chain_dc, 0, 0, chain->extent.width, chain->extent.height, image->dc, 0, 0, chain->extent.width, chain->extent.height, SRCCOPY)) + result = VK_SUCCESS; + else + result = VK_ERROR_MEMORY_MAP_FAILED; + + chain->base.wsi->UnmapMemory(chain->base.device, image->base.memory); + if (result != VK_SUCCESS) + chain->status = result; + + if (result != VK_SUCCESS) + return result; return chain->status; } @@ -448,13 +581,8 @@ wsi_win32_surface_create_swapchain( if (chain == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY; - struct wsi_cpu_image_params image_params = { - .base.image_type = WSI_IMAGE_TYPE_CPU, - }; - VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device, - create_info, &image_params.base, - allocator); + create_info, allocator); if (result != VK_SUCCESS) { vk_free(allocator, chain); return result; @@ -473,20 +601,16 @@ wsi_win32_surface_create_swapchain( chain->surface = surface; - assert(wsi_device->sw); - chain->base.use_buffer_blit = true; - for (uint32_t image = 0; image < chain->base.image_count; image++) { - result = wsi_win32_image_init(device, chain, - create_info, allocator, - &chain->images[image]); + result = wsi_win32_image_init(device, &chain->base, + create_info, allocator, + &chain->images[image]); if (result != VK_SUCCESS) { while (image > 0) { --image; - wsi_win32_image_finish(chain, allocator, - &chain->images[image]); + wsi_win32_image_finish(&chain->base, allocator, + &chain->images[image]); } - wsi_swapchain_finish(&chain->base); vk_free(allocator, chain); goto fail_init_images; } |