diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c
index fe9a91a0a8..b90badcf7f 100644
--- a/gfx/common/vulkan_common.c
+++ b/gfx/common/vulkan_common.c
@@ -13,9 +13,31 @@
* If not, see .
*/
-#include "vulkan_common.h"
#include
+#include "vulkan_common.h"
+
+#ifdef HAVE_VULKAN
+static VkInstance cached_instance;
+static VkDevice cached_device;
+#endif
+
+#define VK_GET_INSTANCE_PROC_ADDR(vk, inst, entrypoint) do { \
+ vk->fp##entrypoint = (PFN_vk##entrypoint) vkGetInstanceProcAddr(inst, "vk"#entrypoint); \
+ if (vk->fp##entrypoint == NULL) { \
+ RARCH_ERR("vkGetInstanceProcAddr failed to find vk%s\n", #entrypoint); \
+ return false; \
+ } \
+} while(0)
+
+#define VK_GET_DEVICE_PROC_ADDR(vk, dev, entrypoint) do { \
+ vk->fp##entrypoint = (PFN_vk##entrypoint) vkGetDeviceProcAddr(dev, "vk" #entrypoint); \
+ if (vk->fp##entrypoint == NULL) { \
+ RARCH_ERR("vkGetDeviceProcAddr failed to find vk%s\n", #entrypoint); \
+ return false; \
+ } \
+} while(0)
+
uint32_t vulkan_find_memory_type(const VkPhysicalDeviceMemoryProperties *mem_props,
uint32_t device_reqs, uint32_t host_reqs)
{
@@ -774,3 +796,569 @@ void vulkan_buffer_chain_free(VkDevice device, struct vk_buffer_chain *chain)
memset(chain, 0, sizeof(*chain));
}
+bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
+ enum vulkan_wsi_type type)
+{
+ unsigned i;
+ uint32_t queue_count;
+ VkQueueFamilyProperties queue_properties[32];
+ VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
+ VkApplicationInfo app = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
+ VkPhysicalDeviceFeatures features = { false };
+ VkDeviceQueueCreateInfo queue_info = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };
+ VkDeviceCreateInfo device_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
+ uint32_t gpu_count = 1;
+ bool found_queue = false;
+ static const float one = 1.0f;
+ static const char *device_extensions[] = {
+ "VK_KHR_swapchain",
+ };
+ static const char *instance_extensions[2];
+
+ instance_extensions[0] = "VK_KHR_surface";
+
+ switch (type)
+ {
+ case VULKAN_WSI_WAYLAND:
+ instance_extensions[1] = "VK_KHR_wayland_surface";
+ break;
+ case VULKAN_WSI_ANDROID:
+ instance_extensions[1] = "VK_KHR_android_surface";
+ break;
+ case VULKAN_WSI_WIN32:
+ instance_extensions[1] = "VK_KHR_win32_surface";
+ break;
+ case VULKAN_WSI_XLIB:
+ instance_extensions[1] = "VK_KHR_xlib_surface";
+ break;
+ case VULKAN_WSI_XCB:
+ instance_extensions[1] = "VK_KHR_xcb_surface";
+ break;
+ case VULKAN_WSI_MIR:
+ instance_extensions[1] = "VK_KHR_mir_surface";
+ break;
+ case VULKAN_WSI_NONE:
+ default:
+ break;
+ }
+
+ app.pApplicationName = "RetroArch";
+ app.applicationVersion = 0;
+ app.pEngineName = "RetroArch";
+ app.engineVersion = 0;
+ app.apiVersion = VK_API_VERSION;
+
+ info.pApplicationInfo = &app;
+ info.enabledExtensionCount = ARRAY_SIZE(instance_extensions);
+ info.ppEnabledExtensionNames = instance_extensions;
+
+ if (cached_instance)
+ {
+ vk->context.instance = cached_instance;
+ cached_instance = NULL;
+ }
+ else if (vkCreateInstance(&info, NULL, &vk->context.instance) != VK_SUCCESS)
+ return false;
+
+ if (vkEnumeratePhysicalDevices(vk->context.instance,
+ &gpu_count, &vk->context.gpu) != VK_SUCCESS)
+ return false;
+
+ if (gpu_count != 1)
+ {
+ RARCH_ERR("[Vulkan]: Failed to enumerate Vulkan physical device.\n");
+ return false;
+ }
+
+ vkGetPhysicalDeviceProperties(vk->context.gpu,
+ &vk->context.gpu_properties);
+ vkGetPhysicalDeviceMemoryProperties(vk->context.gpu,
+ &vk->context.memory_properties);
+ vkGetPhysicalDeviceQueueFamilyProperties(vk->context.gpu,
+ &queue_count, NULL);
+
+ if (queue_count < 1 || queue_count > 32)
+ return false;
+
+ vkGetPhysicalDeviceQueueFamilyProperties(vk->context.gpu,
+ &queue_count, queue_properties);
+
+ for (i = 0; i < queue_count; i++)
+ {
+ if (queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
+ {
+ vk->context.graphics_queue_index = i;
+ RARCH_LOG("[Vulkan]: Device supports %u sub-queues.\n",
+ queue_properties[i].queueCount);
+ found_queue = true;
+ break;
+ }
+ }
+
+ if (!found_queue)
+ {
+ RARCH_ERR("[Vulkan]: Did not find suitable graphics queue.\n");
+ return false;
+ }
+
+ queue_info.queueFamilyIndex = vk->context.graphics_queue_index;
+ queue_info.queueCount = 1;
+ queue_info.pQueuePriorities = &one;
+
+ device_info.queueCreateInfoCount = 1;
+ device_info.pQueueCreateInfos = &queue_info;
+ device_info.enabledExtensionCount = ARRAY_SIZE(device_extensions);
+ device_info.ppEnabledExtensionNames = device_extensions;
+ device_info.pEnabledFeatures = &features;
+
+ if (cached_device)
+ {
+ vk->context.device = cached_device;
+ cached_device = NULL;
+ video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL);
+ RARCH_LOG("[Vulkan]: Using cached Vulkan context.\n");
+ }
+ else if (vkCreateDevice(vk->context.gpu, &device_info,
+ NULL, &vk->context.device) != VK_SUCCESS)
+ return false;
+
+ vkGetDeviceQueue(vk->context.device,
+ vk->context.graphics_queue_index, 0, &vk->context.queue);
+
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, GetPhysicalDeviceSurfaceSupportKHR);
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, GetPhysicalDeviceSurfaceCapabilitiesKHR);
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, GetPhysicalDeviceSurfaceFormatsKHR);
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, GetPhysicalDeviceSurfacePresentModesKHR);
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, DestroySurfaceKHR);
+ VK_GET_DEVICE_PROC_ADDR(vk,
+ vk->context.device, CreateSwapchainKHR);
+ VK_GET_DEVICE_PROC_ADDR(vk,
+ vk->context.device, DestroySwapchainKHR);
+ VK_GET_DEVICE_PROC_ADDR(vk,
+ vk->context.device, GetSwapchainImagesKHR);
+ VK_GET_DEVICE_PROC_ADDR(vk,
+ vk->context.device, AcquireNextImageKHR);
+ VK_GET_DEVICE_PROC_ADDR(vk,
+ vk->context.device, QueuePresentKHR);
+
+ switch (type)
+ {
+ case VULKAN_WSI_WAYLAND:
+#ifdef HAVE_WAYLAND
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, CreateWaylandSurfaceKHR);
+#endif
+ break;
+ case VULKAN_WSI_ANDROID:
+#ifdef ANDROID
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, CreateAndroidSurfaceKHR);
+#endif
+ break;
+ case VULKAN_WSI_WIN32:
+#ifdef _WIN32
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, CreateWin32SurfaceKHR);
+#endif
+ break;
+ case VULKAN_WSI_XLIB:
+#ifdef HAVE_XLIB
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, CreateXlibSurfaceKHR);
+#endif
+ break;
+ case VULKAN_WSI_XCB:
+#ifdef HAVE_XCB
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, CreateXcbSurfaceKHR);
+#endif
+ break;
+ case VULKAN_WSI_MIR:
+#ifdef HAVE_MIR
+ VK_GET_INSTANCE_PROC_ADDR(vk,
+ vk->context.instance, CreateMirSurfaceKHR);
+#endif
+ break;
+ case VULKAN_WSI_NONE:
+ default:
+ break;
+ }
+
+ vk->context.queue_lock = slock_new();
+ if (!vk->context.queue_lock)
+ return false;
+
+ return true;
+}
+
+bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
+ enum vulkan_wsi_type type,
+ void *display, void *surface,
+ unsigned width, unsigned height,
+ unsigned swap_interval)
+{
+ switch (type)
+ {
+ case VULKAN_WSI_WAYLAND:
+#ifdef HAVE_WAYLAND
+ {
+ VkWaylandSurfaceCreateInfoKHR surf_info;
+
+ memset(&surf_info, 0, sizeof(VkWaylandSurfaceCreateInfoKHR));
+
+ surf_info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
+ surf_info.pNext = NULL;
+ surf_info.flags = 0;
+ surf_info.display = (struct wl_display*)display;
+ surf_info.surface = (struct wl_surface*)surface;
+
+ if (vk->fpCreateWaylandSurfaceKHR(vk->context.instance,
+ &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS)
+ return false;
+ }
+#endif
+ break;
+ case VULKAN_WSI_ANDROID:
+#ifdef ANDROID
+ {
+ VkAndroidSurfaceCreateInfoKHR surf_info;
+
+ memset(&surf_info, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
+
+ surf_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+ surf_info.flags = 0;
+ surf_info.window = (ANativeWindow*)surface;
+
+ if (vk->fpCreateAndroidSurfaceKHR(vk->context.instance,
+ &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS)
+ return false;
+ }
+#endif
+ break;
+ case VULKAN_WSI_WIN32:
+#ifdef _WIN32
+ {
+ VkWin32SurfaceCreateInfoKHR surf_info;
+
+ memset(&surf_info, 0, sizeof(VkWin32SurfaceCreateInfoKHR));
+
+ surf_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ surf_info.flags = 0;
+ surf_info.hinstance = display;
+ surf_info.hwnd = surface;
+
+ if (vk->fpCreateWin32SurfaceKHR(vk->context.instance,
+ &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS)
+ return false;
+ }
+#endif
+ break;
+ case VULKAN_WSI_XLIB:
+#ifdef HAVE_XLIB
+ {
+ VkXlibSurfaceCreateInfoKHR surf_info;
+
+ memset(&surf_info, 0, sizeof(VkXlibSurfaceCreateInfoKHR));
+
+ surf_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
+ surf_info.flags = 0;
+ surf_info.dpy = display;
+ surf_info.window = surface;
+
+ if (vk->fpCreateXlibSurfaceKHR(vk->context.instance,
+ &surf_info, NULL, &vk->vk_surface)
+ != VK_SUCCESS)
+ return false;
+ }
+#endif
+ break;
+ case VULKAN_WSI_XCB:
+#ifdef HAVE_XCB
+ {
+ VkXcbSurfaceCreateInfoKHR surf_info;
+
+ memset(&surf_info, 0, sizeof(VkXcbSurfaceCreateInfoKHR));
+
+ surf_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+ surf_info.flags = 0;
+ surf_info.connection = XGetXCBConnection(display);
+ surf_info.window = (xcb_window_t)surface;
+
+ if (vk->fpCreateXcbSurfaceKHR(vk->context.instance,
+ &surf_info, NULL, &vk->vk_surface)
+ != VK_SUCCESS)
+ return false;
+ }
+#endif
+ break;
+ case VULKAN_WSI_MIR:
+#ifdef HAVE_MIR
+ {
+ VkMirSurfaceCreateInfoKHR surf_info;
+
+ memset(&surf_info, 0, sizeof(VkMirSurfaceCreateInfoKHR));
+
+ surf_info.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
+ surf_info.connection = display;
+ surf_info.mirSurface = surface;
+
+ if (vk->fpCreateMirSurfaceKHR(vk->context.instance,
+ &surf_info, NULL, &vk->vk_surface)
+ != VK_SUCCESS)
+ return false;
+ }
+#endif
+ break;
+ case VULKAN_WSI_NONE:
+ default:
+ return false;
+ }
+
+ if (!vulkan_create_swapchain(
+ vk, width, height, swap_interval))
+ return false;
+
+ return true;
+}
+
+void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index)
+{
+ VkResult result = VK_SUCCESS;
+ VkResult err = VK_SUCCESS;
+ VkPresentInfoKHR present = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
+ present.swapchainCount = 1;
+ present.pSwapchains = &vk->swapchain;
+ present.pImageIndices = &index;
+ present.pResults = &result;
+ present.waitSemaphoreCount = 1;
+ present.pWaitSemaphores = &vk->context.swapchain_semaphores[index];
+
+ /* Better hope QueuePresent doesn't block D: */
+ slock_lock(vk->context.queue_lock);
+ err = vk->fpQueuePresentKHR(vk->context.queue, &present);
+
+ if (err != VK_SUCCESS || result != VK_SUCCESS)
+ {
+ RARCH_LOG("[Vulkan]: QueuePresent failed, invalidating swapchain.\n");
+ vk->context.invalid_swapchain = true;
+ }
+ slock_unlock(vk->context.queue_lock);
+}
+
+void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk,
+ bool destroy_surface)
+{
+ unsigned i;
+ if (vk->context.queue)
+ vkQueueWaitIdle(vk->context.queue);
+ if (vk->swapchain)
+ vk->fpDestroySwapchainKHR(vk->context.device,
+ vk->swapchain, NULL);
+
+ if (destroy_surface)
+ vk->fpDestroySurfaceKHR(vk->context.instance,
+ vk->vk_surface, NULL);
+
+ for (i = 0; i < VULKAN_MAX_SWAPCHAIN_IMAGES; i++)
+ {
+ if (vk->context.swapchain_semaphores[i] != VK_NULL_HANDLE)
+ vkDestroySemaphore(vk->context.device,
+ vk->context.swapchain_semaphores[i], NULL);
+ if (vk->context.swapchain_fences[i] != VK_NULL_HANDLE)
+ vkDestroyFence(vk->context.device,
+ vk->context.swapchain_fences[i], NULL);
+ }
+
+ if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL))
+ {
+ cached_device = vk->context.device;
+ cached_instance = vk->context.instance;
+ }
+ else
+ {
+ if (vk->context.device)
+ vkDestroyDevice(vk->context.device, NULL);
+ if (vk->context.instance)
+ vkDestroyInstance(vk->context.instance, NULL);
+ }
+}
+
+void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk)
+{
+ unsigned index;
+ VkResult err;
+ VkFence fence;
+ VkFence *next_fence;
+ VkSemaphoreCreateInfo sem_info =
+ { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
+ VkFenceCreateInfo info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
+
+ vkCreateFence(vk->context.device, &info, NULL, &fence);
+
+ err = vk->fpAcquireNextImageKHR(vk->context.device,
+ vk->swapchain, UINT64_MAX,
+ VK_NULL_HANDLE, fence, &vk->context.current_swapchain_index);
+
+ index = vk->context.current_swapchain_index;
+ if (vk->context.swapchain_semaphores[index] == VK_NULL_HANDLE)
+ vkCreateSemaphore(vk->context.device, &sem_info,
+ NULL, &vk->context.swapchain_semaphores[index]);
+
+ vkWaitForFences(vk->context.device, 1, &fence, true, UINT64_MAX);
+ vkDestroyFence(vk->context.device, fence, NULL);
+
+ next_fence = &vk->context.swapchain_fences[index];
+ if (*next_fence != VK_NULL_HANDLE)
+ {
+ vkWaitForFences(vk->context.device, 1, next_fence, true, UINT64_MAX);
+ vkResetFences(vk->context.device, 1, next_fence);
+ }
+ else
+ vkCreateFence(vk->context.device, &info, NULL, next_fence);
+
+ if (err != VK_SUCCESS)
+ {
+ RARCH_LOG("[Vulkan]: AcquireNextImage failed, invalidating swapchain.\n");
+ vk->context.invalid_swapchain = true;
+ }
+}
+
+bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
+ unsigned width, unsigned height,
+ unsigned swap_interval)
+{
+ unsigned i;
+ uint32_t format_count;
+ uint32_t desired_swapchain_images;
+ VkSurfaceCapabilitiesKHR surface_properties;
+ VkSurfaceFormatKHR formats[256];
+ VkSurfaceFormatKHR format;
+ VkExtent2D swapchain_size;
+ VkSwapchainKHR old_swapchain;
+ VkSurfaceTransformFlagBitsKHR pre_transform;
+ VkPresentModeKHR swapchain_present_mode = swap_interval
+ ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_MAILBOX_KHR;
+ VkSwapchainCreateInfoKHR info = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
+
+ RARCH_LOG("[Vulkan]: Creating swapchain with present mode: %u\n",
+ (unsigned)swapchain_present_mode);
+
+ vk->fpGetPhysicalDeviceSurfaceCapabilitiesKHR(vk->context.gpu,
+ vk->vk_surface, &surface_properties);
+ vk->fpGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
+ vk->vk_surface, &format_count, NULL);
+ vk->fpGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
+ vk->vk_surface, &format_count, formats);
+
+ if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED)
+ {
+ format = formats[0];
+ format.format = VK_FORMAT_B8G8R8A8_UNORM;
+ }
+ else
+ {
+ if (format_count == 0)
+ {
+ RARCH_ERR("[Vulkan]: Surface has no formats.\n");
+ return false;
+ }
+
+ format = formats[0];
+ }
+
+ if (surface_properties.currentExtent.width == -1)
+ {
+ swapchain_size.width = width;
+ swapchain_size.height = height;
+ }
+ else
+ swapchain_size = surface_properties.currentExtent;
+
+ desired_swapchain_images = surface_properties.minImageCount + 1;
+ if ((surface_properties.maxImageCount > 0)
+ && (desired_swapchain_images > surface_properties.maxImageCount))
+ desired_swapchain_images = surface_properties.maxImageCount;
+
+ if (surface_properties.supportedTransforms
+ & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
+ pre_transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+ else
+ pre_transform = surface_properties.currentTransform;
+
+ old_swapchain = vk->swapchain;
+
+ info.surface = vk->vk_surface;
+ info.minImageCount = desired_swapchain_images;
+ info.imageFormat = format.format;
+ info.imageColorSpace = format.colorSpace;
+ info.imageExtent.width = swapchain_size.width;
+ info.imageExtent.height = swapchain_size.height;
+ info.imageArrayLayers = 1;
+ info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
+ | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ info.preTransform = pre_transform;
+ info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+ info.presentMode = swapchain_present_mode;
+ info.clipped = true;
+ info.oldSwapchain = old_swapchain;
+
+ vk->fpCreateSwapchainKHR(vk->context.device, &info, NULL, &vk->swapchain);
+ if (old_swapchain != VK_NULL_HANDLE)
+ vk->fpDestroySwapchainKHR(vk->context.device, old_swapchain, NULL);
+
+ vk->context.swapchain_width = swapchain_size.width;
+ vk->context.swapchain_height = swapchain_size.height;
+
+ /* Make sure we create a backbuffer format that is as we expect. */
+ switch (format.format)
+ {
+ case VK_FORMAT_B8G8R8A8_SRGB:
+ vk->context.swapchain_format = VK_FORMAT_B8G8R8A8_UNORM;
+ vk->context.swapchain_is_srgb = true;
+ break;
+
+ case VK_FORMAT_R8G8B8A8_SRGB:
+ vk->context.swapchain_format = VK_FORMAT_R8G8B8A8_UNORM;
+ vk->context.swapchain_is_srgb = true;
+ break;
+
+ case VK_FORMAT_R8G8B8_SRGB:
+ vk->context.swapchain_format = VK_FORMAT_R8G8B8_UNORM;
+ vk->context.swapchain_is_srgb = true;
+ break;
+
+ case VK_FORMAT_B8G8R8_SRGB:
+ vk->context.swapchain_format = VK_FORMAT_B8G8R8_UNORM;
+ vk->context.swapchain_is_srgb = true;
+ break;
+
+ default:
+ vk->context.swapchain_format = format.format;
+ break;
+ }
+
+ vk->fpGetSwapchainImagesKHR(vk->context.device, vk->swapchain,
+ &vk->context.num_swapchain_images, NULL);
+ vk->fpGetSwapchainImagesKHR(vk->context.device, vk->swapchain,
+ &vk->context.num_swapchain_images, vk->context.swapchain_images);
+
+ for (i = 0; i < vk->context.num_swapchain_images; i++)
+ {
+ if (vk->context.swapchain_fences[i])
+ {
+ vkDestroyFence(vk->context.device,
+ vk->context.swapchain_fences[i], NULL);
+ vk->context.swapchain_fences[i] = VK_NULL_HANDLE;
+ }
+ }
+
+ vulkan_acquire_next_image(vk);
+
+ return true;
+}
diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h
index dc3f87cf6a..ee9ec03acb 100644
--- a/gfx/common/vulkan_common.h
+++ b/gfx/common/vulkan_common.h
@@ -20,6 +20,14 @@
#include "../../config.h"
#endif
+#define VULKAN_DESCRIPTOR_MANAGER_BLOCK_SETS 16
+#define VULKAN_MAX_DESCRIPTOR_POOL_SIZES 16
+#define VULKAN_BUFFER_BLOCK_SIZE (4 * 1024)
+
+#define VULKAN_MAX_SWAPCHAIN_IMAGES 8
+
+#define VULKAN_DIRTY_DYNAMIC_BIT 0x0001
+
#define VK_PROTOTYPES
#ifdef HAVE_WAYLAND
@@ -61,9 +69,12 @@
#include
#include
-#define VULKAN_MAX_SWAPCHAIN_IMAGES 8
-
-#define VULKAN_DIRTY_DYNAMIC_BIT 0x0001
+enum vk_texture_type
+{
+ VULKAN_TEXTURE_STREAMED = 0,
+ VULKAN_TEXTURE_STATIC,
+ VULKAN_TEXTURE_READBACK
+};
enum vulkan_wsi_type
{
@@ -215,14 +226,16 @@ struct vk_buffer_chain vulkan_buffer_chain_init(
VkDeviceSize block_size,
VkDeviceSize alignment,
VkBufferUsageFlags usage);
-void vulkan_buffer_chain_discard(struct vk_buffer_chain *chain);
-bool vulkan_buffer_chain_alloc(const struct vulkan_context *context,
- struct vk_buffer_chain *chain, size_t size, struct vk_buffer_range *range);
-void vulkan_buffer_chain_free(VkDevice device, struct vk_buffer_chain *chain);
-#define VULKAN_DESCRIPTOR_MANAGER_BLOCK_SETS 16
-#define VULKAN_BUFFER_BLOCK_SIZE (4 * 1024)
-#define VULKAN_MAX_DESCRIPTOR_POOL_SIZES 16
+void vulkan_buffer_chain_discard(struct vk_buffer_chain *chain);
+
+bool vulkan_buffer_chain_alloc(const struct vulkan_context *context,
+ struct vk_buffer_chain *chain, size_t size,
+ struct vk_buffer_range *range);
+
+void vulkan_buffer_chain_free(VkDevice device,
+ struct vk_buffer_chain *chain);
+
struct vk_descriptor_pool
{
@@ -298,8 +311,10 @@ typedef struct vk
struct vk_per_frame swapchain[VULKAN_MAX_SWAPCHAIN_IMAGES];
unsigned num_swapchain_images;
- VkCommandBuffer cmd; /* Currently active command buffer. */
- VkCommandPool staging_pool; /* Staging pool for doing buffer transfers on GPU. */
+ /* Currently active command buffer. */
+ VkCommandBuffer cmd;
+ /* Staging pool for doing buffer transfers on GPU. */
+ VkCommandPool staging_pool;
struct
{
@@ -383,18 +398,14 @@ typedef struct vk
vulkan_filter_chain_t *filter_chain;
} vk_t;
-uint32_t vulkan_find_memory_type(const VkPhysicalDeviceMemoryProperties *mem_props,
+uint32_t vulkan_find_memory_type(
+ const VkPhysicalDeviceMemoryProperties *mem_props,
uint32_t device_reqs, uint32_t host_reqs);
-uint32_t vulkan_find_memory_type_fallback(const VkPhysicalDeviceMemoryProperties *mem_props,
+uint32_t vulkan_find_memory_type_fallback(
+ const VkPhysicalDeviceMemoryProperties *mem_props,
uint32_t device_reqs, uint32_t host_reqs);
-enum vk_texture_type
-{
- VULKAN_TEXTURE_STREAMED = 0,
- VULKAN_TEXTURE_STATIC,
- VULKAN_TEXTURE_READBACK
-};
struct vk_texture vulkan_create_texture(vk_t *vk,
struct vk_texture *old,
@@ -421,7 +432,7 @@ void vulkan_image_layout_transition(vk_t *vk, VkCommandBuffer cmd, VkImage image
VkAccessFlags srcAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags srcStages, VkPipelineStageFlags dstStages);
-static inline unsigned vulkan_format_to_bpp(VkFormat format)
+static INLINE unsigned vulkan_format_to_bpp(VkFormat format)
{
switch (format)
{
@@ -441,7 +452,7 @@ static inline unsigned vulkan_format_to_bpp(VkFormat format)
}
}
-static inline void vulkan_write_quad_vbo(struct vk_vertex *pv,
+static INLINE void vulkan_write_quad_vbo(struct vk_vertex *pv,
float x, float y, float width, float height,
float tex_x, float tex_y, float tex_width, float tex_height,
const struct vk_color *color)
@@ -470,12 +481,36 @@ struct vk_buffer vulkan_create_buffer(const struct vulkan_context *context,
size_t size, VkBufferUsageFlags usage);
void vulkan_destroy_buffer(VkDevice device, struct vk_buffer *buffer);
-VkDescriptorSet vulkan_descriptor_manager_alloc(VkDevice device, struct vk_descriptor_manager *manager);
+VkDescriptorSet vulkan_descriptor_manager_alloc(VkDevice device,
+ struct vk_descriptor_manager *manager);
+
void vulkan_descriptor_manager_restart(struct vk_descriptor_manager *manager);
+
struct vk_descriptor_manager vulkan_create_descriptor_manager(VkDevice device,
const VkDescriptorPoolSize *sizes, unsigned num_sizes,
VkDescriptorSetLayout set_layout);
void vulkan_destroy_descriptor_manager(VkDevice device,
struct vk_descriptor_manager *manager);
+
+bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
+ enum vulkan_wsi_type type);
+
+void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk,
+ bool destroy_surface);
+
+bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
+ enum vulkan_wsi_type type,
+ void *display, void *surface,
+ unsigned width, unsigned height,
+ unsigned swap_interval);
+
+void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index);
+
+void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk);
+
+bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
+ unsigned width, unsigned height,
+ unsigned swap_interval);
+
#endif
diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c
index cbe07a4a40..8a500814f9 100644
--- a/gfx/drivers_context/wayland_ctx.c
+++ b/gfx/drivers_context/wayland_ctx.c
@@ -45,11 +45,6 @@
static volatile sig_atomic_t g_quit = 0;
-#ifdef HAVE_VULKAN
-static VkInstance cached_instance;
-static VkDevice cached_device;
-#endif
-
typedef struct gfx_ctx_wayland_data
{
#ifdef HAVE_EGL
@@ -77,7 +72,6 @@ typedef struct gfx_ctx_wayland_data
#endif
} gfx_ctx_wayland_data_t;
-
static enum gfx_ctx_api wl_api;
#ifndef EGL_OPENGL_ES3_BIT_KHR
@@ -169,7 +163,8 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
id, &wl_compositor_interface, num);
}
else if (string_is_equal(interface, "wl_shell"))
- wl->shell = (struct wl_shell*)wl_registry_bind(reg, id, &wl_shell_interface, 1);
+ wl->shell = (struct wl_shell*)
+ wl_registry_bind(reg, id, &wl_shell_interface, 1);
}
static void registry_handle_global_remove(void *data,
@@ -188,46 +183,6 @@ static const struct wl_registry_listener registry_listener = {
static void gfx_ctx_wl_get_video_size(void *data,
unsigned *width, unsigned *height);
-#ifdef HAVE_VULKAN
-static void vulkan_destroy_context(gfx_ctx_vulkan_data_t *vk,
- bool destroy_surface)
-{
- unsigned i;
- if (vk->context.queue)
- vkQueueWaitIdle(vk->context.queue);
- if (vk->swapchain)
- vk->fpDestroySwapchainKHR(vk->context.device,
- vk->swapchain, NULL);
-
- if (destroy_surface)
- vk->fpDestroySurfaceKHR(vk->context.instance,
- vk->vk_surface, NULL);
-
- for (i = 0; i < VULKAN_MAX_SWAPCHAIN_IMAGES; i++)
- {
- if (vk->context.swapchain_semaphores[i] != VK_NULL_HANDLE)
- vkDestroySemaphore(vk->context.device,
- vk->context.swapchain_semaphores[i], NULL);
- if (vk->context.swapchain_fences[i] != VK_NULL_HANDLE)
- vkDestroyFence(vk->context.device,
- vk->context.swapchain_fences[i], NULL);
- }
-
- if (video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL))
- {
- cached_device = vk->context.device;
- cached_instance = vk->context.instance;
- }
- else
- {
- if (vk->context.device)
- vkDestroyDevice(vk->context.device, NULL);
- if (vk->context.instance)
- vkDestroyInstance(vk->context.instance, NULL);
- }
-}
-#endif
-
static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl)
{
if (!wl)
@@ -247,7 +202,7 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl)
break;
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
- vulkan_destroy_context(&wl->vk, wl->surface);
+ vulkan_context_destroy(&wl->vk, wl->surface);
if (wl->fd >= 0)
close(wl->fd);
@@ -352,183 +307,6 @@ static void gfx_ctx_wl_check_window(void *data, bool *quit,
*quit = g_quit;
}
-#ifdef HAVE_VULKAN
-static void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk)
-{
- unsigned index;
- VkResult err;
- VkFence fence;
- VkFence *next_fence;
- VkSemaphoreCreateInfo sem_info =
- { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
- VkFenceCreateInfo info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
-
- vkCreateFence(vk->context.device, &info, NULL, &fence);
-
- err = vk->fpAcquireNextImageKHR(vk->context.device,
- vk->swapchain, UINT64_MAX,
- VK_NULL_HANDLE, fence, &vk->context.current_swapchain_index);
-
- index = vk->context.current_swapchain_index;
- if (vk->context.swapchain_semaphores[index] == VK_NULL_HANDLE)
- vkCreateSemaphore(vk->context.device, &sem_info,
- NULL, &vk->context.swapchain_semaphores[index]);
-
- vkWaitForFences(vk->context.device, 1, &fence, true, UINT64_MAX);
- vkDestroyFence(vk->context.device, fence, NULL);
-
- next_fence = &vk->context.swapchain_fences[index];
- if (*next_fence != VK_NULL_HANDLE)
- {
- vkWaitForFences(vk->context.device, 1, next_fence, true, UINT64_MAX);
- vkResetFences(vk->context.device, 1, next_fence);
- }
- else
- vkCreateFence(vk->context.device, &info, NULL, next_fence);
-
- if (err != VK_SUCCESS)
- {
- RARCH_LOG("[Wayland/Vulkan]: AcquireNextImage failed, invalidating swapchain.\n");
- vk->context.invalid_swapchain = true;
- }
-}
-
-static bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
- unsigned width, unsigned height,
- unsigned swap_interval)
-{
- unsigned i;
- uint32_t format_count;
- uint32_t desired_swapchain_images;
- VkSurfaceCapabilitiesKHR surface_properties;
- VkSurfaceFormatKHR formats[256];
- VkSurfaceFormatKHR format;
- VkExtent2D swapchain_size;
- VkSwapchainKHR old_swapchain;
- VkSurfaceTransformFlagBitsKHR pre_transform;
- VkPresentModeKHR swapchain_present_mode = swap_interval
- ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_MAILBOX_KHR;
- VkSwapchainCreateInfoKHR info = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
-
- RARCH_LOG("[Wayland/Vulkan]: Creating swapchain with present mode: %u\n",
- (unsigned)swapchain_present_mode);
-
- vk->fpGetPhysicalDeviceSurfaceCapabilitiesKHR(vk->context.gpu,
- vk->vk_surface, &surface_properties);
- vk->fpGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
- vk->vk_surface, &format_count, NULL);
- vk->fpGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
- vk->vk_surface, &format_count, formats);
-
- if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED)
- {
- format = formats[0];
- format.format = VK_FORMAT_B8G8R8A8_UNORM;
- }
- else
- {
- if (format_count == 0)
- {
- RARCH_ERR("[Wayland Vulkan]: Surface has no formats.\n");
- return false;
- }
-
- format = formats[0];
- }
-
- if (surface_properties.currentExtent.width == -1)
- {
- swapchain_size.width = width;
- swapchain_size.height = height;
- }
- else
- swapchain_size = surface_properties.currentExtent;
-
- desired_swapchain_images = surface_properties.minImageCount + 1;
- if ((surface_properties.maxImageCount > 0)
- && (desired_swapchain_images > surface_properties.maxImageCount))
- desired_swapchain_images = surface_properties.maxImageCount;
-
- if (surface_properties.supportedTransforms
- & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
- pre_transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
- else
- pre_transform = surface_properties.currentTransform;
-
- old_swapchain = vk->swapchain;
-
- info.surface = vk->vk_surface;
- info.minImageCount = desired_swapchain_images;
- info.imageFormat = format.format;
- info.imageColorSpace = format.colorSpace;
- info.imageExtent.width = swapchain_size.width;
- info.imageExtent.height = swapchain_size.height;
- info.imageArrayLayers = 1;
- info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
- | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
- info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
- info.preTransform = pre_transform;
- info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
- info.presentMode = swapchain_present_mode;
- info.clipped = true;
- info.oldSwapchain = old_swapchain;
-
- vk->fpCreateSwapchainKHR(vk->context.device, &info, NULL, &vk->swapchain);
- if (old_swapchain != VK_NULL_HANDLE)
- vk->fpDestroySwapchainKHR(vk->context.device, old_swapchain, NULL);
-
- vk->context.swapchain_width = swapchain_size.width;
- vk->context.swapchain_height = swapchain_size.height;
-
- /* Make sure we create a backbuffer format that is as we expect. */
- switch (format.format)
- {
- case VK_FORMAT_B8G8R8A8_SRGB:
- vk->context.swapchain_format = VK_FORMAT_B8G8R8A8_UNORM;
- vk->context.swapchain_is_srgb = true;
- break;
-
- case VK_FORMAT_R8G8B8A8_SRGB:
- vk->context.swapchain_format = VK_FORMAT_R8G8B8A8_UNORM;
- vk->context.swapchain_is_srgb = true;
- break;
-
- case VK_FORMAT_R8G8B8_SRGB:
- vk->context.swapchain_format = VK_FORMAT_R8G8B8_UNORM;
- vk->context.swapchain_is_srgb = true;
- break;
-
- case VK_FORMAT_B8G8R8_SRGB:
- vk->context.swapchain_format = VK_FORMAT_B8G8R8_UNORM;
- vk->context.swapchain_is_srgb = true;
- break;
-
- default:
- vk->context.swapchain_format = format.format;
- break;
- }
-
- vk->fpGetSwapchainImagesKHR(vk->context.device, vk->swapchain,
- &vk->context.num_swapchain_images, NULL);
- vk->fpGetSwapchainImagesKHR(vk->context.device, vk->swapchain,
- &vk->context.num_swapchain_images, vk->context.swapchain_images);
-
- for (i = 0; i < vk->context.num_swapchain_images; i++)
- {
- if (vk->context.swapchain_fences[i])
- {
- vkDestroyFence(vk->context.device,
- vk->context.swapchain_fences[i], NULL);
- vk->context.swapchain_fences[i] = VK_NULL_HANDLE;
- }
- }
-
- vulkan_acquire_next_image(vk);
-
- return true;
-}
-#endif
-
static bool gfx_ctx_wl_set_resize(void *data, unsigned width, unsigned height)
{
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
@@ -603,225 +381,6 @@ static void gfx_ctx_wl_get_video_size(void *data,
EGL_DEPTH_SIZE, 0
#endif
-#ifdef HAVE_VULKAN
-
-#define VK_GET_INSTANCE_PROC_ADDR(vk, inst, entrypoint) do { \
- vk->fp##entrypoint = (PFN_vk##entrypoint) vkGetInstanceProcAddr(inst, "vk"#entrypoint); \
- if (vk->fp##entrypoint == NULL) { \
- RARCH_ERR("vkGetInstanceProcAddr failed to find vk%s\n", #entrypoint); \
- return false; \
- } \
-} while(0)
-
-#define VK_GET_DEVICE_PROC_ADDR(vk, dev, entrypoint) do { \
- vk->fp##entrypoint = (PFN_vk##entrypoint) vkGetDeviceProcAddr(dev, "vk" #entrypoint); \
- if (vk->fp##entrypoint == NULL) { \
- RARCH_ERR("vkGetDeviceProcAddr failed to find vk%s\n", #entrypoint); \
- return false; \
- } \
-} while(0)
-
-static bool vulkan_init_context(gfx_ctx_vulkan_data_t *vk,
- enum vulkan_wsi_type type)
-{
- unsigned i;
- uint32_t queue_count;
- VkQueueFamilyProperties queue_properties[32];
- VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
- VkApplicationInfo app = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
- VkPhysicalDeviceFeatures features = { false };
- VkDeviceQueueCreateInfo queue_info = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };
- VkDeviceCreateInfo device_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
- uint32_t gpu_count = 1;
- bool found_queue = false;
- static const float one = 1.0f;
- static const char *device_extensions[] = {
- "VK_KHR_swapchain",
- };
- static const char *instance_extensions[2];
-
- instance_extensions[0] = "VK_KHR_surface";
-
- switch (type)
- {
- case VULKAN_WSI_WAYLAND:
- instance_extensions[1] = "VK_KHR_wayland_surface";
- break;
- case VULKAN_WSI_ANDROID:
- instance_extensions[1] = "VK_KHR_android_surface";
- break;
- case VULKAN_WSI_WIN32:
- instance_extensions[1] = "VK_KHR_win32_surface";
- break;
- case VULKAN_WSI_XLIB:
- instance_extensions[1] = "VK_KHR_xlib_surface";
- break;
- case VULKAN_WSI_XCB:
- instance_extensions[1] = "VK_KHR_xcb_surface";
- break;
- case VULKAN_WSI_MIR:
- instance_extensions[1] = "VK_KHR_mir_surface";
- break;
- case VULKAN_WSI_NONE:
- default:
- break;
- }
-
- app.pApplicationName = "RetroArch";
- app.applicationVersion = 0;
- app.pEngineName = "RetroArch";
- app.engineVersion = 0;
- app.apiVersion = VK_API_VERSION;
-
- info.pApplicationInfo = &app;
- info.enabledExtensionCount = ARRAY_SIZE(instance_extensions);
- info.ppEnabledExtensionNames = instance_extensions;
-
- if (cached_instance)
- {
- vk->context.instance = cached_instance;
- cached_instance = NULL;
- }
- else if (vkCreateInstance(&info, NULL, &vk->context.instance) != VK_SUCCESS)
- return false;
-
- if (vkEnumeratePhysicalDevices(vk->context.instance,
- &gpu_count, &vk->context.gpu) != VK_SUCCESS)
- return false;
-
- if (gpu_count != 1)
- {
- RARCH_ERR("[Wayland/Vulkan]: Failed to enumerate Vulkan physical device.\n");
- return false;
- }
-
- vkGetPhysicalDeviceProperties(vk->context.gpu,
- &vk->context.gpu_properties);
- vkGetPhysicalDeviceMemoryProperties(vk->context.gpu,
- &vk->context.memory_properties);
- vkGetPhysicalDeviceQueueFamilyProperties(vk->context.gpu,
- &queue_count, NULL);
-
- if (queue_count < 1 || queue_count > 32)
- return false;
-
- vkGetPhysicalDeviceQueueFamilyProperties(vk->context.gpu,
- &queue_count, queue_properties);
-
- for (i = 0; i < queue_count; i++)
- {
- if (queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
- {
- vk->context.graphics_queue_index = i;
- RARCH_LOG("[Wayland/Vulkan]: Device supports %u sub-queues.\n",
- queue_properties[i].queueCount);
- found_queue = true;
- break;
- }
- }
-
- if (!found_queue)
- {
- RARCH_ERR("[Wayland/Vulkan]: Did not find suitable graphics queue.\n");
- return false;
- }
-
- queue_info.queueFamilyIndex = vk->context.graphics_queue_index;
- queue_info.queueCount = 1;
- queue_info.pQueuePriorities = &one;
-
- device_info.queueCreateInfoCount = 1;
- device_info.pQueueCreateInfos = &queue_info;
- device_info.enabledExtensionCount = ARRAY_SIZE(device_extensions);
- device_info.ppEnabledExtensionNames = device_extensions;
- device_info.pEnabledFeatures = &features;
-
- if (cached_device)
- {
- vk->context.device = cached_device;
- cached_device = NULL;
- video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL);
- RARCH_LOG("[Vulkan]: Using cached Vulkan context.\n");
- }
- else if (vkCreateDevice(vk->context.gpu, &device_info,
- NULL, &vk->context.device) != VK_SUCCESS)
- return false;
-
- vkGetDeviceQueue(vk->context.device,
- vk->context.graphics_queue_index, 0, &vk->context.queue);
-
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, GetPhysicalDeviceSurfaceSupportKHR);
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, GetPhysicalDeviceSurfaceCapabilitiesKHR);
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, GetPhysicalDeviceSurfaceFormatsKHR);
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, GetPhysicalDeviceSurfacePresentModesKHR);
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, DestroySurfaceKHR);
- VK_GET_DEVICE_PROC_ADDR(vk,
- vk->context.device, CreateSwapchainKHR);
- VK_GET_DEVICE_PROC_ADDR(vk,
- vk->context.device, DestroySwapchainKHR);
- VK_GET_DEVICE_PROC_ADDR(vk,
- vk->context.device, GetSwapchainImagesKHR);
- VK_GET_DEVICE_PROC_ADDR(vk,
- vk->context.device, AcquireNextImageKHR);
- VK_GET_DEVICE_PROC_ADDR(vk,
- vk->context.device, QueuePresentKHR);
-
- switch (type)
- {
- case VULKAN_WSI_WAYLAND:
-#ifdef HAVE_WAYLAND
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, CreateWaylandSurfaceKHR);
-#endif
- break;
- case VULKAN_WSI_ANDROID:
-#ifdef ANDROID
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, CreateAndroidSurfaceKHR);
-#endif
- break;
- case VULKAN_WSI_WIN32:
-#ifdef _WIN32
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, CreateWin32SurfaceKHR);
-#endif
- break;
- case VULKAN_WSI_XLIB:
-#ifdef HAVE_XLIB
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, CreateXlibSurfaceKHR);
-#endif
- break;
- case VULKAN_WSI_XCB:
-#ifdef HAVE_XCB
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, CreateXcbSurfaceKHR);
-#endif
- break;
- case VULKAN_WSI_MIR:
-#ifdef HAVE_MIR
- VK_GET_INSTANCE_PROC_ADDR(vk,
- vk->context.instance, CreateMirSurfaceKHR);
-#endif
- break;
- case VULKAN_WSI_NONE:
- default:
- break;
- }
-
- vk->context.queue_lock = slock_new();
- if (!vk->context.queue_lock)
- return false;
-
- return true;
-}
-#endif
-
static void *gfx_ctx_wl_init(void *video_driver)
{
@@ -965,7 +524,7 @@ static void *gfx_ctx_wl_init(void *video_driver)
break;
case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
- if (!vulkan_init_context(&wl->vk, VULKAN_WSI_WAYLAND))
+ if (!vulkan_context_init(&wl->vk, VULKAN_WSI_WAYLAND))
goto error;
#endif
break;
@@ -1108,138 +667,6 @@ static void gfx_ctx_wl_set_swap_interval(void *data, unsigned swap_interval)
}
}
-#ifdef HAVE_VULKAN
-static bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
- enum vulkan_wsi_type type,
- void *display, void *surface,
- unsigned width, unsigned height,
- unsigned swap_interval)
-{
- switch (type)
- {
- case VULKAN_WSI_WAYLAND:
-#ifdef HAVE_WAYLAND
- {
- VkWaylandSurfaceCreateInfoKHR surf_info;
-
- memset(&surf_info, 0, sizeof(VkWaylandSurfaceCreateInfoKHR));
-
- surf_info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
- surf_info.pNext = NULL;
- surf_info.flags = 0;
- surf_info.display = (struct wl_display*)display;
- surf_info.surface = (struct wl_surface*)surface;
-
- if (vk->fpCreateWaylandSurfaceKHR(vk->context.instance,
- &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS)
- return false;
- }
-#endif
- break;
- case VULKAN_WSI_ANDROID:
-#ifdef ANDROID
- {
- VkAndroidSurfaceCreateInfoKHR surf_info;
-
- memset(&surf_info, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
-
- surf_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
- surf_info.flags = 0;
- surf_info.window = (ANativeWindow*)surface;
-
- if (vk->fpCreateAndroidSurfaceKHR(vk->context.instance,
- &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS)
- return false;
- }
-#endif
- break;
- case VULKAN_WSI_WIN32:
-#ifdef _WIN32
- {
- VkWin32SurfaceCreateInfoKHR surf_info;
-
- memset(&surf_info, 0, sizeof(VkWin32SurfaceCreateInfoKHR));
-
- surf_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
- surf_info.flags = 0;
- surf_info.hinstance = display;
- surf_info.hwnd = surface;
-
- if (vk->fpCreateWin32SurfaceKHR(vk->context.instance,
- &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS)
- return false;
- }
-#endif
- break;
- case VULKAN_WSI_XLIB:
-#ifdef HAVE_XLIB
- {
- VkXlibSurfaceCreateInfoKHR surf_info;
-
- memset(&surf_info, 0, sizeof(VkXlibSurfaceCreateInfoKHR));
-
- surf_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
- surf_info.flags = 0;
- surf_info.dpy = display;
- surf_info.window = surface;
-
- if (vk->fpCreateXlibSurfaceKHR(vk->context.instance,
- &surf_info, NULL, &vk->vk_surface)
- != VK_SUCCESS)
- return false;
- }
-#endif
- break;
- case VULKAN_WSI_XCB:
-#ifdef HAVE_XCB
- {
- VkXcbSurfaceCreateInfoKHR surf_info;
-
- memset(&surf_info, 0, sizeof(VkXcbSurfaceCreateInfoKHR));
-
- surf_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
- surf_info.flags = 0;
- surf_info.connection = XGetXCBConnection(display);
- surf_info.window = (xcb_window_t)surface;
-
- if (vk->fpCreateXcbSurfaceKHR(vk->context.instance,
- &surf_info, NULL, &vk->vk_surface)
- != VK_SUCCESS)
- return false;
- }
-#endif
- break;
- case VULKAN_WSI_MIR:
-#ifdef HAVE_MIR
- {
- VkMirSurfaceCreateInfoKHR surf_info;
-
- memset(&surf_info, 0, sizeof(VkMirSurfaceCreateInfoKHR));
-
- surf_info.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
- surf_info.connection = display;
- surf_info.mirSurface = surface;
-
- if (vk->fpCreateMirSurfaceKHR(vk->context.instance,
- &surf_info, NULL, &vk->vk_surface)
- != VK_SUCCESS)
- return false;
- }
-#endif
- break;
- case VULKAN_WSI_NONE:
- default:
- return false;
- }
-
- if (!vulkan_create_swapchain(
- vk, width, height, swap_interval))
- return false;
-
- return true;
-}
-#endif
-
static bool gfx_ctx_wl_set_video_mode(void *data,
unsigned width, unsigned height,
bool fullscreen)
@@ -1559,37 +986,12 @@ static const struct wl_seat_listener seat_listener = {
seat_handle_capabilities,
};
-
#ifdef HAVE_VULKAN
static void *gfx_ctx_wl_get_context_data(void *data)
{
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
return &wl->vk.context;
}
-
-static void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index)
-{
- VkResult result = VK_SUCCESS;
- VkResult err = VK_SUCCESS;
- VkPresentInfoKHR present = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
- present.swapchainCount = 1;
- present.pSwapchains = &vk->swapchain;
- present.pImageIndices = &index;
- present.pResults = &result;
- present.waitSemaphoreCount = 1;
- present.pWaitSemaphores = &vk->context.swapchain_semaphores[index];
-
- /* Better hope QueuePresent doesn't block D: */
- slock_lock(vk->context.queue_lock);
- err = vk->fpQueuePresentKHR(vk->context.queue, &present);
-
- if (err != VK_SUCCESS || result != VK_SUCCESS)
- {
- RARCH_LOG("[Wayland/Vulkan]: QueuePresent failed, invalidating swapchain.\n");
- vk->context.invalid_swapchain = true;
- }
- slock_unlock(vk->context.queue_lock);
-}
#endif
static void gfx_ctx_wl_swap_buffers(void *data)