vk/WSI: Use a callback mechanism instead of explicit switching

This commit is contained in:
Jason Ekstrand
2015-09-04 10:28:26 -07:00
parent ca3cfbf6f1
commit c0b97577e8
3 changed files with 114 additions and 137 deletions

View File

@@ -103,12 +103,7 @@ anv_DestroySwapChainWSI(
assert(swap_chain->device == anv_device_from_handle(device));
switch (swap_chain->type) {
case ANV_SWAP_CHAIN_TYPE_X11:
return anv_x11_destroy_swap_chain((void *)swap_chain);
default:
return vk_error(VK_ERROR_INVALID_VALUE);
}
return swap_chain->destroy(swap_chain);
}
VkResult
@@ -123,13 +118,8 @@ anv_GetSwapChainInfoWSI(
assert(swap_chain->device == anv_device_from_handle(device));
switch (swap_chain->type) {
case ANV_SWAP_CHAIN_TYPE_X11:
return anv_x11_get_swap_chain_info((void *)swap_chain,
infoType, pDataSize, pData);
default:
return vk_error(VK_ERROR_INVALID_VALUE);
}
return swap_chain->get_swap_chain_info(swap_chain, infoType,
pDataSize, pData);
}
VkResult
@@ -144,13 +134,8 @@ anv_AcquireNextImageWSI(
assert(swap_chain->device == anv_device_from_handle(device));
switch (swap_chain->type) {
case ANV_SWAP_CHAIN_TYPE_X11:
return anv_x11_acquire_next_image((void *)swap_chain,
timeout, semaphore, pImageIndex);
default:
return vk_error(VK_ERROR_INVALID_VALUE);
}
return swap_chain->acquire_next_image(swap_chain,
timeout, semaphore, pImageIndex);
}
VkResult
@@ -166,19 +151,11 @@ anv_QueuePresentWSI(
assert(swap_chain->device == queue->device);
switch (swap_chain->type) {
case ANV_SWAP_CHAIN_TYPE_X11:
result = anv_x11_queue_present(queue, (void *)swap_chain,
pPresentInfo->imageIndices[i]);
/* TODO: What if one of them returns OUT_OF_DATE? */
if (result != VK_SUCCESS)
return result;
else
continue;
default:
return vk_error(VK_ERROR_INVALID_VALUE);
}
result = swap_chain->queue_present(swap_chain, queue,
pPresentInfo->imageIndices[i]);
/* TODO: What if one of them returns OUT_OF_DATE? */
if (result != VK_SUCCESS)
return result;
}
return VK_SUCCESS;

View File

@@ -25,17 +25,20 @@
#include "anv_private.h"
enum anv_swap_chain_type {
ANV_SWAP_CHAIN_TYPE_X11 = 11,
};
struct anv_swap_chain {
enum anv_swap_chain_type type;
struct anv_device * device;
};
struct anv_x11_swap_chain;
VkResult (*destroy)(struct anv_swap_chain *swap_chain);
VkResult (*get_swap_chain_info)(struct anv_swap_chain *swap_chain,
VkSwapChainInfoTypeWSI infoType,
size_t *pDataSize, void *pData);
VkResult (*acquire_next_image)(struct anv_swap_chain *swap_chain,
uint64_t timeout, VkSemaphore semaphore,
uint32_t *image_index);
VkResult (*queue_present)(struct anv_swap_chain *swap_chain,
struct anv_queue *queue,
uint32_t image_index);
};
ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_swap_chain, VkSwapChainWSI)
@@ -45,15 +48,4 @@ VkResult anv_x11_get_surface_info(struct anv_device *device,
size_t* pDataSize, void* pData);
VkResult anv_x11_create_swap_chain(struct anv_device *device,
const VkSwapChainCreateInfoWSI *pCreateInfo,
struct anv_x11_swap_chain **swap_chain);
VkResult anv_x11_destroy_swap_chain(struct anv_x11_swap_chain *swap_chain);
VkResult anv_x11_get_swap_chain_info(struct anv_x11_swap_chain *swap_chain,
VkSwapChainInfoTypeWSI infoType,
size_t* pDataSize, void* pData);
VkResult anv_x11_acquire_next_image(struct anv_x11_swap_chain *swap_chain,
uint64_t timeout,
VkSemaphore semaphore,
uint32_t *image_index);
VkResult anv_x11_queue_present(struct anv_queue *queue,
struct anv_x11_swap_chain *swap_chain,
uint32_t image_index);
struct anv_swap_chain **swap_chain);

View File

