mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 04:20:27 +00:00
Vulkan: Begin hooking up negotiation interface.
This commit is contained in:
parent
6ab368811f
commit
10a6d7a458
15
dynamic.c
15
dynamic.c
@ -1434,9 +1434,7 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
|||||||
{
|
{
|
||||||
RARCH_WARN("Environ SET_MEMORY_MAPS, but system pointer not initialized..\n");
|
RARCH_WARN("Environ SET_MEMORY_MAPS, but system pointer not initialized..\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1495,7 +1493,16 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
|||||||
cheevos_set_support_cheevos(state);
|
cheevos_set_support_cheevos(state);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE:
|
||||||
|
{
|
||||||
|
const struct retro_hw_render_context_negotiation_interface *iface =
|
||||||
|
(const struct retro_hw_render_context_negotiation_interface*)data;
|
||||||
|
RARCH_LOG("Environ SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE.\n");
|
||||||
|
video_driver_set_context_negotiation_interface(iface);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Default */
|
/* Default */
|
||||||
default:
|
default:
|
||||||
|
@ -1372,150 +1372,30 @@ end:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool vulkan_context_init_device(gfx_ctx_vulkan_data_t *vk)
|
||||||
bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
|
||||||
enum vulkan_wsi_type type)
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
bool use_device_ext;
|
||||||
uint32_t queue_count;
|
static const float one = 1.0f;
|
||||||
VkResult res;
|
|
||||||
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;
|
uint32_t gpu_count = 1;
|
||||||
bool found_queue = false;
|
bool found_queue = false;
|
||||||
VkPhysicalDevice *gpus = NULL;
|
VkPhysicalDevice *gpus = NULL;
|
||||||
static const float one = 1.0f;
|
|
||||||
|
VkPhysicalDeviceFeatures features = { false };
|
||||||
|
VkDeviceQueueCreateInfo queue_info = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };
|
||||||
|
VkDeviceCreateInfo device_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
|
||||||
|
VkQueueFamilyProperties queue_properties[32];
|
||||||
|
uint32_t queue_count;
|
||||||
|
VkResult res;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
static const char *device_extensions[] = {
|
static const char *device_extensions[] = {
|
||||||
"VK_KHR_swapchain",
|
"VK_KHR_swapchain",
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef VULKAN_DEBUG
|
#ifdef VULKAN_DEBUG
|
||||||
const char *instance_extensions[3];
|
|
||||||
instance_extensions[2] = "VK_EXT_debug_report";
|
|
||||||
static const char *instance_layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
|
||||||
static const char *device_layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
static const char *device_layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
||||||
#else
|
|
||||||
const char *instance_extensions[2];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool use_instance_ext, use_device_ext;
|
|
||||||
|
|
||||||
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:
|
|
||||||
instance_extensions[1] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
vulkan_library = dylib_load("vulkan-1.dll");
|
|
||||||
#else
|
|
||||||
vulkan_library = dylib_load("libvulkan.so");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!vulkan_library)
|
|
||||||
{
|
|
||||||
RARCH_ERR("[Vulkan]: Failed to open Vulkan loader.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RARCH_LOG("Vulkan dynamic library loaded.\n");
|
|
||||||
|
|
||||||
VKSYM(vk, GetInstanceProcAddr);
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(EnumerateInstanceExtensionProperties);
|
|
||||||
|
|
||||||
use_instance_ext = vulkan_find_instance_extensions(instance_extensions, ARRAY_SIZE(instance_extensions));
|
|
||||||
|
|
||||||
app.pApplicationName = "RetroArch";
|
|
||||||
app.applicationVersion = 0;
|
|
||||||
app.pEngineName = "RetroArch";
|
|
||||||
app.engineVersion = 0;
|
|
||||||
app.apiVersion = VK_MAKE_VERSION(1, 0, 6);
|
|
||||||
|
|
||||||
info.pApplicationInfo = &app;
|
|
||||||
info.enabledExtensionCount = use_instance_ext ? ARRAY_SIZE(instance_extensions) : 0;
|
|
||||||
info.ppEnabledExtensionNames = use_instance_ext ? instance_extensions : NULL;
|
|
||||||
#ifdef VULKAN_DEBUG
|
|
||||||
info.enabledLayerCount = ARRAY_SIZE(instance_layers);
|
|
||||||
info.ppEnabledLayerNames = instance_layers;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cached_instance)
|
|
||||||
{
|
|
||||||
vk->context.instance = cached_instance;
|
|
||||||
cached_instance = NULL;
|
|
||||||
res = VK_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This will be called with a NULL instance, which
|
|
||||||
* is what we want. */
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateInstance);
|
|
||||||
res = VKFUNC(vkCreateInstance)(&info, NULL, &vk->context.instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VULKAN_DEBUG
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateDebugReportCallbackEXT);
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(DebugReportMessageEXT);
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(DestroyDebugReportCallbackEXT);
|
|
||||||
|
|
||||||
{
|
|
||||||
VkDebugReportCallbackCreateInfoEXT info =
|
|
||||||
{ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT };
|
|
||||||
info.flags =
|
|
||||||
VK_DEBUG_REPORT_ERROR_BIT_EXT |
|
|
||||||
VK_DEBUG_REPORT_WARNING_BIT_EXT |
|
|
||||||
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
|
||||||
info.pfnCallback = vulkan_debug_cb;
|
|
||||||
VKFUNC(vkCreateDebugReportCallbackEXT)(vk->context.instance, &info, NULL, &vk->context.debug_callback);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Try different API versions if driver has compatible
|
|
||||||
* but slightly different VK_API_VERSION. */
|
|
||||||
for (i = 1; i < 4 && res == VK_ERROR_INCOMPATIBLE_DRIVER; i++)
|
|
||||||
{
|
|
||||||
app.apiVersion = VK_MAKE_VERSION(1, 0, i);
|
|
||||||
res = VKFUNC(vkCreateInstance)(&info, NULL, &vk->context.instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == VK_ERROR_INCOMPATIBLE_DRIVER)
|
|
||||||
{
|
|
||||||
RARCH_ERR("Failed to create Vulkan instance.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vulkan_load_instance_symbols(vk))
|
|
||||||
{
|
|
||||||
RARCH_ERR("[Vulkan]: Failed to load instance symbols.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VKFUNC(vkEnumeratePhysicalDevices)(vk->context.instance,
|
if (VKFUNC(vkEnumeratePhysicalDevices)(vk->context.instance,
|
||||||
&gpu_count, NULL) != VK_SUCCESS)
|
&gpu_count, NULL) != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -1594,8 +1474,8 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
|||||||
device_info.ppEnabledExtensionNames = use_device_ext ? device_extensions : NULL;
|
device_info.ppEnabledExtensionNames = use_device_ext ? device_extensions : NULL;
|
||||||
device_info.pEnabledFeatures = &features;
|
device_info.pEnabledFeatures = &features;
|
||||||
#ifdef VULKAN_DEBUG
|
#ifdef VULKAN_DEBUG
|
||||||
info.enabledLayerCount = ARRAY_SIZE(device_layers);
|
device_info.enabledLayerCount = ARRAY_SIZE(device_layers);
|
||||||
info.ppEnabledLayerNames = device_layers;
|
device_info.ppEnabledLayerNames = device_layers;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cached_device)
|
if (cached_device)
|
||||||
@ -1622,43 +1502,6 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
|||||||
VKFUNC(vkGetDeviceQueue)(vk->context.device,
|
VKFUNC(vkGetDeviceQueue)(vk->context.device,
|
||||||
vk->context.graphics_queue_index, 0, &vk->context.queue);
|
vk->context.graphics_queue_index, 0, &vk->context.queue);
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case VULKAN_WSI_WAYLAND:
|
|
||||||
#ifdef HAVE_WAYLAND
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateWaylandSurfaceKHR);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VULKAN_WSI_ANDROID:
|
|
||||||
#ifdef ANDROID
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateAndroidSurfaceKHR);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VULKAN_WSI_WIN32:
|
|
||||||
#ifdef _WIN32
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateWin32SurfaceKHR);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VULKAN_WSI_XLIB:
|
|
||||||
#ifdef HAVE_XLIB
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateXlibSurfaceKHR);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VULKAN_WSI_XCB:
|
|
||||||
#ifdef HAVE_XCB
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateXcbSurfaceKHR);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VULKAN_WSI_MIR:
|
|
||||||
#ifdef HAVE_MIR
|
|
||||||
VK_GET_INSTANCE_PROC_ADDR(CreateMirSurfaceKHR);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case VULKAN_WSI_NONE:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
vk->context.queue_lock = slock_new();
|
vk->context.queue_lock = slock_new();
|
||||||
if (!vk->context.queue_lock)
|
if (!vk->context.queue_lock)
|
||||||
@ -1671,6 +1514,171 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
||||||
|
enum vulkan_wsi_type type)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
VkResult res;
|
||||||
|
VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
|
||||||
|
VkApplicationInfo app = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
|
||||||
|
#ifdef VULKAN_DEBUG
|
||||||
|
const char *instance_extensions[3];
|
||||||
|
instance_extensions[2] = "VK_EXT_debug_report";
|
||||||
|
static const char *instance_layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
||||||
|
#else
|
||||||
|
const char *instance_extensions[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool use_instance_ext;
|
||||||
|
struct retro_hw_render_context_negotiation_interface_vulkan *iface =
|
||||||
|
(struct retro_hw_render_context_negotiation_interface_vulkan*)video_driver_get_context_negotiation_interface();
|
||||||
|
|
||||||
|
if (iface && iface->interface_type != RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN)
|
||||||
|
{
|
||||||
|
RARCH_WARN("[Vulkan]: Got HW context negotiation interface, but it's the wrong API.\n");
|
||||||
|
iface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iface && iface->interface_version != RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION)
|
||||||
|
{
|
||||||
|
RARCH_WARN("[Vulkan]: Got HW context negotiation interface, but it's the wrong interface version.\n");
|
||||||
|
iface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
instance_extensions[1] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
vulkan_library = dylib_load("vulkan-1.dll");
|
||||||
|
#else
|
||||||
|
vulkan_library = dylib_load("libvulkan.so");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!vulkan_library)
|
||||||
|
{
|
||||||
|
RARCH_ERR("[Vulkan]: Failed to open Vulkan loader.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RARCH_LOG("Vulkan dynamic library loaded.\n");
|
||||||
|
|
||||||
|
VKSYM(vk, GetInstanceProcAddr);
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(EnumerateInstanceExtensionProperties);
|
||||||
|
|
||||||
|
use_instance_ext = vulkan_find_instance_extensions(instance_extensions, ARRAY_SIZE(instance_extensions));
|
||||||
|
|
||||||
|
app.pApplicationName = "RetroArch";
|
||||||
|
app.applicationVersion = 0;
|
||||||
|
app.pEngineName = "RetroArch";
|
||||||
|
app.engineVersion = 0;
|
||||||
|
app.apiVersion = VK_MAKE_VERSION(1, 0, 18);
|
||||||
|
|
||||||
|
info.pApplicationInfo = &app;
|
||||||
|
info.enabledExtensionCount = use_instance_ext ? ARRAY_SIZE(instance_extensions) : 0;
|
||||||
|
info.ppEnabledExtensionNames = use_instance_ext ? instance_extensions : NULL;
|
||||||
|
#ifdef VULKAN_DEBUG
|
||||||
|
info.enabledLayerCount = ARRAY_SIZE(instance_layers);
|
||||||
|
info.ppEnabledLayerNames = instance_layers;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (iface && iface->get_application_info)
|
||||||
|
{
|
||||||
|
info.pApplicationInfo = iface->get_application_info();
|
||||||
|
if (info.pApplicationInfo->pApplicationName)
|
||||||
|
{
|
||||||
|
RARCH_LOG("[Vulkan]: App: %s (version %u)\n",
|
||||||
|
info.pApplicationInfo->pApplicationName,
|
||||||
|
info.pApplicationInfo->applicationVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.pApplicationInfo->pEngineName)
|
||||||
|
{
|
||||||
|
RARCH_LOG("[Vulkan]: Engine: %s (version %u)\n",
|
||||||
|
info.pApplicationInfo->pEngineName,
|
||||||
|
info.pApplicationInfo->engineVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cached_instance)
|
||||||
|
{
|
||||||
|
vk->context.instance = cached_instance;
|
||||||
|
cached_instance = NULL;
|
||||||
|
res = VK_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This will be called with a NULL instance, which
|
||||||
|
* is what we want. */
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateInstance);
|
||||||
|
res = VKFUNC(vkCreateInstance)(&info, NULL, &vk->context.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VULKAN_DEBUG
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateDebugReportCallbackEXT);
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(DebugReportMessageEXT);
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(DestroyDebugReportCallbackEXT);
|
||||||
|
|
||||||
|
{
|
||||||
|
VkDebugReportCallbackCreateInfoEXT info =
|
||||||
|
{ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT };
|
||||||
|
info.flags =
|
||||||
|
VK_DEBUG_REPORT_ERROR_BIT_EXT |
|
||||||
|
VK_DEBUG_REPORT_WARNING_BIT_EXT |
|
||||||
|
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||||
|
info.pfnCallback = vulkan_debug_cb;
|
||||||
|
VKFUNC(vkCreateDebugReportCallbackEXT)(vk->context.instance, &info, NULL, &vk->context.debug_callback);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Try different API versions if driver has compatible
|
||||||
|
* but slightly different VK_API_VERSION. */
|
||||||
|
for (i = 1; i < 4 && res == VK_ERROR_INCOMPATIBLE_DRIVER; i++)
|
||||||
|
{
|
||||||
|
info.pApplicationInfo = &app;
|
||||||
|
app.apiVersion = VK_MAKE_VERSION(1, 0, i);
|
||||||
|
res = VKFUNC(vkCreateInstance)(&info, NULL, &vk->context.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == VK_ERROR_INCOMPATIBLE_DRIVER)
|
||||||
|
{
|
||||||
|
RARCH_ERR("Failed to create Vulkan instance.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vulkan_load_instance_symbols(vk))
|
||||||
|
{
|
||||||
|
RARCH_ERR("[Vulkan]: Failed to load instance symbols.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||||
enum vulkan_wsi_type type,
|
enum vulkan_wsi_type type,
|
||||||
void *display, void *surface,
|
void *display, void *surface,
|
||||||
@ -1681,6 +1689,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
|||||||
{
|
{
|
||||||
case VULKAN_WSI_WAYLAND:
|
case VULKAN_WSI_WAYLAND:
|
||||||
#ifdef HAVE_WAYLAND
|
#ifdef HAVE_WAYLAND
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateWaylandSurfaceKHR);
|
||||||
{
|
{
|
||||||
VkWaylandSurfaceCreateInfoKHR surf_info;
|
VkWaylandSurfaceCreateInfoKHR surf_info;
|
||||||
|
|
||||||
@ -1700,6 +1709,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
|||||||
break;
|
break;
|
||||||
case VULKAN_WSI_ANDROID:
|
case VULKAN_WSI_ANDROID:
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateAndroidSurfaceKHR);
|
||||||
{
|
{
|
||||||
VkAndroidSurfaceCreateInfoKHR surf_info;
|
VkAndroidSurfaceCreateInfoKHR surf_info;
|
||||||
|
|
||||||
@ -1722,6 +1732,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
|||||||
break;
|
break;
|
||||||
case VULKAN_WSI_WIN32:
|
case VULKAN_WSI_WIN32:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateWin32SurfaceKHR);
|
||||||
{
|
{
|
||||||
VkWin32SurfaceCreateInfoKHR surf_info;
|
VkWin32SurfaceCreateInfoKHR surf_info;
|
||||||
|
|
||||||
@ -1740,6 +1751,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
|||||||
break;
|
break;
|
||||||
case VULKAN_WSI_XLIB:
|
case VULKAN_WSI_XLIB:
|
||||||
#ifdef HAVE_XLIB
|
#ifdef HAVE_XLIB
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateXlibSurfaceKHR);
|
||||||
{
|
{
|
||||||
VkXlibSurfaceCreateInfoKHR surf_info;
|
VkXlibSurfaceCreateInfoKHR surf_info;
|
||||||
|
|
||||||
@ -1760,6 +1772,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
|||||||
case VULKAN_WSI_XCB:
|
case VULKAN_WSI_XCB:
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
#ifdef HAVE_XCB
|
#ifdef HAVE_XCB
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateXcbSurfaceKHR);
|
||||||
{
|
{
|
||||||
VkXcbSurfaceCreateInfoKHR surf_info;
|
VkXcbSurfaceCreateInfoKHR surf_info;
|
||||||
|
|
||||||
@ -1780,6 +1793,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
|||||||
break;
|
break;
|
||||||
case VULKAN_WSI_MIR:
|
case VULKAN_WSI_MIR:
|
||||||
#ifdef HAVE_MIR
|
#ifdef HAVE_MIR
|
||||||
|
VK_GET_INSTANCE_PROC_ADDR(CreateMirSurfaceKHR);
|
||||||
{
|
{
|
||||||
VkMirSurfaceCreateInfoKHR surf_info;
|
VkMirSurfaceCreateInfoKHR surf_info;
|
||||||
|
|
||||||
@ -1801,6 +1815,10 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Must create device after surface since we need to be able to query queues to use for presentation. */
|
||||||
|
if (!vulkan_context_init_device(vk))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!vulkan_create_swapchain(
|
if (!vulkan_create_swapchain(
|
||||||
vk, width, height, swap_interval))
|
vk, width, height, swap_interval))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1283,6 +1283,8 @@ void video_driver_menu_settings(void **list_data, void *list_info_data,
|
|||||||
* used for GLES.
|
* used for GLES.
|
||||||
* TODO: Refactor this better. */
|
* TODO: Refactor this better. */
|
||||||
static struct retro_hw_render_callback hw_render;
|
static struct retro_hw_render_callback hw_render;
|
||||||
|
static const struct retro_hw_render_context_negotiation_interface *hw_render_context_negotiation;
|
||||||
|
|
||||||
static bool video_driver_use_rgba = false;
|
static bool video_driver_use_rgba = false;
|
||||||
static bool video_driver_data_own = false;
|
static bool video_driver_data_own = false;
|
||||||
static bool video_driver_active = false;
|
static bool video_driver_active = false;
|
||||||
@ -1820,6 +1822,7 @@ void video_driver_deinit_hw_context(void)
|
|||||||
hw_render.context_destroy();
|
hw_render.context_destroy();
|
||||||
|
|
||||||
memset(&hw_render, 0, sizeof(hw_render));
|
memset(&hw_render, 0, sizeof(hw_render));
|
||||||
|
hw_render_context_negotiation = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct retro_hw_render_callback *video_driver_get_hw_context(void)
|
struct retro_hw_render_callback *video_driver_get_hw_context(void)
|
||||||
@ -1827,6 +1830,16 @@ struct retro_hw_render_callback *video_driver_get_hw_context(void)
|
|||||||
return &hw_render;
|
return &hw_render;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct retro_hw_render_context_negotiation_interface *video_driver_get_context_negotiation_interface(void)
|
||||||
|
{
|
||||||
|
return hw_render_context_negotiation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void video_driver_set_context_negotiation_interface(const struct retro_hw_render_context_negotiation_interface *iface)
|
||||||
|
{
|
||||||
|
hw_render_context_negotiation = iface;
|
||||||
|
}
|
||||||
|
|
||||||
void video_driver_set_video_cache_context(void)
|
void video_driver_set_video_cache_context(void)
|
||||||
{
|
{
|
||||||
video_driver_cache_context = true;
|
video_driver_cache_context = true;
|
||||||
|
@ -312,6 +312,8 @@ bool video_driver_owns_driver(void);
|
|||||||
bool video_driver_is_hw_context(void);
|
bool video_driver_is_hw_context(void);
|
||||||
void video_driver_deinit_hw_context(void);
|
void video_driver_deinit_hw_context(void);
|
||||||
struct retro_hw_render_callback *video_driver_get_hw_context(void);
|
struct retro_hw_render_callback *video_driver_get_hw_context(void);
|
||||||
|
const struct retro_hw_render_context_negotiation_interface *video_driver_get_context_negotiation_interface(void);
|
||||||
|
void video_driver_set_context_negotiation_interface(const struct retro_hw_render_context_negotiation_interface *iface);
|
||||||
void video_driver_set_video_cache_context(void);
|
void video_driver_set_video_cache_context(void);
|
||||||
void video_driver_unset_video_cache_context(void);
|
void video_driver_unset_video_cache_context(void);
|
||||||
bool video_driver_is_video_cache_context(void);
|
bool video_driver_is_video_cache_context(void);
|
||||||
|
@ -51,20 +51,27 @@ typedef void (*retro_vulkan_wait_sync_index_t)(void *handle);
|
|||||||
typedef void (*retro_vulkan_lock_queue_t)(void *handle);
|
typedef void (*retro_vulkan_lock_queue_t)(void *handle);
|
||||||
typedef void (*retro_vulkan_unlock_queue_t)(void *handle);
|
typedef void (*retro_vulkan_unlock_queue_t)(void *handle);
|
||||||
|
|
||||||
|
typedef const VkApplicationInfo *(*retro_vulkan_get_application_info_t)(void);
|
||||||
|
|
||||||
struct retro_vulkan_context
|
struct retro_vulkan_context
|
||||||
{
|
{
|
||||||
VkPhysicalDevice gpu;
|
VkPhysicalDevice gpu;
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
VkQueue queue;
|
VkQueue queue;
|
||||||
uint32_t queue_family_index;
|
uint32_t queue_family_index;
|
||||||
|
VkQueue presentation_queue;
|
||||||
|
uint32_t presentation_queue_family_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void *(*retro_vulkan_create_device_t)(
|
typedef bool (*retro_vulkan_create_device_t)(
|
||||||
struct retro_vulkan_context *context,
|
struct retro_vulkan_context *context,
|
||||||
VkInstance instance,
|
VkInstance instance,
|
||||||
PFN_vkGetInstanceProcAddr get_proc_addr,
|
VkSurfaceKHR surface,
|
||||||
|
PFN_vkGetInstanceProcAddr get_instance_proc_addr,
|
||||||
const char **required_device_extensions,
|
const char **required_device_extensions,
|
||||||
unsigned num_required_device_extensions,
|
unsigned num_required_device_extensions,
|
||||||
|
const char **required_device_layers,
|
||||||
|
unsigned num_required_device_layers,
|
||||||
const VkPhysicalDeviceFeatures *required_features);
|
const VkPhysicalDeviceFeatures *required_features);
|
||||||
|
|
||||||
typedef void (*retro_vulkan_destroy_handle_t)(void *data);
|
typedef void (*retro_vulkan_destroy_handle_t)(void *data);
|
||||||
@ -79,12 +86,31 @@ typedef void (*retro_vulkan_destroy_handle_t)(void *data);
|
|||||||
struct retro_hw_render_context_negotiation_interface_vulkan
|
struct retro_hw_render_context_negotiation_interface_vulkan
|
||||||
{
|
{
|
||||||
/* Must be set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN. */
|
/* Must be set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN. */
|
||||||
enum retro_hw_render_interface_type interface_type;
|
enum retro_hw_render_context_negotiation_interface_type interface_type;
|
||||||
/* Must be set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION. */
|
/* Must be set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION. */
|
||||||
unsigned interface_version;
|
unsigned interface_version;
|
||||||
|
|
||||||
|
/* If non-NULL, returns a VkApplicationInfo struct that the frontend can use instead of
|
||||||
|
* its "default" application info.
|
||||||
|
*/
|
||||||
|
retro_vulkan_get_application_info_t get_application_info;
|
||||||
|
|
||||||
|
/* If non-NULL, the libretro core will choose one or more physical devices,
|
||||||
|
* create one or more logical devices and create one or more queues.
|
||||||
|
* The core must prepare a designated PhysicalDevice, Device, Queue and queue family index
|
||||||
|
* which the frontend will use for its internal operation.
|
||||||
|
*
|
||||||
|
* The frontend will request certain extensions and layers for a device which is created.
|
||||||
|
* The core must ensure that the queue and queue_family_index support GRAPHICS and COMPUTE.
|
||||||
|
*
|
||||||
|
* If presentation to "surface" is supported on the queue, presentation_queue must be equal to queue.
|
||||||
|
* If not, a second queue must be provided in presentation_queue and presentation_queue_index.
|
||||||
|
*
|
||||||
|
* The core is free to set its own queue priorities.
|
||||||
|
* Device provided to frontend is owned by the frontend, but any additional device resources must be freed by core
|
||||||
|
* in either destroy_context callback or retro_unload_game().
|
||||||
|
*/
|
||||||
retro_vulkan_create_device_t create_device;
|
retro_vulkan_create_device_t create_device;
|
||||||
retro_vulkan_destroy_handle_t destroy_handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct retro_hw_render_interface_vulkan
|
struct retro_hw_render_interface_vulkan
|
||||||
@ -108,11 +134,6 @@ struct retro_hw_render_interface_vulkan
|
|||||||
*/
|
*/
|
||||||
void *handle;
|
void *handle;
|
||||||
|
|
||||||
/* An opaque handle that is used to pass data from context negotiation interface
|
|
||||||
* to the hardware interface.
|
|
||||||
*/
|
|
||||||
void *core_handle;
|
|
||||||
|
|
||||||
/* The Vulkan instance the context is using. */
|
/* The Vulkan instance the context is using. */
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
/* The physical device used. */
|
/* The physical device used. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user