From 1720bbd353d87412754fd4ecb6fa76406d54d413 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 14 Oct 2016 01:34:10 +0100 Subject: [PATCH] anv/wsi: split image alloc/free out to separate fns. This moves these outside the wsi platform code, so we can reuse that code Reviewed-by: Jason Ekstrand --- src/intel/vulkan/anv_wsi.c | 121 +++++++++++++++++++++++++++++++- src/intel/vulkan/anv_wsi.h | 19 ++++- src/intel/vulkan/anv_wsi_wayland.c | 120 +++++++------------------------- src/intel/vulkan/anv_wsi_x11.c | 139 +++++-------------------------------- 4 files changed, 180 insertions(+), 219 deletions(-) diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index f91e6f66304..514a29f0b5c 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -22,7 +22,7 @@ */ #include "anv_wsi.h" - +#include "vk_format_info.h" VkResult anv_init_wsi(struct anv_physical_device *physical_device) { @@ -126,6 +126,122 @@ VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR( pPresentModes); } + +static VkResult +x11_anv_wsi_image_create(VkDevice device_h, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImage *image_p, + VkDeviceMemory *memory_p, + uint32_t *size, + uint32_t *offset, + uint32_t *row_pitch, int *fd_p) +{ + struct anv_device *device = anv_device_from_handle(device_h); + VkImage image_h; + struct anv_image *image; + + VkResult result; + result = anv_image_create(anv_device_to_handle(device), + &(struct anv_image_create_info) { + .isl_tiling_flags = ISL_TILING_X_BIT, + .stride = 0, + .vk_info = + &(VkImageCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = VK_IMAGE_TYPE_2D, + .format = pCreateInfo->imageFormat, + .extent = { + .width = pCreateInfo->imageExtent.width, + .height = pCreateInfo->imageExtent.height, + .depth = 1 + }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = 1, + /* FIXME: Need a way to use X tiling to allow scanout */ + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = (pCreateInfo->imageUsage | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT), + .flags = 0, + }}, + NULL, + &image_h); + if (result != VK_SUCCESS) + return result; + + image = anv_image_from_handle(image_h); + assert(vk_format_is_color(image->vk_format)); + + VkDeviceMemory memory_h; + struct anv_device_memory *memory; + result = anv_AllocateMemory(anv_device_to_handle(device), + &(VkMemoryAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = image->size, + .memoryTypeIndex = 0, + }, + NULL /* XXX: pAllocator */, + &memory_h); + if (result != VK_SUCCESS) + goto fail_create_image; + + memory = anv_device_memory_from_handle(memory_h); + memory->bo.is_winsys_bo = true; + + anv_BindImageMemory(VK_NULL_HANDLE, image_h, memory_h, 0); + + struct anv_surface *surface = &image->color_surface; + assert(surface->isl.tiling == ISL_TILING_X); + + *row_pitch = surface->isl.row_pitch; + int ret = anv_gem_set_tiling(device, memory->bo.gem_handle, + surface->isl.row_pitch, I915_TILING_X); + if (ret) { + /* FINISHME: Choose a better error. */ + result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, + "set_tiling failed: %m"); + goto fail_alloc_memory; + } + + int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle); + if (fd == -1) { + /* FINISHME: Choose a better error. */ + result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, + "handle_to_fd failed: %m"); + goto fail_alloc_memory; + } + + *image_p = image_h; + *memory_p = memory_h; + *fd_p = fd; + *size = image->size; + *offset = image->offset; + return VK_SUCCESS; +fail_alloc_memory: + anv_FreeMemory(device_h, memory_h, pAllocator); + +fail_create_image: + anv_DestroyImage(device_h, image_h, pAllocator); + return result; +} + +static void +x11_anv_wsi_image_free(VkDevice device, + const VkAllocationCallbacks* pAllocator, + VkImage image_h, + VkDeviceMemory memory_h) +{ + anv_DestroyImage(device, image_h, pAllocator); + + anv_FreeMemory(device, memory_h, pAllocator); +} + +static const struct anv_wsi_image_fns anv_wsi_image_fns = { + .create_wsi_image = x11_anv_wsi_image_create, + .free_wsi_image = x11_anv_wsi_image_free, +}; + VkResult anv_CreateSwapchainKHR( VkDevice _device, const VkSwapchainCreateInfoKHR* pCreateInfo, @@ -139,7 +255,8 @@ VkResult anv_CreateSwapchainKHR( struct anv_swapchain *swapchain; VkResult result = iface->create_swapchain(surface, device, pCreateInfo, - pAllocator, &swapchain); + pAllocator, &anv_wsi_image_fns, + &swapchain); if (result != VK_SUCCESS) return result; diff --git a/src/intel/vulkan/anv_wsi.h b/src/intel/vulkan/anv_wsi.h index 1b7147dd417..2548e412c12 100644 --- a/src/intel/vulkan/anv_wsi.h +++ b/src/intel/vulkan/anv_wsi.h @@ -28,6 +28,22 @@ struct anv_swapchain; +struct anv_wsi_image_fns { + VkResult (*create_wsi_image)(VkDevice device_h, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkImage *image_p, + VkDeviceMemory *memory_p, + uint32_t *size_p, + uint32_t *offset_p, + uint32_t *row_pitch_p, + int *fd_p); + void (*free_wsi_image)(VkDevice device, + const VkAllocationCallbacks *pAllocator, + VkImage image_h, + VkDeviceMemory memory_h); +}; + struct anv_wsi_interface { VkResult (*get_support)(VkIcdSurfaceBase *surface, struct anv_wsi_device *wsi_device, @@ -47,6 +63,7 @@ struct anv_wsi_interface { struct anv_device *device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, + const struct anv_wsi_image_fns *image_fns, struct anv_swapchain **swapchain); }; @@ -54,7 +71,7 @@ struct anv_swapchain { VkDevice device; VkAllocationCallbacks alloc; - + const struct anv_wsi_image_fns *image_fns; VkFence fences[3]; VkResult (*destroy)(struct anv_swapchain *swapchain, diff --git a/src/intel/vulkan/anv_wsi_wayland.c b/src/intel/vulkan/anv_wsi_wayland.c index dc239c96e75..e56b3befa65 100644 --- a/src/intel/vulkan/anv_wsi_wayland.c +++ b/src/intel/vulkan/anv_wsi_wayland.c @@ -427,6 +427,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *surface, struct anv_device *device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, + const struct anv_wsi_image_fns *image_fns, struct anv_swapchain **swapchain); VkResult anv_CreateWaylandSurfaceKHR( @@ -456,8 +457,8 @@ VkResult anv_CreateWaylandSurfaceKHR( } struct wsi_wl_image { - struct anv_image * image; - struct anv_device_memory * memory; + VkImage image; + VkDeviceMemory memory; struct wl_buffer * buffer; bool busy; }; @@ -493,7 +494,7 @@ wsi_wl_swapchain_get_images(struct anv_swapchain *anv_chain, assert(chain->image_count <= *pCount); for (uint32_t i = 0; i < chain->image_count; i++) - pSwapchainImages[i] = anv_image_to_handle(chain->images[i].image); + pSwapchainImages[i] = chain->images[i].image; *pCount = chain->image_count; @@ -585,17 +586,6 @@ wsi_wl_swapchain_queue_present(struct anv_swapchain *anv_chain, } static void -wsi_wl_image_finish(struct wsi_wl_swapchain *chain, struct wsi_wl_image *image, - const VkAllocationCallbacks* pAllocator) -{ - VkDevice vk_device = chain->base.device; - anv_FreeMemory(vk_device, anv_device_memory_to_handle(image->memory), - pAllocator); - anv_DestroyImage(vk_device, anv_image_to_handle(image->image), - pAllocator); -} - -static void buffer_handle_release(void *data, struct wl_buffer *buffer) { struct wsi_wl_image *image = data; @@ -616,89 +606,30 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, const VkAllocationCallbacks* pAllocator) { VkDevice vk_device = chain->base.device; - struct anv_device *device = anv_device_from_handle(vk_device); VkResult result; - - VkImage vk_image; - result = anv_image_create(vk_device, - &(struct anv_image_create_info) { - .isl_tiling_flags = ISL_TILING_X_BIT, - .stride = 0, - .vk_info = - &(VkImageCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .imageType = VK_IMAGE_TYPE_2D, - .format = chain->vk_format, - .extent = { - .width = chain->extent.width, - .height = chain->extent.height, - .depth = 1 - }, - .mipLevels = 1, - .arrayLayers = 1, - .samples = 1, - /* FIXME: Need a way to use X tiling to allow scanout */ - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - pCreateInfo->imageUsage), - .flags = 0, - }}, - pAllocator, - &vk_image); - + int fd; + uint32_t size; + uint32_t row_pitch; + uint32_t offset; + result = chain->base.image_fns->create_wsi_image(vk_device, + pCreateInfo, + pAllocator, + &image->image, + &image->memory, + &size, + &offset, + &row_pitch, + &fd); if (result != VK_SUCCESS) return result; - image->image = anv_image_from_handle(vk_image); - assert(vk_format_is_color(image->image->vk_format)); - - struct anv_surface *surface = &image->image->color_surface; - - VkDeviceMemory vk_memory; - result = anv_AllocateMemory(vk_device, - &(VkMemoryAllocateInfo) { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .allocationSize = image->image->size, - .memoryTypeIndex = 0, - }, - pAllocator, - &vk_memory); - - if (result != VK_SUCCESS) - goto fail_image; - - image->memory = anv_device_memory_from_handle(vk_memory); - image->memory->bo.is_winsys_bo = true; - - result = anv_BindImageMemory(vk_device, vk_image, vk_memory, 0); - - if (result != VK_SUCCESS) - goto fail_mem; - - int ret = anv_gem_set_tiling(device, - image->memory->bo.gem_handle, - surface->isl.row_pitch, I915_TILING_X); - if (ret) { - /* FINISHME: Choose a better error. */ - result = vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY); - goto fail_mem; - } - - int fd = anv_gem_handle_to_fd(device, - image->memory->bo.gem_handle); - if (fd == -1) { - /* FINISHME: Choose a better error. */ - result = vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY); - goto fail_mem; - } - image->buffer = wl_drm_create_prime_buffer(chain->display->drm, fd, /* name */ chain->extent.width, chain->extent.height, chain->drm_format, - surface->offset, - surface->isl.row_pitch, + offset, + row_pitch, 0, 0, 0, 0 /* unused */); wl_display_roundtrip(chain->display->display); close(fd); @@ -708,10 +639,8 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, return VK_SUCCESS; -fail_mem: - anv_FreeMemory(vk_device, vk_memory, pAllocator); -fail_image: - anv_DestroyImage(vk_device, vk_image, pAllocator); + chain->base.image_fns->free_wsi_image(vk_device, pAllocator, + image->image, image->memory); return result; } @@ -724,7 +653,9 @@ wsi_wl_swapchain_destroy(struct anv_swapchain *anv_chain, struct anv_device *device = anv_device_from_handle(chain->base.device); for (uint32_t i = 0; i < chain->image_count; i++) { if (chain->images[i].buffer) - wsi_wl_image_finish(chain, &chain->images[i], pAllocator); + chain->base.image_fns->free_wsi_image(chain->base.device, pAllocator, + chain->images[i].image, + chain->images[i].memory); } vk_free2(&device->alloc, pAllocator, chain); @@ -737,6 +668,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, struct anv_device *device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, + const struct anv_wsi_image_fns *image_fns, struct anv_swapchain **swapchain_out) { VkIcdSurfaceWayland *surface = (VkIcdSurfaceWayland *)icd_surface; @@ -769,7 +701,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.get_images = wsi_wl_swapchain_get_images; chain->base.acquire_next_image = wsi_wl_swapchain_acquire_next_image; chain->base.queue_present = wsi_wl_swapchain_queue_present; - + chain->base.image_fns = image_fns; chain->surface = surface->surface; chain->extent = pCreateInfo->imageExtent; chain->vk_format = pCreateInfo->imageFormat; diff --git a/src/intel/vulkan/anv_wsi_x11.c b/src/intel/vulkan/anv_wsi_x11.c index 8f9f7418090..54fe05701b9 100644 --- a/src/intel/vulkan/anv_wsi_x11.c +++ b/src/intel/vulkan/anv_wsi_x11.c @@ -439,6 +439,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *surface, struct anv_device *device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, + const struct anv_wsi_image_fns *image_fns, struct anv_swapchain **swapchain); VkResult anv_CreateXcbSurfaceKHR( @@ -652,115 +653,6 @@ x11_queue_present(struct anv_swapchain *anv_chain, } static VkResult -x11_anv_create_image(VkDevice device_h, - struct x11_swapchain *chain, - const VkSwapchainCreateInfoKHR *pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImage *image_p, - VkDeviceMemory *memory_p, - uint32_t *size, - uint32_t *row_pitch, int *fd_p) -{ - struct anv_device *device = anv_device_from_handle(device_h); - VkImage image_h; - struct anv_image *image; - - VkResult result; - result = anv_image_create(anv_device_to_handle(device), - &(struct anv_image_create_info) { - .isl_tiling_flags = ISL_TILING_X_BIT, - .stride = 0, - .vk_info = - &(VkImageCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .imageType = VK_IMAGE_TYPE_2D, - .format = pCreateInfo->imageFormat, - .extent = { - .width = pCreateInfo->imageExtent.width, - .height = pCreateInfo->imageExtent.height, - .depth = 1 - }, - .mipLevels = 1, - .arrayLayers = 1, - .samples = 1, - /* FIXME: Need a way to use X tiling to allow scanout */ - .tiling = VK_IMAGE_TILING_OPTIMAL, - .usage = (pCreateInfo->imageUsage | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT), - .flags = 0, - }}, - NULL, - &image_h); - if (result != VK_SUCCESS) - return result; - - image = anv_image_from_handle(image_h); - assert(vk_format_is_color(image->vk_format)); - - VkDeviceMemory memory_h; - struct anv_device_memory *memory; - result = anv_AllocateMemory(anv_device_to_handle(device), - &(VkMemoryAllocateInfo) { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .allocationSize = image->size, - .memoryTypeIndex = 0, - }, - NULL /* XXX: pAllocator */, - &memory_h); - if (result != VK_SUCCESS) - goto fail_create_image; - - memory = anv_device_memory_from_handle(memory_h); - memory->bo.is_winsys_bo = true; - - anv_BindImageMemory(VK_NULL_HANDLE, image_h, memory_h, 0); - - struct anv_surface *surface = &image->color_surface; - assert(surface->isl.tiling == ISL_TILING_X); - - *row_pitch = surface->isl.row_pitch; - int ret = anv_gem_set_tiling(device, memory->bo.gem_handle, - surface->isl.row_pitch, I915_TILING_X); - if (ret) { - /* FINISHME: Choose a better error. */ - result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, - "set_tiling failed: %m"); - goto fail_alloc_memory; - } - - int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle); - if (fd == -1) { - /* FINISHME: Choose a better error. */ - result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, - "handle_to_fd failed: %m"); - goto fail_alloc_memory; - } - - *image_p = image_h; - *memory_p = memory_h; - *fd_p = fd; - *size = image->size; - return VK_SUCCESS; -fail_alloc_memory: - anv_FreeMemory(device_h, memory_h, pAllocator); - -fail_create_image: - anv_DestroyImage(device_h, image_h, pAllocator); - return result; -} - -static void -x11_anv_free_image(VkDevice device, - const VkAllocationCallbacks* pAllocator) - VkImage image_h, - VkDeviceMemory memory_h) -{ - anv_DestroyImage(device, image_h, pAllocator); - - anv_FreeMemory(device, memory_h, pAllocator); -} - -static VkResult x11_image_init(VkDevice device_h, struct x11_swapchain *chain, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -769,19 +661,21 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, xcb_void_cookie_t cookie; VkResult result; uint32_t row_pitch; + uint32_t offset; uint32_t bpp = 32; uint32_t depth = 24; int fd; uint32_t size; - result = x11_anv_create_image(device_h, - pCreateInfo, - pAllocator, - &image->image, - &image->memory, - &size, - &row_pitch, - &fd); + result = chain->base.image_fns->create_wsi_image(device_h, + pCreateInfo, + pAllocator, + &image->image, + &image->memory, + &size, + &offset, + &row_pitch, + &fd); if (result != VK_SUCCESS) return result; @@ -825,8 +719,8 @@ fail_pixmap: cookie = xcb_free_pixmap(chain->conn, image->pixmap); xcb_discard_reply(chain->conn, cookie.sequence); - x11_anv_free_image(device_h, pAllocator, - image->image, image->memory); + chain->base.image_fns->free_wsi_image(device_h, pAllocator, + image->image, image->memory); return result; } @@ -844,8 +738,8 @@ x11_image_finish(struct x11_swapchain *chain, cookie = xcb_free_pixmap(chain->conn, image->pixmap); xcb_discard_reply(chain->conn, cookie.sequence); - x11_anv_free_image(chain->base.device, pAllocator, - image->image, image->memory); + chain->base.image_fns->free_wsi_image(chain->base.device, pAllocator, + image->image, image->memory); } static VkResult @@ -869,6 +763,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, struct anv_device *device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, + const struct anv_wsi_image_fns *image_fns, struct anv_swapchain **swapchain_out) { struct x11_swapchain *chain; @@ -899,7 +794,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.get_images = x11_get_images; chain->base.acquire_next_image = x11_acquire_next_image; chain->base.queue_present = x11_queue_present; - + chain->base.image_fns = image_fns; chain->conn = x11_surface_get_connection(icd_surface); chain->window = x11_surface_get_window(icd_surface); chain->extent = pCreateInfo->imageExtent; -- 2.11.0