mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 00:20:01 +00:00
Vulkan: Begin hooking up negotiation interface.
This commit is contained in:
parent
6ab368811f
commit
10a6d7a458
13
dynamic.c
13
dynamic.c
@ -1435,8 +1435,6 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
RARCH_WARN("Environ SET_MEMORY_MAPS, but system pointer not initialized..\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1495,7 +1493,16 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
cheevos_set_support_cheevos(state);
|
||||
}
|
||||
#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:
|
||||
|
@ -1372,150 +1372,30 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
||||
enum vulkan_wsi_type type)
|
||||
static bool vulkan_context_init_device(gfx_ctx_vulkan_data_t *vk)
|
||||
{
|
||||
unsigned i;
|
||||
uint32_t queue_count;
|
||||
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 };
|
||||
bool use_device_ext;
|
||||
static const float one = 1.0f;
|
||||
uint32_t gpu_count = 1;
|
||||
bool found_queue = false;
|
||||
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[] = {
|
||||
"VK_KHR_swapchain",
|
||||
};
|
||||
|
||||
#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" };
|
||||
#else
|
||||
const char *instance_extensions[2];
|
||||
#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,
|
||||
&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.pEnabledFeatures = &features;
|
||||
#ifdef VULKAN_DEBUG
|
||||
info.enabledLayerCount = ARRAY_SIZE(device_layers);
|
||||
info.ppEnabledLayerNames = device_layers;
|
||||
device_info.enabledLayerCount = ARRAY_SIZE(device_layers);
|
||||
device_info.ppEnabledLayerNames = device_layers;
|
||||
#endif
|
||||
|
||||
if (cached_device)
|
||||
@ -1622,43 +1502,6 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
||||
VKFUNC(vkGetDeviceQueue)(vk->context.device,
|
||||
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
|
||||
vk->context.queue_lock = slock_new();
|
||||
if (!vk->context.queue_lock)
|
||||
@ -1671,6 +1514,171 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
||||
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,
|
||||
enum vulkan_wsi_type type,
|
||||
void *display, void *surface,
|
||||
@ -1681,6 +1689,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||
{
|
||||
case VULKAN_WSI_WAYLAND:
|
||||
#ifdef HAVE_WAYLAND
|
||||
VK_GET_INSTANCE_PROC_ADDR(CreateWaylandSurfaceKHR);
|
||||
{
|
||||
VkWaylandSurfaceCreateInfoKHR surf_info;
|
||||
|
||||
@ -1700,6 +1709,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||
break;
|
||||
case VULKAN_WSI_ANDROID:
|
||||
#ifdef ANDROID
|
||||
VK_GET_INSTANCE_PROC_ADDR(CreateAndroidSurfaceKHR);
|
||||
{
|
||||
VkAndroidSurfaceCreateInfoKHR surf_info;
|
||||
|
||||
@ -1722,6 +1732,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||
break;
|
||||
case VULKAN_WSI_WIN32:
|
||||
#ifdef _WIN32
|
||||
VK_GET_INSTANCE_PROC_ADDR(CreateWin32SurfaceKHR);
|
||||
{
|
||||
VkWin32SurfaceCreateInfoKHR surf_info;
|
||||
|
||||
@ -1740,6 +1751,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||
break;
|
||||
case VULKAN_WSI_XLIB:
|
||||
#ifdef HAVE_XLIB
|
||||
VK_GET_INSTANCE_PROC_ADDR(CreateXlibSurfaceKHR);
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR surf_info;
|
||||
|
||||
@ -1760,6 +1772,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||
case VULKAN_WSI_XCB:
|
||||
#ifdef HAVE_X11
|
||||
#ifdef HAVE_XCB
|
||||
VK_GET_INSTANCE_PROC_ADDR(CreateXcbSurfaceKHR);
|
||||
{
|
||||
VkXcbSurfaceCreateInfoKHR surf_info;
|
||||
|
||||
@ -1780,6 +1793,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||
break;
|
||||
case VULKAN_WSI_MIR:
|
||||
#ifdef HAVE_MIR
|
||||
VK_GET_INSTANCE_PROC_ADDR(CreateMirSurfaceKHR);
|
||||
{
|
||||
VkMirSurfaceCreateInfoKHR surf_info;
|
||||
|
||||
@ -1801,6 +1815,10 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
|
||||
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(
|
||||
vk, width, height, swap_interval))
|
||||
return false;
|
||||
|
@ -1283,6 +1283,8 @@ void video_driver_menu_settings(void **list_data, void *list_info_data,
|
||||
* used for GLES.
|
||||
* TODO: Refactor this better. */
|
||||
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_data_own = false;
|
||||
static bool video_driver_active = false;
|
||||
@ -1820,6 +1822,7 @@ void video_driver_deinit_hw_context(void)
|
||||
hw_render.context_destroy();
|
||||
|
||||
memset(&hw_render, 0, sizeof(hw_render));
|
||||
hw_render_context_negotiation = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
video_driver_cache_context = true;
|
||||
|
@ -312,6 +312,8 @@ bool video_driver_owns_driver(void);
|
||||
bool video_driver_is_hw_context(void);
|
||||
void video_driver_deinit_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_unset_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_unlock_queue_t)(void *handle);
|
||||
|
||||
typedef const VkApplicationInfo *(*retro_vulkan_get_application_info_t)(void);
|
||||
|
||||
struct retro_vulkan_context
|
||||
{
|
||||
VkPhysicalDevice gpu;
|
||||
VkDevice device;
|
||||
VkQueue queue;
|
||||
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,
|
||||
VkInstance instance,
|
||||
PFN_vkGetInstanceProcAddr get_proc_addr,
|
||||
VkSurfaceKHR surface,
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc_addr,
|
||||
const char **required_device_extensions,
|
||||
unsigned num_required_device_extensions,
|
||||
const char **required_device_layers,
|
||||
unsigned num_required_device_layers,
|
||||
const VkPhysicalDeviceFeatures *required_features);
|
||||
|
||||
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
|
||||
{
|
||||
/* 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. */
|
||||
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_destroy_handle_t destroy_handle;
|
||||
};
|
||||
|
||||
struct retro_hw_render_interface_vulkan
|
||||
@ -108,11 +134,6 @@ struct retro_hw_render_interface_vulkan
|
||||
*/
|
||||
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. */
|
||||
VkInstance instance;
|
||||
/* The physical device used. */
|
||||
|
Loading…
Reference in New Issue
Block a user