aboutsummaryrefslogtreecommitdiff
path: root/loader/wsi.c
diff options
context:
space:
mode:
authorMark Young <marky@lunarg.com>2016-06-28 10:52:43 -0600
committerMark Young <marky@lunarg.com>2016-09-19 14:52:50 -0600
commitddca7b207067f44df0990a697b9471efdef8b066 (patch)
treeed9a206caedb824d2ae585cf058a5e49e0a17143 /loader/wsi.c
parent93340a0ede3a328b990653cbd332c9cb2632340a (diff)
downloadusermoji-ddca7b207067f44df0990a697b9471efdef8b066.tar.xz
loader: gh181 use ICD for SurfaceKHR
Use the ICD to create and destroy VkSurfaceKHR objects instead of just performing the work in the ICD. This only occurs if the ICD exports the appropriate entry-points, and exposes version 3 of the loader/icd interface. Change-Id: I5e7bf9506318823c57ad75cf19d3f53fdfa6451e
Diffstat (limited to 'loader/wsi.c')
-rw-r--r--loader/wsi.c577
1 files changed, 474 insertions, 103 deletions
diff --git a/loader/wsi.c b/loader/wsi.c
index a74cdb4b..d38085d5 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -30,6 +30,10 @@
#include "wsi.h"
#include <vulkan/vk_icd.h>
+// The first ICD/Loader interface that support querying the SurfaceKHR from
+// the ICDs.
+#define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3
+
static const VkExtensionProperties wsi_surface_extension_info = {
.extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
.specVersion = VK_KHR_SURFACE_SPEC_VERSION,
@@ -207,6 +211,32 @@ terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
const VkAllocationCallbacks *pAllocator) {
struct loader_instance *ptr_instance = loader_get_instance(instance);
+// Android doesn't have to worry about multiple ICD scenario, but the rest do.
+#ifndef VK_USE_PLATFORM_ANDROID_KHR
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+ if (NULL != icd_surface->real_icd_surfaces) {
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ if (ptr_instance->icd_libs.list[i].interface_version >=
+ ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != icd->DestroySurfaceKHR &&
+ NULL != (void *)icd_surface->real_icd_surfaces[i]) {
+ icd->DestroySurfaceKHR(instance,
+ icd_surface->real_icd_surfaces[i],
+ pAllocator);
+ icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)NULL;
+ }
+ } else {
+ // The real_icd_surface for any ICD not supporting the proper
+ // interface version should be NULL. If not, then we have a
+ // problem.
+ assert(NULL == icd_surface->real_icd_surfaces[i]);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
+ }
+#endif // !VK_USE_PLATFORM_XLIB_KHR
+
loader_instance_heap_free(ptr_instance, (void *)surface);
}
@@ -252,6 +282,17 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(
assert(icd->GetPhysicalDeviceSurfaceSupportKHR &&
"loader: null GetPhysicalDeviceSurfaceSupportKHR ICD pointer");
+// Android doesn't have to worry about multiple ICD scenario, but the rest do.
+#ifndef VK_USE_PLATFORM_ANDROID_KHR
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+ if (NULL != icd_surface->real_icd_surfaces &&
+ NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+ return icd->GetPhysicalDeviceSurfaceSupportKHR(
+ phys_dev->phys_dev, queueFamilyIndex,
+ icd_surface->real_icd_surfaces[phys_dev->icd_index], pSupported);
+ }
+#endif
+
return icd->GetPhysicalDeviceSurfaceSupportKHR(
phys_dev->phys_dev, queueFamilyIndex, surface, pSupported);
}
@@ -298,6 +339,18 @@ terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(
assert(icd->GetPhysicalDeviceSurfaceCapabilitiesKHR &&
"loader: null GetPhysicalDeviceSurfaceCapabilitiesKHR ICD pointer");
+// Android doesn't have to worry about multiple ICD scenario, but the rest do.
+#ifndef VK_USE_PLATFORM_ANDROID_KHR
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+ if (NULL != icd_surface->real_icd_surfaces &&
+ NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+ return icd->GetPhysicalDeviceSurfaceCapabilitiesKHR(
+ phys_dev->phys_dev,
+ icd_surface->real_icd_surfaces[phys_dev->icd_index],
+ pSurfaceCapabilities);
+ }
+#endif
+
return icd->GetPhysicalDeviceSurfaceCapabilitiesKHR(
phys_dev->phys_dev, surface, pSurfaceCapabilities);
}
@@ -345,6 +398,18 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(
assert(icd->GetPhysicalDeviceSurfaceFormatsKHR &&
"loader: null GetPhysicalDeviceSurfaceFormatsKHR ICD pointer");
+// Android doesn't have to worry about multiple ICD scenario, but the rest do.
+#ifndef VK_USE_PLATFORM_ANDROID_KHR
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+ if (NULL != icd_surface->real_icd_surfaces &&
+ NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+ return icd->GetPhysicalDeviceSurfaceFormatsKHR(
+ phys_dev->phys_dev,
+ icd_surface->real_icd_surfaces[phys_dev->icd_index],
+ pSurfaceFormatCount, pSurfaceFormats);
+ }
+#endif
+
return icd->GetPhysicalDeviceSurfaceFormatsKHR(
phys_dev->phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
}
@@ -391,6 +456,18 @@ terminator_GetPhysicalDeviceSurfacePresentModesKHR(
assert(icd->GetPhysicalDeviceSurfacePresentModesKHR &&
"loader: null GetPhysicalDeviceSurfacePresentModesKHR ICD pointer");
+// Android doesn't have to worry about multiple ICD scenario, but the rest do.
+#ifndef VK_USE_PLATFORM_ANDROID_KHR
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+ if (NULL != icd_surface->real_icd_surfaces &&
+ NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+ return icd->GetPhysicalDeviceSurfacePresentModesKHR(
+ phys_dev->phys_dev,
+ icd_surface->real_icd_surfaces[phys_dev->icd_index],
+ pPresentModeCount, pPresentModes);
+ }
+#endif
+
return icd->GetPhysicalDeviceSurfacePresentModesKHR(
phys_dev->phys_dev, surface, pPresentModeCount, pPresentModes);
}
@@ -407,6 +484,40 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
pSwapchain);
}
+VKAPI_ATTR VkResult VKAPI_CALL terminator_vkCreateSwapchainKHR(
+ VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd *icd = loader_get_icd_and_device(device, &dev, &icd_index);
+ PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
+ if (NULL != icd &&
+ NULL != icd->CreateSwapchainKHR) {
+ // Android doesn't have to worry about multiple ICD scenario, but the rest do.
+#ifndef VK_USE_PLATFORM_ANDROID_KHR
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(pCreateInfo->surface);
+ if (NULL != icd_surface->real_icd_surfaces) {
+ if (NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {
+ // We found the ICD, and there is an ICD KHR surface
+ // associated with it, so copy the CreateInfo struct
+ // and point it at the ICD's surface.
+ VkSwapchainCreateInfoKHR *pCreateCopy =
+ loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR));
+ if (NULL == pCreateCopy) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memcpy(pCreateCopy, pCreateInfo, sizeof(VkIcdSurface));
+ pCreateCopy->surface =
+ icd_surface->real_icd_surfaces[icd_index];
+ return icd->CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain);
+ }
+ }
+#endif
+ return icd->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+ }
+ return VK_SUCCESS;
+}
+
// This is the trampoline entrypoint for DestroySwapchainKHR
LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
@@ -416,22 +527,26 @@ vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
disp->DestroySwapchainKHR(device, swapchain, pAllocator);
}
-// This is the trampoline entrypoint for GetSwapchainImagesKHR
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
- uint32_t *pSwapchainImageCount,
- VkImage *pSwapchainImages) {
+/*
+ * This is the trampoline entrypoint
+ * for GetSwapchainImagesKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
+ VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
+ VkImage *pSwapchainImages) {
const VkLayerDispatchTable *disp;
disp = loader_get_dispatch(device);
return disp->GetSwapchainImagesKHR(
device, swapchain, pSwapchainImageCount, pSwapchainImages);
}
-// This is the trampoline entrypoint for AcquireNextImageKHR
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain,
- uint64_t timeout, VkSemaphore semaphore, VkFence fence,
- uint32_t *pImageIndex) {
+/*
+ * This is the trampoline entrypoint
+ * for AcquireNextImageKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
+ VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
+ VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
const VkLayerDispatchTable *disp;
disp = loader_get_dispatch(device);
return disp->AcquireNextImageKHR(device, swapchain, timeout,
@@ -468,32 +583,83 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(
VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
// First, check to ensure the appropriate extension was enabled:
struct loader_instance *ptr_instance = loader_get_instance(instance);
if (!ptr_instance->wsi_win32_surface_enabled) {
loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"VK_KHR_win32_surface extension not enabled. "
"vkCreateWin32SurfaceKHR not executed!\n");
- return VK_ERROR_EXTENSION_NOT_PRESENT;
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
}
// Next, if so, proceed with the implementation of this function:
- VkIcdSurfaceWin32 *pIcdSurface = NULL;
-
- pIcdSurface =
- loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWin32),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pIcdSurface == NULL) {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
}
- pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_WIN32;
- pIcdSurface->hinstance = pCreateInfo->hinstance;
- pIcdSurface->hwnd = pCreateInfo->hwnd;
+ pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
+ pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance;
+ pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd;
+
+ // Setup the new sizes and offsets so we can grow the structures in the
+ // future withouth having problems
+ pIcdSurface->base_size = sizeof(pIcdSurface->win_surf.base);
+ pIcdSurface->platform_size = sizeof(pIcdSurface->win_surf);
+ pIcdSurface->non_platform_offset = (uint32_t)(
+ (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+ pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+ pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(pIcdSurface->real_icd_surfaces, 0,
+ sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ if (ptr_instance->icd_libs.list[i].interface_version >=
+ ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != icd->CreateWin32SurfaceKHR) {
+ vkRes = icd->CreateWin32SurfaceKHR(
+ instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
- *pSurface = (VkSurfaceKHR)pIcdSurface;
+ *pSurface = (VkSurfaceKHR)(pIcdSurface);
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+ NULL != icd->DestroySurfaceKHR) {
+ icd->DestroySurfaceKHR(
+ instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
- return VK_SUCCESS;
+ return vkRes;
}
// This is the trampoline entrypoint for
@@ -561,32 +727,83 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(
VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
// First, check to ensure the appropriate extension was enabled:
struct loader_instance *ptr_instance = loader_get_instance(instance);
if (!ptr_instance->wsi_mir_surface_enabled) {
loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"VK_KHR_mir_surface extension not enabled. "
"vkCreateMirSurfaceKHR not executed!\n");
- return VK_ERROR_EXTENSION_NOT_PRESENT;
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
}
// Next, if so, proceed with the implementation of this function:
- VkIcdSurfaceMir *pIcdSurface = NULL;
-
- pIcdSurface =
- loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceMir),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pIcdSurface == NULL) {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
}
- pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_MIR;
- pIcdSurface->connection = pCreateInfo->connection;
- pIcdSurface->mirSurface = pCreateInfo->mirSurface;
+ pIcdSurface->mir_surf.base.platform = VK_ICD_WSI_PLATFORM_MIR;
+ pIcdSurface->mir_surf.connection = pCreateInfo->connection;
+ pIcdSurface->mir_surf.mirSurface = pCreateInfo->mirSurface;
+
+ // Setup the new sizes and offsets so we can grow the structures in the
+ // future withouth having problems
+ pIcdSurface->base_size = sizeof(pIcdSurface->mir_surf.base);
+ pIcdSurface->platform_size = sizeof(pIcdSurface->mir_surf);
+ pIcdSurface->non_platform_offset = (uint32_t)(
+ (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+ pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+ pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(pIcdSurface->real_icd_surfaces, 0,
+ sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ if (ptr_instance->icd_libs.list[i].interface_version >=
+ ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != icd->CreateMirSurfaceKHR) {
+ vkRes = icd->CreateMirSurfaceKHR(
+ instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
*pSurface = (VkSurfaceKHR)pIcdSurface;
- return VK_SUCCESS;
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+ NULL != icd->DestroySurfaceKHR) {
+ icd->DestroySurfaceKHR(
+ instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
}
// This is the trampoline entrypoint for
@@ -637,15 +854,13 @@ terminator_GetPhysicalDeviceMirPresentationSupportKHR(
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-
-// Functions for the VK_KHR_wayland_surface extension:
-
-// This is the trampoline entrypoint for CreateWaylandSurfaceKHR
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateWaylandSurfaceKHR(VkInstance instance,
- const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkSurfaceKHR *pSurface) {
+/*
+ * This is the trampoline entrypoint
+ * for CreateWaylandSurfaceKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
+ VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
const VkLayerInstanceDispatchTable *disp;
disp = loader_get_instance_dispatch(instance);
VkResult res;
@@ -659,32 +874,83 @@ vkCreateWaylandSurfaceKHR(VkInstance instance,
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(
VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
// First, check to ensure the appropriate extension was enabled:
struct loader_instance *ptr_instance = loader_get_instance(instance);
if (!ptr_instance->wsi_wayland_surface_enabled) {
loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"VK_KHR_wayland_surface extension not enabled. "
"vkCreateWaylandSurfaceKHR not executed!\n");
- return VK_ERROR_EXTENSION_NOT_PRESENT;
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
}
// Next, if so, proceed with the implementation of this function:
- VkIcdSurfaceWayland *pIcdSurface = NULL;
-
- pIcdSurface =
- loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWayland),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pIcdSurface == NULL) {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
}
- pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
- pIcdSurface->display = pCreateInfo->display;
- pIcdSurface->surface = pCreateInfo->surface;
+ pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
+ pIcdSurface->wayland_surf.display = pCreateInfo->display;
+ pIcdSurface->wayland_surf.surface = pCreateInfo->surface;
+
+ // Setup the new sizes and offsets so we can grow the structures in the
+ // future withouth having problems
+ pIcdSurface->base_size = sizeof(pIcdSurface->wayland_surf.base);
+ pIcdSurface->platform_size = sizeof(pIcdSurface->wayland_surf);
+ pIcdSurface->non_platform_offset = (uint32_t)(
+ (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+ pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+ pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(pIcdSurface->real_icd_surfaces, 0,
+ sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ if (ptr_instance->icd_libs.list[i].interface_version >=
+ ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != icd->CreateWaylandSurfaceKHR) {
+ vkRes = icd->CreateWaylandSurfaceKHR(
+ instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
*pSurface = (VkSurfaceKHR)pIcdSurface;
- return VK_SUCCESS;
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+ NULL != icd->DestroySurfaceKHR) {
+ icd->DestroySurfaceKHR(
+ instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
}
@@ -756,32 +1022,83 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(
VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
// First, check to ensure the appropriate extension was enabled:
struct loader_instance *ptr_instance = loader_get_instance(instance);
if (!ptr_instance->wsi_xcb_surface_enabled) {
loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"VK_KHR_xcb_surface extension not enabled. "
"vkCreateXcbSurfaceKHR not executed!\n");
- return VK_ERROR_EXTENSION_NOT_PRESENT;
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
}
// Next, if so, proceed with the implementation of this function:
- VkIcdSurfaceXcb *pIcdSurface = NULL;
-
- pIcdSurface =
- loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXcb),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pIcdSurface == NULL) {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
}
- pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_XCB;
- pIcdSurface->connection = pCreateInfo->connection;
- pIcdSurface->window = pCreateInfo->window;
+ pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB;
+ pIcdSurface->xcb_surf.connection = pCreateInfo->connection;
+ pIcdSurface->xcb_surf.window = pCreateInfo->window;
+
+ // Setup the new sizes and offsets so we can grow the structures in the
+ // future withouth having problems
+ pIcdSurface->base_size = sizeof(pIcdSurface->xcb_surf.base);
+ pIcdSurface->platform_size = sizeof(pIcdSurface->xcb_surf);
+ pIcdSurface->non_platform_offset = (uint32_t)(
+ (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+ pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+ pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(pIcdSurface->real_icd_surfaces, 0,
+ sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ if (ptr_instance->icd_libs.list[i].interface_version >=
+ ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != icd->CreateXcbSurfaceKHR) {
+ vkRes = icd->CreateXcbSurfaceKHR(
+ instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
*pSurface = (VkSurfaceKHR)pIcdSurface;
- return VK_SUCCESS;
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+ NULL != icd->DestroySurfaceKHR) {
+ icd->DestroySurfaceKHR(
+ instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
}
// This is the trampoline entrypoint for
@@ -852,32 +1169,83 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(
VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
// First, check to ensure the appropriate extension was enabled:
struct loader_instance *ptr_instance = loader_get_instance(instance);
if (!ptr_instance->wsi_xlib_surface_enabled) {
loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"VK_KHR_xlib_surface extension not enabled. "
"vkCreateXlibSurfaceKHR not executed!\n");
- return VK_ERROR_EXTENSION_NOT_PRESENT;
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
}
// Next, if so, proceed with the implementation of this function:
- VkIcdSurfaceXlib *pIcdSurface = NULL;
-
- pIcdSurface =
- loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXlib),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pIcdSurface == NULL) {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
}
- pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_XLIB;
- pIcdSurface->dpy = pCreateInfo->dpy;
- pIcdSurface->window = pCreateInfo->window;
+ pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB;
+ pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy;
+ pIcdSurface->xlib_surf.window = pCreateInfo->window;
+
+ // Setup the new sizes and offsets so we can grow the structures in the
+ // future withouth having problems
+ pIcdSurface->base_size = sizeof(pIcdSurface->xlib_surf.base);
+ pIcdSurface->platform_size = sizeof(pIcdSurface->xlib_surf);
+ pIcdSurface->non_platform_offset = (uint32_t)(
+ (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+ pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+ pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+ ptr_instance, sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(pIcdSurface->real_icd_surfaces, 0,
+ sizeof(VkSurfaceKHR) * ptr_instance->total_icd_count);
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ if (ptr_instance->icd_libs.list[i].interface_version >=
+ ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != icd->CreateXlibSurfaceKHR) {
+ vkRes = icd->CreateXlibSurfaceKHR(
+ instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
*pSurface = (VkSurfaceKHR)pIcdSurface;
- return VK_SUCCESS;
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+ struct loader_icd *icd = &ptr_instance->icds[i];
+ if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+ NULL != icd->DestroySurfaceKHR) {
+ icd->DestroySurfaceKHR(
+ instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
}
// This is the trampoline entrypoint for GetPhysicalDeviceXlibPresentationSupportKHR
@@ -956,11 +1324,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(
}
// Next, if so, proceed with the implementation of this function:
- VkIcdSurfaceAndroid *pIcdSurface = NULL;
-
- pIcdSurface =
+ VkIcdSurfaceAndroid *pIcdSurface =
loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceAndroid),
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pIcdSurface == NULL) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
@@ -1071,11 +1437,9 @@ vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
return res;
}
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
- uint32_t planeIndex,
- uint32_t *pDisplayCount,
- VkDisplayKHR *pDisplays) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(
+ VkPhysicalDevice physicalDevice, uint32_t planeIndex,
+ uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
// First, check to ensure the appropriate extension was enabled:
struct loader_physical_device *phys_dev =
(struct loader_physical_device *)physicalDevice;
@@ -1098,10 +1462,9 @@ terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
phys_dev->phys_dev, planeIndex, pDisplayCount, pDisplays);
}
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,
- VkDisplayKHR display, uint32_t *pPropertyCount,
- VkDisplayModePropertiesKHR *pProperties) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(
+ VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
VkPhysicalDevice unwrapped_phys_dev =
loader_unwrap_physical_device(physicalDevice);
const VkLayerInstanceDispatchTable *disp;
@@ -1175,10 +1538,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(
pAllocator, pMode);
}
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
- VkDisplayModeKHR mode, uint32_t planeIndex,
- VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(
+ VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex,
+ VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
VkPhysicalDevice unwrapped_phys_dev =
loader_unwrap_physical_device(physicalDevice);
const VkLayerInstanceDispatchTable *disp;
@@ -1229,7 +1591,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(
VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
struct loader_instance *inst = loader_get_instance(instance);
- VkIcdSurfaceDisplay *pIcdSurface = NULL;
+ VkIcdSurface *pIcdSurface = NULL;
if (!inst->wsi_surface_enabled) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -1238,20 +1600,29 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
- pIcdSurface = loader_instance_heap_alloc(
- inst, sizeof(VkIcdSurfaceDisplay), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ pIcdSurface = loader_instance_heap_alloc(inst, sizeof(VkIcdSurface),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pIcdSurface == NULL) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
- pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
- pIcdSurface->displayMode = pCreateInfo->displayMode;
- pIcdSurface->planeIndex = pCreateInfo->planeIndex;
- pIcdSurface->planeStackIndex = pCreateInfo->planeStackIndex;
- pIcdSurface->transform = pCreateInfo->transform;
- pIcdSurface->globalAlpha = pCreateInfo->globalAlpha;
- pIcdSurface->alphaMode = pCreateInfo->alphaMode;
- pIcdSurface->imageExtent = pCreateInfo->imageExtent;
+ pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
+ pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
+ pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
+ pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
+ pIcdSurface->display_surf.transform = pCreateInfo->transform;
+ pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
+ pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
+ pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
+
+ // Setup the new sizes and offsets so we can grow the structures in the
+ // future withouth having problems
+ pIcdSurface->real_icd_surfaces = NULL;
+ pIcdSurface->base_size = sizeof(pIcdSurface->display_surf.base);
+ pIcdSurface->platform_size = sizeof(pIcdSurface->display_surf);
+ pIcdSurface->non_platform_offset = (uint32_t)(
+ (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+ pIcdSurface->entire_size = sizeof(VkIcdSurface);
*pSurface = (VkSurfaceKHR)pIcdSurface;