External Interop (#14)
parent
4783d2efc2
commit
b12b785dbe
|
@ -46,6 +46,12 @@
|
||||||
#endif /* __GNUC__ */
|
#endif /* __GNUC__ */
|
||||||
#endif /* REFRESHNAMELESS */
|
#endif /* REFRESHNAMELESS */
|
||||||
|
|
||||||
|
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
|
||||||
|
|
||||||
|
VK_DEFINE_HANDLE(VkInstance)
|
||||||
|
VK_DEFINE_HANDLE(VkDevice)
|
||||||
|
VK_DEFINE_HANDLE(VkPhysicalDevice)
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -608,6 +614,56 @@ typedef struct Refresh_FramebufferCreateInfo
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
} Refresh_FramebufferCreateInfo;
|
} Refresh_FramebufferCreateInfo;
|
||||||
|
|
||||||
|
/* Interop Structs */
|
||||||
|
|
||||||
|
typedef enum Refresh_SysRendererType
|
||||||
|
{
|
||||||
|
REFRESH_RENDERER_TYPE_VULKAN
|
||||||
|
} Refresh_SysRendererType;
|
||||||
|
|
||||||
|
typedef struct Refresh_SysRenderer
|
||||||
|
{
|
||||||
|
Refresh_SysRendererType rendererType;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
#if REFRESH_DRIVER_VULKAN
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
VkInstance instance;
|
||||||
|
VkPhysicalDevice physicalDevice;
|
||||||
|
VkDevice logicalDevice;
|
||||||
|
uint32_t queueFamilyIndex;
|
||||||
|
} vulkan;
|
||||||
|
#endif /* REFRESH_DRIVER_VULKAN */
|
||||||
|
uint8_t filler[64];
|
||||||
|
} renderer;
|
||||||
|
} Refresh_SysRenderer;
|
||||||
|
|
||||||
|
typedef struct Refresh_TextureHandles
|
||||||
|
{
|
||||||
|
Refresh_SysRendererType rendererType;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
#if REFRESH_DRIVER_VULKAN
|
||||||
|
|
||||||
|
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
|
||||||
|
#define REFRESH_VULKAN_HANDLE_TYPE void*
|
||||||
|
#else
|
||||||
|
#define REFRESH_VULKAN_HANDLE_TYPE uint64_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
REFRESH_VULKAN_HANDLE_TYPE image; /* VkImage */
|
||||||
|
REFRESH_VULKAN_HANDLE_TYPE view; /* VkImageView */
|
||||||
|
} vulkan;
|
||||||
|
#endif /* REFRESH_DRIVER_VULKAN */
|
||||||
|
uint8_t filler[64];
|
||||||
|
} texture;
|
||||||
|
} Refresh_TextureHandles;
|
||||||
|
|
||||||
/* Version API */
|
/* Version API */
|
||||||
|
|
||||||
#define REFRESH_ABI_VERSION 0
|
#define REFRESH_ABI_VERSION 0
|
||||||
|
@ -655,6 +711,18 @@ REFRESHAPI Refresh_Device* Refresh_CreateDevice(
|
||||||
uint8_t debugMode
|
uint8_t debugMode
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Create a rendering context by taking an externally-initialized VkDevice.
|
||||||
|
* Only valid with Vulkan backend.
|
||||||
|
* Useful for piggybacking on a separate graphics library like FNA3D.
|
||||||
|
*
|
||||||
|
* sysRenderer: Externally-initialized device info.
|
||||||
|
* debugMode: Enable debug mode properties.
|
||||||
|
*/
|
||||||
|
REFRESHAPI Refresh_Device* Refresh_CreateDeviceUsingExternal(
|
||||||
|
Refresh_SysRenderer *sysRenderer,
|
||||||
|
uint8_t debugMode
|
||||||
|
);
|
||||||
|
|
||||||
/* Destroys a rendering context previously returned by Refresh_CreateDevice. */
|
/* Destroys a rendering context previously returned by Refresh_CreateDevice. */
|
||||||
REFRESHAPI void Refresh_DestroyDevice(Refresh_Device *device);
|
REFRESHAPI void Refresh_DestroyDevice(Refresh_Device *device);
|
||||||
|
|
||||||
|
@ -1357,6 +1425,13 @@ REFRESHAPI void Refresh_Wait(
|
||||||
Refresh_Device *device
|
Refresh_Device *device
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Export handles to be consumed by another API */
|
||||||
|
REFRESHAPI void Refresh_GetTextureHandles(
|
||||||
|
Refresh_Device* device,
|
||||||
|
Refresh_Texture* texture,
|
||||||
|
Refresh_TextureHandles* handles
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
|
@ -141,6 +141,26 @@ Refresh_Device* Refresh_CreateDevice(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Refresh_Device* Refresh_CreateDeviceUsingExternal(
|
||||||
|
Refresh_SysRenderer *sysRenderer,
|
||||||
|
uint8_t debugMode
|
||||||
|
) {
|
||||||
|
if (selectedDriver < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sysRenderer == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drivers[selectedDriver]->CreateDeviceUsingExternal(
|
||||||
|
sysRenderer,
|
||||||
|
debugMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void Refresh_DestroyDevice(Refresh_Device *device)
|
void Refresh_DestroyDevice(Refresh_Device *device)
|
||||||
{
|
{
|
||||||
NULL_RETURN(device);
|
NULL_RETURN(device);
|
||||||
|
@ -895,4 +915,17 @@ void Refresh_Wait(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Refresh_GetTextureHandles(
|
||||||
|
Refresh_Device* device,
|
||||||
|
Refresh_Texture* texture,
|
||||||
|
Refresh_TextureHandles *handles
|
||||||
|
) {
|
||||||
|
NULL_RETURN(device);
|
||||||
|
return device->GetTextureHandles(
|
||||||
|
device->driverData,
|
||||||
|
texture,
|
||||||
|
handles
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
|
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
|
||||||
|
|
|
@ -526,6 +526,12 @@ struct Refresh_Device
|
||||||
Refresh_Renderer *driverData
|
Refresh_Renderer *driverData
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void(*GetTextureHandles)(
|
||||||
|
Refresh_Renderer *driverData,
|
||||||
|
Refresh_Texture *texture,
|
||||||
|
Refresh_TextureHandles *handles
|
||||||
|
);
|
||||||
|
|
||||||
/* Opaque pointer for the Driver */
|
/* Opaque pointer for the Driver */
|
||||||
Refresh_Renderer *driverData;
|
Refresh_Renderer *driverData;
|
||||||
};
|
};
|
||||||
|
@ -583,7 +589,8 @@ struct Refresh_Device
|
||||||
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
|
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
|
||||||
ASSIGN_DRIVER_FUNC(QueuePresent, name) \
|
ASSIGN_DRIVER_FUNC(QueuePresent, name) \
|
||||||
ASSIGN_DRIVER_FUNC(Submit, name) \
|
ASSIGN_DRIVER_FUNC(Submit, name) \
|
||||||
ASSIGN_DRIVER_FUNC(Wait, name)
|
ASSIGN_DRIVER_FUNC(Wait, name) \
|
||||||
|
ASSIGN_DRIVER_FUNC(GetTextureHandles, name)
|
||||||
|
|
||||||
typedef struct Refresh_Driver
|
typedef struct Refresh_Driver
|
||||||
{
|
{
|
||||||
|
@ -592,6 +599,10 @@ typedef struct Refresh_Driver
|
||||||
Refresh_PresentationParameters *presentationParameters,
|
Refresh_PresentationParameters *presentationParameters,
|
||||||
uint8_t debugMode
|
uint8_t debugMode
|
||||||
);
|
);
|
||||||
|
Refresh_Device* (*CreateDeviceUsingExternal)(
|
||||||
|
Refresh_SysRenderer *sysRenderer,
|
||||||
|
uint8_t debugMode
|
||||||
|
);
|
||||||
} Refresh_Driver;
|
} Refresh_Driver;
|
||||||
|
|
||||||
extern Refresh_Driver VulkanDriver;
|
extern Refresh_Driver VulkanDriver;
|
||||||
|
|
|
@ -1446,6 +1446,10 @@ typedef struct VulkanRenderer
|
||||||
uint32_t submittedRenderPassesToDestroyCount;
|
uint32_t submittedRenderPassesToDestroyCount;
|
||||||
uint32_t submittedRenderPassesToDestroyCapacity;
|
uint32_t submittedRenderPassesToDestroyCapacity;
|
||||||
|
|
||||||
|
/* External Interop */
|
||||||
|
|
||||||
|
uint8_t usesExternalDevice;
|
||||||
|
|
||||||
#define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \
|
#define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \
|
||||||
vkfntype_##func func;
|
vkfntype_##func func;
|
||||||
#define VULKAN_DEVICE_FUNCTION(ext, ret, func, params) \
|
#define VULKAN_DEVICE_FUNCTION(ext, ret, func, params) \
|
||||||
|
@ -3650,8 +3654,11 @@ static void VULKAN_DestroyDevice(
|
||||||
|
|
||||||
SDL_free(renderer->buffersInUse);
|
SDL_free(renderer->buffersInUse);
|
||||||
|
|
||||||
renderer->vkDestroyDevice(renderer->logicalDevice, NULL);
|
if (!renderer->usesExternalDevice)
|
||||||
renderer->vkDestroyInstance(renderer->instance, NULL);
|
{
|
||||||
|
renderer->vkDestroyDevice(renderer->logicalDevice, NULL);
|
||||||
|
renderer->vkDestroyInstance(renderer->instance, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_free(renderer);
|
SDL_free(renderer);
|
||||||
SDL_free(device);
|
SDL_free(device);
|
||||||
|
@ -8226,7 +8233,7 @@ static void VULKAN_Submit(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
submitInfo.pWaitDstStageMask = NULL;
|
submitInfo.pWaitDstStageMask = waitStages;
|
||||||
submitInfo.signalSemaphoreCount = 0;
|
submitInfo.signalSemaphoreCount = 0;
|
||||||
submitInfo.pSignalSemaphores = NULL;
|
submitInfo.pSignalSemaphores = NULL;
|
||||||
}
|
}
|
||||||
|
@ -8380,6 +8387,21 @@ static void VULKAN_Wait(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* External interop */
|
||||||
|
|
||||||
|
static void VULKAN_GetTextureHandles(
|
||||||
|
Refresh_Renderer* driverData,
|
||||||
|
Refresh_Texture* texture,
|
||||||
|
Refresh_TextureHandles *handles
|
||||||
|
) {
|
||||||
|
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||||
|
VulkanTexture *vulkanTexture = (VulkanTexture*) texture;
|
||||||
|
|
||||||
|
handles->rendererType = REFRESH_RENDERER_TYPE_VULKAN;
|
||||||
|
handles->texture.vulkan.image = vulkanTexture->image;
|
||||||
|
handles->texture.vulkan.view = vulkanTexture->view;
|
||||||
|
}
|
||||||
|
|
||||||
/* Device instantiation */
|
/* Device instantiation */
|
||||||
|
|
||||||
static inline uint8_t VULKAN_INTERNAL_SupportsExtension(
|
static inline uint8_t VULKAN_INTERNAL_SupportsExtension(
|
||||||
|
@ -8768,6 +8790,24 @@ static uint8_t VULKAN_INTERNAL_IsDeviceSuitable(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VULKAN_INTERNAL_GetPhysicalDeviceProperties(
|
||||||
|
VulkanRenderer *renderer
|
||||||
|
) {
|
||||||
|
renderer->physicalDeviceDriverProperties.sType =
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
|
||||||
|
renderer->physicalDeviceDriverProperties.pNext = NULL;
|
||||||
|
|
||||||
|
renderer->physicalDeviceProperties.sType =
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||||
|
renderer->physicalDeviceProperties.pNext =
|
||||||
|
&renderer->physicalDeviceDriverProperties;
|
||||||
|
|
||||||
|
renderer->vkGetPhysicalDeviceProperties2KHR(
|
||||||
|
renderer->physicalDevice,
|
||||||
|
&renderer->physicalDeviceProperties
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t VULKAN_INTERNAL_DeterminePhysicalDevice(
|
static uint8_t VULKAN_INTERNAL_DeterminePhysicalDevice(
|
||||||
VulkanRenderer *renderer,
|
VulkanRenderer *renderer,
|
||||||
const char **deviceExtensionNames,
|
const char **deviceExtensionNames,
|
||||||
|
@ -8855,19 +8895,7 @@ static uint8_t VULKAN_INTERNAL_DeterminePhysicalDevice(
|
||||||
renderer->physicalDevice = physicalDevice;
|
renderer->physicalDevice = physicalDevice;
|
||||||
renderer->queueFamilyIndices = queueFamilyIndices;
|
renderer->queueFamilyIndices = queueFamilyIndices;
|
||||||
|
|
||||||
renderer->physicalDeviceDriverProperties.sType =
|
VULKAN_INTERNAL_GetPhysicalDeviceProperties(renderer);
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
|
|
||||||
renderer->physicalDeviceDriverProperties.pNext = NULL;
|
|
||||||
|
|
||||||
renderer->physicalDeviceProperties.sType =
|
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
|
||||||
renderer->physicalDeviceProperties.pNext =
|
|
||||||
&renderer->physicalDeviceDriverProperties;
|
|
||||||
|
|
||||||
renderer->vkGetPhysicalDeviceProperties2KHR(
|
|
||||||
renderer->physicalDevice,
|
|
||||||
&renderer->physicalDeviceProperties
|
|
||||||
);
|
|
||||||
|
|
||||||
SDL_stack_free(physicalDevices);
|
SDL_stack_free(physicalDevices);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -8991,12 +9019,44 @@ static uint8_t VULKAN_INTERNAL_CreateLogicalDevice(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Refresh_Device* VULKAN_CreateDevice(
|
static void VULKAN_INTERNAL_LoadEntryPoints(
|
||||||
Refresh_PresentationParameters *presentationParameters,
|
VulkanRenderer *renderer
|
||||||
uint8_t debugMode
|
) {
|
||||||
|
/* Load Vulkan entry points */
|
||||||
|
if (SDL_Vulkan_LoadLibrary(NULL) < 0)
|
||||||
|
{
|
||||||
|
Refresh_LogWarn("Vulkan: SDL_Vulkan_LoadLibrary failed!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||||
|
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr();
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
if (vkGetInstanceProcAddr == NULL)
|
||||||
|
{
|
||||||
|
Refresh_LogWarn(
|
||||||
|
"SDL_Vulkan_GetVkGetInstanceProcAddr(): %s",
|
||||||
|
SDL_GetError()
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VULKAN_GLOBAL_FUNCTION(name) \
|
||||||
|
name = (PFN_##name) vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \
|
||||||
|
if (name == NULL) \
|
||||||
|
{ \
|
||||||
|
Refresh_LogWarn("vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed"); \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
#include "Refresh_Driver_Vulkan_vkfuncs.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expects a partially initialized VulkanRenderer */
|
||||||
|
static Refresh_Device* VULKAN_INTERNAL_CreateDevice(
|
||||||
|
VulkanRenderer *renderer
|
||||||
) {
|
) {
|
||||||
Refresh_Device *result;
|
Refresh_Device *result;
|
||||||
VulkanRenderer *renderer;
|
|
||||||
|
|
||||||
VkResult vulkanResult;
|
VkResult vulkanResult;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -9028,124 +9088,7 @@ static Refresh_Device* VULKAN_CreateDevice(
|
||||||
result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device));
|
result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device));
|
||||||
ASSIGN_DRIVER(VULKAN)
|
ASSIGN_DRIVER(VULKAN)
|
||||||
|
|
||||||
renderer = (VulkanRenderer*) SDL_malloc(sizeof(VulkanRenderer));
|
|
||||||
|
|
||||||
/* Load Vulkan entry points */
|
|
||||||
if (SDL_Vulkan_LoadLibrary(NULL) < 0)
|
|
||||||
{
|
|
||||||
Refresh_LogWarn("Vulkan: SDL_Vulkan_LoadLibrary failed!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
||||||
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) SDL_Vulkan_GetVkGetInstanceProcAddr();
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
if (vkGetInstanceProcAddr == NULL)
|
|
||||||
{
|
|
||||||
Refresh_LogWarn(
|
|
||||||
"SDL_Vulkan_GetVkGetInstanceProcAddr(): %s",
|
|
||||||
SDL_GetError()
|
|
||||||
);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define VULKAN_GLOBAL_FUNCTION(name) \
|
|
||||||
name = (PFN_##name) vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \
|
|
||||||
if (name == NULL) \
|
|
||||||
{ \
|
|
||||||
Refresh_LogWarn("vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed"); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
#include "Refresh_Driver_Vulkan_vkfuncs.h"
|
|
||||||
|
|
||||||
result->driverData = (Refresh_Renderer*) renderer;
|
result->driverData = (Refresh_Renderer*) renderer;
|
||||||
renderer->debugMode = debugMode;
|
|
||||||
renderer->headless = presentationParameters->deviceWindowHandle == NULL;
|
|
||||||
|
|
||||||
/* Create the VkInstance */
|
|
||||||
if (!VULKAN_INTERNAL_CreateInstance(renderer, presentationParameters->deviceWindowHandle))
|
|
||||||
{
|
|
||||||
Refresh_LogError("Error creating vulkan instance");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer->deviceWindowHandle = presentationParameters->deviceWindowHandle;
|
|
||||||
renderer->presentMode = presentationParameters->presentMode;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the WSI vkSurface
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!SDL_Vulkan_CreateSurface(
|
|
||||||
(SDL_Window*) renderer->deviceWindowHandle,
|
|
||||||
renderer->instance,
|
|
||||||
&renderer->surface
|
|
||||||
)) {
|
|
||||||
Refresh_LogError(
|
|
||||||
"SDL_Vulkan_CreateSurface failed: %s",
|
|
||||||
SDL_GetError()
|
|
||||||
);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get vkInstance entry points
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \
|
|
||||||
renderer->func = (vkfntype_##func) vkGetInstanceProcAddr(renderer->instance, #func);
|
|
||||||
#include "Refresh_Driver_Vulkan_vkfuncs.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Choose/Create vkDevice
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (SDL_strcmp(SDL_GetPlatform(), "Stadia") != 0)
|
|
||||||
{
|
|
||||||
deviceExtensionCount -= 1;
|
|
||||||
}
|
|
||||||
if (!VULKAN_INTERNAL_DeterminePhysicalDevice(
|
|
||||||
renderer,
|
|
||||||
deviceExtensionNames,
|
|
||||||
deviceExtensionCount
|
|
||||||
)) {
|
|
||||||
Refresh_LogError("Failed to determine a suitable physical device");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Refresh_LogInfo("Refresh Driver: Vulkan");
|
|
||||||
Refresh_LogInfo(
|
|
||||||
"Vulkan Device: %s",
|
|
||||||
renderer->physicalDeviceProperties.properties.deviceName
|
|
||||||
);
|
|
||||||
Refresh_LogInfo(
|
|
||||||
"Vulkan Driver: %s %s",
|
|
||||||
renderer->physicalDeviceDriverProperties.driverName,
|
|
||||||
renderer->physicalDeviceDriverProperties.driverInfo
|
|
||||||
);
|
|
||||||
Refresh_LogInfo(
|
|
||||||
"Vulkan Conformance: %u.%u.%u",
|
|
||||||
renderer->physicalDeviceDriverProperties.conformanceVersion.major,
|
|
||||||
renderer->physicalDeviceDriverProperties.conformanceVersion.minor,
|
|
||||||
renderer->physicalDeviceDriverProperties.conformanceVersion.patch
|
|
||||||
);
|
|
||||||
Refresh_LogWarn(
|
|
||||||
"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
|
||||||
"! Refresh Vulkan is still in development! !\n"
|
|
||||||
"! The API is unstable and subject to change! !\n"
|
|
||||||
"! You have been warned! !\n"
|
|
||||||
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!VULKAN_INTERNAL_CreateLogicalDevice(
|
|
||||||
renderer,
|
|
||||||
deviceExtensionNames,
|
|
||||||
deviceExtensionCount
|
|
||||||
)) {
|
|
||||||
Refresh_LogError("Failed to create logical device");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create initial swapchain
|
* Create initial swapchain
|
||||||
|
@ -9818,9 +9761,181 @@ static Refresh_Device* VULKAN_CreateDevice(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Refresh_Device* VULKAN_CreateDevice(
|
||||||
|
Refresh_PresentationParameters *presentationParameters,
|
||||||
|
uint8_t debugMode
|
||||||
|
) {
|
||||||
|
VulkanRenderer *renderer = (VulkanRenderer*) SDL_malloc(sizeof(VulkanRenderer));
|
||||||
|
|
||||||
|
VULKAN_INTERNAL_LoadEntryPoints(renderer);
|
||||||
|
|
||||||
|
/* Create the VkInstance */
|
||||||
|
if (!VULKAN_INTERNAL_CreateInstance(renderer, presentationParameters->deviceWindowHandle))
|
||||||
|
{
|
||||||
|
Refresh_LogError("Error creating vulkan instance");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->deviceWindowHandle = presentationParameters->deviceWindowHandle;
|
||||||
|
renderer->presentMode = presentationParameters->presentMode;
|
||||||
|
renderer->debugMode = debugMode;
|
||||||
|
renderer->headless = presentationParameters->deviceWindowHandle == NULL;
|
||||||
|
renderer->usesExternalDevice = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the WSI vkSurface
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!SDL_Vulkan_CreateSurface(
|
||||||
|
(SDL_Window*)renderer->deviceWindowHandle,
|
||||||
|
renderer->instance,
|
||||||
|
&renderer->surface
|
||||||
|
)) {
|
||||||
|
Refresh_LogError(
|
||||||
|
"SDL_Vulkan_CreateSurface failed: %s",
|
||||||
|
SDL_GetError()
|
||||||
|
);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get vkInstance entry points
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \
|
||||||
|
renderer->func = (vkfntype_##func) vkGetInstanceProcAddr(renderer->instance, #func);
|
||||||
|
#include "Refresh_Driver_Vulkan_vkfuncs.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Choose/Create vkDevice
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (SDL_strcmp(SDL_GetPlatform(), "Stadia") != 0)
|
||||||
|
{
|
||||||
|
deviceExtensionCount -= 1;
|
||||||
|
}
|
||||||
|
if (!VULKAN_INTERNAL_DeterminePhysicalDevice(
|
||||||
|
renderer,
|
||||||
|
deviceExtensionNames,
|
||||||
|
deviceExtensionCount
|
||||||
|
)) {
|
||||||
|
Refresh_LogError("Failed to determine a suitable physical device");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Refresh_LogInfo("Refresh Driver: Vulkan");
|
||||||
|
Refresh_LogInfo(
|
||||||
|
"Vulkan Device: %s",
|
||||||
|
renderer->physicalDeviceProperties.properties.deviceName
|
||||||
|
);
|
||||||
|
Refresh_LogInfo(
|
||||||
|
"Vulkan Driver: %s %s",
|
||||||
|
renderer->physicalDeviceDriverProperties.driverName,
|
||||||
|
renderer->physicalDeviceDriverProperties.driverInfo
|
||||||
|
);
|
||||||
|
Refresh_LogInfo(
|
||||||
|
"Vulkan Conformance: %u.%u.%u",
|
||||||
|
renderer->physicalDeviceDriverProperties.conformanceVersion.major,
|
||||||
|
renderer->physicalDeviceDriverProperties.conformanceVersion.minor,
|
||||||
|
renderer->physicalDeviceDriverProperties.conformanceVersion.patch
|
||||||
|
);
|
||||||
|
Refresh_LogWarn(
|
||||||
|
"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||||
|
"! Refresh Vulkan is still in development! !\n"
|
||||||
|
"! The API is unstable and subject to change! !\n"
|
||||||
|
"! You have been warned! !\n"
|
||||||
|
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!VULKAN_INTERNAL_CreateLogicalDevice(
|
||||||
|
renderer,
|
||||||
|
deviceExtensionNames,
|
||||||
|
deviceExtensionCount
|
||||||
|
)) {
|
||||||
|
Refresh_LogError("Failed to create logical device");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VULKAN_INTERNAL_CreateDevice(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Refresh_Device* VULKAN_CreateDeviceUsingExternal(
|
||||||
|
Refresh_SysRenderer *sysRenderer,
|
||||||
|
uint8_t debugMode
|
||||||
|
) {
|
||||||
|
VulkanRenderer* renderer = (VulkanRenderer*)SDL_malloc(sizeof(VulkanRenderer));
|
||||||
|
|
||||||
|
renderer->instance = sysRenderer->renderer.vulkan.instance;
|
||||||
|
renderer->physicalDevice = sysRenderer->renderer.vulkan.physicalDevice;
|
||||||
|
renderer->logicalDevice = sysRenderer->renderer.vulkan.logicalDevice;
|
||||||
|
renderer->queueFamilyIndices.computeFamily = sysRenderer->renderer.vulkan.queueFamilyIndex;
|
||||||
|
renderer->queueFamilyIndices.graphicsFamily = sysRenderer->renderer.vulkan.queueFamilyIndex;
|
||||||
|
renderer->queueFamilyIndices.presentFamily = sysRenderer->renderer.vulkan.queueFamilyIndex;
|
||||||
|
renderer->queueFamilyIndices.transferFamily = sysRenderer->renderer.vulkan.queueFamilyIndex;
|
||||||
|
renderer->deviceWindowHandle = NULL;
|
||||||
|
renderer->presentMode = 0;
|
||||||
|
renderer->debugMode = debugMode;
|
||||||
|
renderer->headless = 1;
|
||||||
|
renderer->usesExternalDevice = 1;
|
||||||
|
|
||||||
|
VULKAN_INTERNAL_LoadEntryPoints(renderer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get vkInstance entry points
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \
|
||||||
|
renderer->func = (vkfntype_##func) vkGetInstanceProcAddr(renderer->instance, #func);
|
||||||
|
#include "Refresh_Driver_Vulkan_vkfuncs.h"
|
||||||
|
|
||||||
|
/* Load vkDevice entry points */
|
||||||
|
|
||||||
|
#define VULKAN_DEVICE_FUNCTION(ext, ret, func, params) \
|
||||||
|
renderer->func = (vkfntype_##func) \
|
||||||
|
renderer->vkGetDeviceProcAddr( \
|
||||||
|
renderer->logicalDevice, \
|
||||||
|
#func \
|
||||||
|
);
|
||||||
|
#include "Refresh_Driver_Vulkan_vkfuncs.h"
|
||||||
|
|
||||||
|
renderer->vkGetDeviceQueue(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
renderer->queueFamilyIndices.graphicsFamily,
|
||||||
|
0,
|
||||||
|
&renderer->graphicsQueue
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer->vkGetDeviceQueue(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
renderer->queueFamilyIndices.presentFamily,
|
||||||
|
0,
|
||||||
|
&renderer->presentQueue
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer->vkGetDeviceQueue(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
renderer->queueFamilyIndices.computeFamily,
|
||||||
|
0,
|
||||||
|
&renderer->computeQueue
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer->vkGetDeviceQueue(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
renderer->queueFamilyIndices.transferFamily,
|
||||||
|
0,
|
||||||
|
&renderer->transferQueue
|
||||||
|
);
|
||||||
|
|
||||||
|
VULKAN_INTERNAL_GetPhysicalDeviceProperties(renderer);
|
||||||
|
|
||||||
|
return VULKAN_INTERNAL_CreateDevice(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Refresh_Driver VulkanDriver = {
|
Refresh_Driver VulkanDriver = {
|
||||||
"Vulkan",
|
"Vulkan",
|
||||||
VULKAN_CreateDevice
|
VULKAN_CreateDevice,
|
||||||
|
VULKAN_CreateDeviceUsingExternal
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //REFRESH_DRIVER_VULKAN
|
#endif //REFRESH_DRIVER_VULKAN
|
||||||
|
|
Loading…
Reference in New Issue