@@ -92,7 +92,7 @@ anv_x11_get_surface_info(struct anv_device *device,
}
}
struct anv_x11_swap_chain {
struct x11_swap_chain {
struct anv_swap_chain base;
xcb_connection_t * conn;
@@ -108,12 +108,96 @@ struct anv_x11_swap_chain {
} images[0];
};
static VkResult
x11_get_swap_chain_info(struct anv_swap_chain *anv_chain,
VkSwapChainInfoTypeWSI infoType,
size_t* pDataSize, void* pData)
{
struct x11_swap_chain *chain = (struct x11_swap_chain *)anv_chain;
size_t size;
switch (infoType) {
case VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI: {
VkSwapChainImagePropertiesWSI *images = pData;
size = chain->image_count * sizeof(*images);
if (pData == NULL) {
*pDataSize = size;
return VK_SUCCESS;
}
assert(size <= *pDataSize);
for (uint32_t i = 0; i < chain->image_count; i++)
images[i].image = anv_image_to_handle(chain->images[i].image);
*pDataSize = size;
return VK_SUCCESS;
}
default:
return vk_error(VK_ERROR_INVALID_VALUE);
}
}
static VkResult
x11_acquire_next_image(struct anv_swap_chain *anv_chain,
uint64_t timeout,
VkSemaphore semaphore,
uint32_t *image_index)
{
struct x11_swap_chain *chain = (struct x11_swap_chain *)anv_chain;
anv_finishme("Implement real blocking AcquireNextImage");
*image_index = chain->next_image;
chain->next_image = (chain->next_image + 1) % chain->image_count;
return VK_SUCCESS;
}
static VkResult
x11_queue_present(struct anv_swap_chain *anv_chain,
struct anv_queue *queue,
uint32_t image_index)
{
struct x11_swap_chain *chain = (struct x11_swap_chain *)anv_chain;
xcb_void_cookie_t cookie;
xcb_pixmap_t pixmap = chain->images[image_index].pixmap;
if (pixmap == XCB_NONE)
return vk_error(VK_ERROR_INVALID_VALUE);
cookie = xcb_copy_area(chain->conn,
pixmap,
chain->window,
chain->gc,
0, 0,
0, 0,
chain->extent.width,
chain->extent.height);
xcb_discard_reply(chain->conn, cookie.sequence);
xcb_flush(chain->conn);
return VK_SUCCESS;
}
static VkResult
x11_destroy_swap_chain(struct anv_swap_chain *chain)
{
anv_device_free(chain->device, chain);
return VK_SUCCESS;
}
VkResult
anv_x11_create_swap_chain(struct anv_device *device,
const VkSwapChainCreateInfoWSI *pCreateInfo,
struct anv_x11_swap_chain **swap_chain_out)
struct anv_swap_chain **swap_chain_out)
{
struct anv_x11_swap_chain *chain;
struct x11_swap_chain *chain;
xcb_void_cookie_t cookie;
VkResult result;
@@ -133,8 +217,11 @@ anv_x11_create_swap_chain(struct anv_device *device,
if (chain == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
chain->base.type = ANV_SWAP_CHAIN_TYPE_X11;
chain->base.device = device;
chain->base.destroy = x11_destroy_swap_chain;
chain->base.get_swap_chain_info = x11_get_swap_chain_info;
chain->base.acquire_next_image = x11_acquire_next_image;
chain->base.queue_present = x11_queue_present;
VkPlatformHandleXcbWSI *vk_xcb_handle = vk_window->pPlatformHandle;
@@ -241,89 +328,10 @@ anv_x11_create_swap_chain(struct anv_device *device,
(uint32_t []) { 0 });
xcb_discard_reply(chain->conn, cookie.sequence);
*swap_chain_out = chain;
*swap_chain_out = &chain->base;
return VK_SUCCESS;
fail:
return result;
}
VkResult
anv_x11_destroy_swap_chain(struct anv_x11_swap_chain *chain)
{
anv_device_free(chain->base.device, chain);
return VK_SUCCESS;
}
VkResult
anv_x11_get_swap_chain_info(struct anv_x11_swap_chain *chain,
VkSwapChainInfoTypeWSI infoType,
size_t* pDataSize, void* pData)
{
size_t size;
switch (infoType) {
case VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI: {
VkSwapChainImagePropertiesWSI *images = pData;
size = chain->image_count * sizeof(*images);
if (pData == NULL) {
*pDataSize = size;
return VK_SUCCESS;
}
assert(size <= *pDataSize);
for (uint32_t i = 0; i < chain->image_count; i++)
images[i].image = anv_image_to_handle(chain->images[i].image);
*pDataSize = size;
return VK_SUCCESS;
}
default:
return vk_error(VK_ERROR_INVALID_VALUE);
}
}
VkResult
anv_x11_acquire_next_image(struct anv_x11_swap_chain *chain,
uint64_t timeout,
VkSemaphore semaphore,
uint32_t *image_index)
{
anv_finishme("Implement real blocking AcquireNextImage");
*image_index = chain->next_image;
chain->next_image = (chain->next_image + 1) % chain->image_count;
return VK_SUCCESS;
}
VkResult
anv_x11_queue_present(struct anv_queue *queue,
struct anv_x11_swap_chain *chain,
uint32_t image_index)
{
xcb_void_cookie_t cookie;
xcb_pixmap_t pixmap = chain->images[image_index].pixmap;
if (pixmap == XCB_NONE)
return vk_error(VK_ERROR_INVALID_VALUE);
cookie = xcb_copy_area(chain->conn,
pixmap,
chain->window,
chain->gc,
0, 0,
0, 0,
chain->extent.width,
chain->extent.height);
xcb_discard_reply(chain->conn, cookie.sequence);
xcb_flush(chain->conn);
return VK_SUCCESS;
}