*/
#include "anv_wsi.h"
-
+#include "vk_format_info.h"
VkResult
anv_init_wsi(struct anv_physical_device *physical_device)
{
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,
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;
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,
struct anv_device *device,
const VkSwapchainCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
+ const struct anv_wsi_image_fns *image_fns,
struct anv_swapchain **swapchain);
};
VkDevice device;
VkAllocationCallbacks alloc;
-
+ const struct anv_wsi_image_fns *image_fns;
VkFence fences[3];
VkResult (*destroy)(struct anv_swapchain *swapchain,
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(
}
struct wsi_wl_image {
- struct anv_image * image;
- struct anv_device_memory * memory;
+ VkImage image;
+ VkDeviceMemory memory;
struct wl_buffer * buffer;
bool busy;
};
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;
return VK_SUCCESS;
}
-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)
{
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);
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;
}
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);
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;
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;
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(
return VK_SUCCESS;
}
-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,
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;
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;
}
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
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;
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;