mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-04-05 07:09:32 +00:00
gpu: Vulkan feature/extension lists do not need to be stored in the renderer
This commit is contained in:
@@ -1079,6 +1079,24 @@ struct VulkanCommandPool
|
||||
Uint32 inactiveCommandBufferCount;
|
||||
};
|
||||
|
||||
// Feature Checks
|
||||
|
||||
typedef struct VulkanFeatures
|
||||
{
|
||||
Uint32 desiredApiVersion;
|
||||
VkPhysicalDeviceFeatures desiredVulkan10DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan11Features desiredVulkan11DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan12Features desiredVulkan12DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan13Features desiredVulkan13DeviceFeatures;
|
||||
|
||||
bool usesCustomVulkanOptions;
|
||||
|
||||
Uint32 additionalDeviceExtensionCount;
|
||||
const char **additionalDeviceExtensionNames;
|
||||
Uint32 additionalInstanceExtensionCount;
|
||||
const char **additionalInstanceExtensionNames;
|
||||
} VulkanFeatures;
|
||||
|
||||
// Context
|
||||
|
||||
struct VulkanRenderer
|
||||
@@ -1087,23 +1105,12 @@ struct VulkanRenderer
|
||||
VkPhysicalDevice physicalDevice;
|
||||
VkPhysicalDeviceProperties2KHR physicalDeviceProperties;
|
||||
VkPhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties;
|
||||
VkPhysicalDeviceFeatures desiredVulkan10DeviceFeatures;
|
||||
VkDevice logicalDevice;
|
||||
Uint8 integratedMemoryNotification;
|
||||
Uint8 outOfDeviceLocalMemoryWarning;
|
||||
Uint8 outofBARMemoryWarning;
|
||||
Uint8 fillModeOnlyWarning;
|
||||
|
||||
bool usesCustomVulkanOptions;
|
||||
Uint32 desiredApiVersion;
|
||||
VkPhysicalDeviceVulkan11Features desiredVulkan11DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan12Features desiredVulkan12DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan13Features desiredVulkan13DeviceFeatures;
|
||||
Uint32 additionalDeviceExtensionCount;
|
||||
const char **additionalDeviceExtensionNames;
|
||||
Uint32 additionalInstanceExtensionCount;
|
||||
const char **additionalInstanceExtensionNames;
|
||||
|
||||
bool debugMode;
|
||||
bool preferLowPower;
|
||||
bool requireHardwareAcceleration;
|
||||
@@ -11128,23 +11135,22 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
|
||||
return allExtensionsSupported;
|
||||
}
|
||||
|
||||
static Uint8 CheckOptInDeviceExtensions(VulkanRenderer *renderer,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
static Uint8 CheckOptInDeviceExtensions(VulkanFeatures *features,
|
||||
Uint32 numExtensions,
|
||||
VkExtensionProperties *availableExtensions,
|
||||
const char **missingExtensionName) {
|
||||
Uint8 supportsAll = 1;
|
||||
for (Uint32 extensionIdx = 0; extensionIdx < renderer->additionalDeviceExtensionCount; extensionIdx++) {
|
||||
for (Uint32 extensionIdx = 0; extensionIdx < features->additionalDeviceExtensionCount; extensionIdx++) {
|
||||
bool found = false;
|
||||
for (Uint32 searchIdx = 0; searchIdx < numExtensions; searchIdx++) {
|
||||
if (SDL_strcmp(renderer->additionalDeviceExtensionNames[extensionIdx], availableExtensions[searchIdx].extensionName) == 0) {
|
||||
if (SDL_strcmp(features->additionalDeviceExtensionNames[extensionIdx], availableExtensions[searchIdx].extensionName) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
supportsAll = 0;
|
||||
*missingExtensionName = renderer->additionalDeviceExtensionNames[extensionIdx];
|
||||
*missingExtensionName = features->additionalDeviceExtensionNames[extensionIdx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -11154,6 +11160,7 @@ static Uint8 CheckOptInDeviceExtensions(VulkanRenderer *renderer,
|
||||
|
||||
static Uint8 VULKAN_INTERNAL_CheckDeviceExtensions(
|
||||
VulkanRenderer *renderer,
|
||||
VulkanFeatures *features,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VulkanExtensions *physicalDeviceExtensions)
|
||||
{
|
||||
@@ -11179,9 +11186,9 @@ static Uint8 VULKAN_INTERNAL_CheckDeviceExtensions(
|
||||
extensionCount,
|
||||
physicalDeviceExtensions);
|
||||
|
||||
if (renderer->usesCustomVulkanOptions) {
|
||||
if (features->usesCustomVulkanOptions) {
|
||||
const char *missingExtensionName;
|
||||
if (!CheckOptInDeviceExtensions(renderer, physicalDevice, extensionCount, availableExtensions, &missingExtensionName)) {
|
||||
if (!CheckOptInDeviceExtensions(features, extensionCount, availableExtensions, &missingExtensionName)) {
|
||||
SDL_assert(missingExtensionName);
|
||||
if (renderer->debugMode) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_GPU,
|
||||
@@ -11416,14 +11423,14 @@ static bool VULKAN_INTERNAL_ValidateOptInVulkan13Features(VkPhysicalDeviceVulkan
|
||||
|
||||
#undef CHECK_OPTIONAL_DEVICE_FEATURE
|
||||
|
||||
static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *vk10Features)
|
||||
static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VulkanFeatures *features, VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *vk10Features)
|
||||
{
|
||||
bool supportsAllFeatures = true;
|
||||
|
||||
int minorVersion = VK_API_VERSION_MINOR(renderer->desiredApiVersion);
|
||||
int minorVersion = VK_API_VERSION_MINOR(features->desiredApiVersion);
|
||||
|
||||
if (minorVersion < 1) {
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&renderer->desiredVulkan10DeviceFeatures, vk10Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&features->desiredVulkan10DeviceFeatures, vk10Features);
|
||||
} else if (minorVersion < 2) {
|
||||
// Query device features using the pre-1.2 structures
|
||||
VkPhysicalDevice16BitStorageFeatures storage = { 0 };
|
||||
@@ -11472,8 +11479,8 @@ static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VkPh
|
||||
vk11Features.variablePointersStorageBuffer = varPointers.variablePointersStorageBuffer;
|
||||
|
||||
// Check support
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&renderer->desiredVulkan10DeviceFeatures, vk10Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&renderer->desiredVulkan11DeviceFeatures, &vk11Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&features->desiredVulkan10DeviceFeatures, vk10Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&features->desiredVulkan11DeviceFeatures, &vk11Features);
|
||||
} else {
|
||||
VkPhysicalDeviceVulkan11Features vk11Features = { 0 };
|
||||
vk11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
|
||||
@@ -11492,10 +11499,10 @@ static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VkPh
|
||||
|
||||
renderer->vkGetPhysicalDeviceFeatures2(physicalDevice, &supportedFeatureList);
|
||||
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&renderer->desiredVulkan10DeviceFeatures, vk10Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&renderer->desiredVulkan11DeviceFeatures, &vk11Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan12Features(&renderer->desiredVulkan12DeviceFeatures, &vk12Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan13Features(&renderer->desiredVulkan13DeviceFeatures, &vk13Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&features->desiredVulkan10DeviceFeatures, vk10Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&features->desiredVulkan11DeviceFeatures, &vk11Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan12Features(&features->desiredVulkan12DeviceFeatures, &vk12Features);
|
||||
supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan13Features(&features->desiredVulkan13DeviceFeatures, &vk13Features);
|
||||
}
|
||||
|
||||
return supportsAllFeatures;
|
||||
@@ -11629,35 +11636,35 @@ static bool VULKAN_INTERNAL_TryAddDeviceFeatures_Vulkan_12_Or_Later(VkPhysicalDe
|
||||
return hasAdded;
|
||||
}
|
||||
|
||||
static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, VulkanRenderer *renderer)
|
||||
static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, VulkanRenderer *renderer, VulkanFeatures *features)
|
||||
{
|
||||
if (SDL_HasProperty(props, SDL_PROP_GPU_DEVICE_CREATE_VULKAN_OPTIONS_POINTER)) {
|
||||
SDL_GPUVulkanOptions *options = (SDL_GPUVulkanOptions *)SDL_GetPointerProperty(props, SDL_PROP_GPU_DEVICE_CREATE_VULKAN_OPTIONS_POINTER, NULL);
|
||||
if (options) {
|
||||
renderer->usesCustomVulkanOptions = true;
|
||||
renderer->desiredApiVersion = options->vulkan_api_version;
|
||||
features->usesCustomVulkanOptions = true;
|
||||
features->desiredApiVersion = options->vulkan_api_version;
|
||||
|
||||
SDL_memset(&renderer->desiredVulkan11DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan11Features));
|
||||
SDL_memset(&renderer->desiredVulkan12DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan12Features));
|
||||
SDL_memset(&renderer->desiredVulkan13DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan13Features));
|
||||
renderer->desiredVulkan11DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
|
||||
renderer->desiredVulkan12DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
|
||||
renderer->desiredVulkan13DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
|
||||
SDL_memset(&features->desiredVulkan11DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan11Features));
|
||||
SDL_memset(&features->desiredVulkan12DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan12Features));
|
||||
SDL_memset(&features->desiredVulkan13DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan13Features));
|
||||
features->desiredVulkan11DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
|
||||
features->desiredVulkan12DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
|
||||
features->desiredVulkan13DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
|
||||
|
||||
// Handle requested device features
|
||||
VkPhysicalDeviceFeatures *vk10Features = &renderer->desiredVulkan10DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan11Features *vk11Features = &renderer->desiredVulkan11DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan12Features *vk12Features = &renderer->desiredVulkan12DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan13Features *vk13Features = &renderer->desiredVulkan13DeviceFeatures;
|
||||
VkPhysicalDeviceFeatures *vk10Features = &features->desiredVulkan10DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan11Features *vk11Features = &features->desiredVulkan11DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan12Features *vk12Features = &features->desiredVulkan12DeviceFeatures;
|
||||
VkPhysicalDeviceVulkan13Features *vk13Features = &features->desiredVulkan13DeviceFeatures;
|
||||
|
||||
if (options->vulkan_10_physical_device_features) {
|
||||
VkPhysicalDeviceFeatures *features = (VkPhysicalDeviceFeatures *)options->vulkan_10_physical_device_features;
|
||||
VkPhysicalDeviceFeatures *deviceFeatures = (VkPhysicalDeviceFeatures *)options->vulkan_10_physical_device_features;
|
||||
VULKAN_INTERNAL_AddDeviceFeatures(&vk10Features->robustBufferAccess,
|
||||
&vk10Features->inheritedQueries,
|
||||
&features->robustBufferAccess);
|
||||
&deviceFeatures->robustBufferAccess);
|
||||
}
|
||||
|
||||
int minorVersion = VK_API_VERSION_MINOR(renderer->desiredApiVersion);
|
||||
int minorVersion = VK_API_VERSION_MINOR(features->desiredApiVersion);
|
||||
bool supportsHigherLevelFeatures = minorVersion > 0;
|
||||
if (supportsHigherLevelFeatures && options->feature_list) {
|
||||
if (minorVersion < 2) {
|
||||
@@ -11675,17 +11682,17 @@ static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, Vulkan
|
||||
vk11Features,
|
||||
vk12Features,
|
||||
vk13Features,
|
||||
renderer->desiredApiVersion,
|
||||
features->desiredApiVersion,
|
||||
nextStructure);
|
||||
nextStructure = nextStructure->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderer->additionalDeviceExtensionCount = options->device_extension_count;
|
||||
renderer->additionalDeviceExtensionNames = options->device_extension_names;
|
||||
renderer->additionalInstanceExtensionCount = options->instance_extension_count;
|
||||
renderer->additionalInstanceExtensionNames = options->instance_extension_names;
|
||||
features->additionalDeviceExtensionCount = options->device_extension_count;
|
||||
features->additionalDeviceExtensionNames = options->device_extension_names;
|
||||
features->additionalInstanceExtensionCount = options->instance_extension_count;
|
||||
features->additionalInstanceExtensionNames = options->instance_extension_names;
|
||||
} else if (renderer->debugMode) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_GPU,
|
||||
"VULKAN_INTERNAL_AddOptInVulkanOptions: Additional options property was set, but value was null. This may be a bug.");
|
||||
@@ -11693,7 +11700,7 @@ static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeatures *features)
|
||||
{
|
||||
VkResult vulkanResult;
|
||||
VkApplicationInfo appInfo;
|
||||
@@ -11710,8 +11717,8 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
appInfo.applicationVersion = 0;
|
||||
appInfo.pEngineName = "SDLGPU";
|
||||
appInfo.engineVersion = SDL_VERSION;
|
||||
appInfo.apiVersion = renderer->usesCustomVulkanOptions
|
||||
? renderer->desiredApiVersion
|
||||
appInfo.apiVersion = features->usesCustomVulkanOptions
|
||||
? features->desiredApiVersion
|
||||
: VK_MAKE_VERSION(1, 0, 0);
|
||||
|
||||
createFlags = 0;
|
||||
@@ -11726,8 +11733,8 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uint32 extraInstanceExtensionCount = renderer->additionalInstanceExtensionCount;
|
||||
const char** extraInstanceExtensionNames = renderer->additionalInstanceExtensionNames;
|
||||
Uint32 extraInstanceExtensionCount = features->additionalInstanceExtensionCount;
|
||||
const char** extraInstanceExtensionNames = features->additionalInstanceExtensionNames;
|
||||
|
||||
/* Extra space for the following extensions:
|
||||
* VK_KHR_get_physical_device_properties2
|
||||
@@ -11940,6 +11947,7 @@ static bool VULKAN_INTERNAL_GetDeviceRank(
|
||||
|
||||
static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
|
||||
VulkanRenderer *renderer,
|
||||
VulkanFeatures *features,
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VulkanExtensions *physicalDeviceExtensions,
|
||||
Uint32 *queueFamilyIndex)
|
||||
@@ -11954,19 +11962,19 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
|
||||
physicalDevice,
|
||||
&deviceFeatures);
|
||||
|
||||
if ((!deviceFeatures.independentBlend && renderer->desiredVulkan10DeviceFeatures.independentBlend) ||
|
||||
(!deviceFeatures.imageCubeArray && renderer->desiredVulkan10DeviceFeatures.imageCubeArray) ||
|
||||
(!deviceFeatures.depthClamp && renderer->desiredVulkan10DeviceFeatures.depthClamp) ||
|
||||
(!deviceFeatures.shaderClipDistance && renderer->desiredVulkan10DeviceFeatures.shaderClipDistance) ||
|
||||
(!deviceFeatures.drawIndirectFirstInstance && renderer->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance) ||
|
||||
(!deviceFeatures.sampleRateShading && renderer->desiredVulkan10DeviceFeatures.sampleRateShading) ||
|
||||
(!deviceFeatures.samplerAnisotropy && renderer->desiredVulkan10DeviceFeatures.samplerAnisotropy)) {
|
||||
if ((!deviceFeatures.independentBlend && features->desiredVulkan10DeviceFeatures.independentBlend) ||
|
||||
(!deviceFeatures.imageCubeArray && features->desiredVulkan10DeviceFeatures.imageCubeArray) ||
|
||||
(!deviceFeatures.depthClamp && features->desiredVulkan10DeviceFeatures.depthClamp) ||
|
||||
(!deviceFeatures.shaderClipDistance && features->desiredVulkan10DeviceFeatures.shaderClipDistance) ||
|
||||
(!deviceFeatures.drawIndirectFirstInstance && features->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance) ||
|
||||
(!deviceFeatures.sampleRateShading && features->desiredVulkan10DeviceFeatures.sampleRateShading) ||
|
||||
(!deviceFeatures.samplerAnisotropy && features->desiredVulkan10DeviceFeatures.samplerAnisotropy)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check opt-in device features
|
||||
if (renderer->usesCustomVulkanOptions) {
|
||||
bool supportsAllFeatures = VULKAN_INTERNAL_ValidateOptInFeatures(renderer, physicalDevice, &deviceFeatures);
|
||||
if (features->usesCustomVulkanOptions) {
|
||||
bool supportsAllFeatures = VULKAN_INTERNAL_ValidateOptInFeatures(renderer, features, physicalDevice, &deviceFeatures);
|
||||
if (!supportsAllFeatures) {
|
||||
return 0;
|
||||
}
|
||||
@@ -11974,6 +11982,7 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
|
||||
|
||||
if (!VULKAN_INTERNAL_CheckDeviceExtensions(
|
||||
renderer,
|
||||
features,
|
||||
physicalDevice,
|
||||
physicalDeviceExtensions)) {
|
||||
return 0;
|
||||
@@ -12057,7 +12066,7 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer)
|
||||
static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer, VulkanFeatures *features)
|
||||
{
|
||||
VkResult vulkanResult;
|
||||
VkPhysicalDevice *physicalDevices;
|
||||
@@ -12116,6 +12125,7 @@ static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer)
|
||||
|
||||
if (!VULKAN_INTERNAL_IsDeviceSuitable(
|
||||
renderer,
|
||||
features,
|
||||
physicalDevices[i],
|
||||
&physicalDeviceExtensions[i],
|
||||
&queueFamilyIndex)) {
|
||||
@@ -12180,7 +12190,8 @@ static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer)
|
||||
}
|
||||
|
||||
static Uint8 VULKAN_INTERNAL_CreateLogicalDevice(
|
||||
VulkanRenderer *renderer)
|
||||
VulkanRenderer *renderer,
|
||||
VulkanFeatures *features)
|
||||
{
|
||||
VkResult vulkanResult;
|
||||
VkDeviceCreateInfo deviceCreateInfo;
|
||||
@@ -12208,12 +12219,12 @@ static Uint8 VULKAN_INTERNAL_CreateLogicalDevice(
|
||||
// specifying used device features
|
||||
|
||||
if (haveDeviceFeatures.fillModeNonSolid) {
|
||||
renderer->desiredVulkan10DeviceFeatures.fillModeNonSolid = VK_TRUE;
|
||||
features->desiredVulkan10DeviceFeatures.fillModeNonSolid = VK_TRUE;
|
||||
renderer->supportsFillModeNonSolid = true;
|
||||
}
|
||||
|
||||
if (haveDeviceFeatures.multiDrawIndirect) {
|
||||
renderer->desiredVulkan10DeviceFeatures.multiDrawIndirect = VK_TRUE;
|
||||
features->desiredVulkan10DeviceFeatures.multiDrawIndirect = VK_TRUE;
|
||||
renderer->supportsMultiDrawIndirect = true;
|
||||
}
|
||||
|
||||
@@ -12256,17 +12267,17 @@ static Uint8 VULKAN_INTERNAL_CreateLogicalDevice(
|
||||
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions;
|
||||
|
||||
VkPhysicalDeviceFeatures2 featureList;
|
||||
if (renderer->usesCustomVulkanOptions) {
|
||||
if (features->usesCustomVulkanOptions) {
|
||||
featureList.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
featureList.features = renderer->desiredVulkan10DeviceFeatures;
|
||||
featureList.pNext = &renderer->desiredVulkan11DeviceFeatures;
|
||||
renderer->desiredVulkan11DeviceFeatures.pNext = &renderer->desiredVulkan12DeviceFeatures;
|
||||
renderer->desiredVulkan12DeviceFeatures.pNext = &renderer->desiredVulkan13DeviceFeatures;
|
||||
renderer->desiredVulkan13DeviceFeatures.pNext = (void *)deviceCreateInfo.pNext;
|
||||
featureList.features = features->desiredVulkan10DeviceFeatures;
|
||||
featureList.pNext = &features->desiredVulkan11DeviceFeatures;
|
||||
features->desiredVulkan11DeviceFeatures.pNext = &features->desiredVulkan12DeviceFeatures;
|
||||
features->desiredVulkan12DeviceFeatures.pNext = &features->desiredVulkan13DeviceFeatures;
|
||||
features->desiredVulkan13DeviceFeatures.pNext = (void *)deviceCreateInfo.pNext;
|
||||
deviceCreateInfo.pEnabledFeatures = NULL;
|
||||
deviceCreateInfo.pNext = &featureList;
|
||||
} else {
|
||||
deviceCreateInfo.pEnabledFeatures = &renderer->desiredVulkan10DeviceFeatures;
|
||||
deviceCreateInfo.pEnabledFeatures = &features->desiredVulkan10DeviceFeatures;
|
||||
}
|
||||
|
||||
vulkanResult = renderer->vkCreateDevice(
|
||||
@@ -12333,27 +12344,30 @@ static void VULKAN_INTERNAL_LoadEntryPoints(void)
|
||||
|
||||
static bool VULKAN_INTERNAL_PrepareVulkan(
|
||||
VulkanRenderer *renderer,
|
||||
VulkanFeatures *features,
|
||||
SDL_PropertiesID props)
|
||||
{
|
||||
VULKAN_INTERNAL_LoadEntryPoints();
|
||||
|
||||
SDL_zerop(features);
|
||||
|
||||
// Opt out device features (higher compatibility in exchange for reduced functionality)
|
||||
renderer->desiredVulkan10DeviceFeatures.samplerAnisotropy = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
renderer->desiredVulkan10DeviceFeatures.depthClamp = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
renderer->desiredVulkan10DeviceFeatures.shaderClipDistance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
renderer->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
features->desiredVulkan10DeviceFeatures.samplerAnisotropy = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
features->desiredVulkan10DeviceFeatures.depthClamp = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
features->desiredVulkan10DeviceFeatures.shaderClipDistance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
features->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
|
||||
|
||||
// These features have near universal support so they are always enabled
|
||||
renderer->desiredVulkan10DeviceFeatures.independentBlend = VK_TRUE;
|
||||
renderer->desiredVulkan10DeviceFeatures.sampleRateShading = VK_TRUE;
|
||||
renderer->desiredVulkan10DeviceFeatures.imageCubeArray = VK_TRUE;
|
||||
features->desiredVulkan10DeviceFeatures.independentBlend = VK_TRUE;
|
||||
features->desiredVulkan10DeviceFeatures.sampleRateShading = VK_TRUE;
|
||||
features->desiredVulkan10DeviceFeatures.imageCubeArray = VK_TRUE;
|
||||
|
||||
// Handle opt-in device features
|
||||
VULKAN_INTERNAL_AddOptInVulkanOptions(props, renderer);
|
||||
VULKAN_INTERNAL_AddOptInVulkanOptions(props, renderer, features);
|
||||
|
||||
renderer->requireHardwareAcceleration = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_VULKAN_REQUIRE_HARDWARE_ACCELERATION_BOOLEAN, false);
|
||||
|
||||
if (!VULKAN_INTERNAL_CreateInstance(renderer)) {
|
||||
if (!VULKAN_INTERNAL_CreateInstance(renderer, features)) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Vulkan: Could not create Vulkan instance");
|
||||
return false;
|
||||
}
|
||||
@@ -12362,7 +12376,7 @@ static bool VULKAN_INTERNAL_PrepareVulkan(
|
||||
renderer->func = (PFN_##func)vkGetInstanceProcAddr(renderer->instance, #func);
|
||||
#include "SDL_gpu_vulkan_vkfuncs.h"
|
||||
|
||||
if (!VULKAN_INTERNAL_DeterminePhysicalDevice(renderer)) {
|
||||
if (!VULKAN_INTERNAL_DeterminePhysicalDevice(renderer, features)) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Vulkan: Failed to determine a suitable physical device");
|
||||
return false;
|
||||
}
|
||||
@@ -12373,6 +12387,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props)
|
||||
{
|
||||
// Set up dummy VulkanRenderer
|
||||
VulkanRenderer *renderer;
|
||||
VulkanFeatures features;
|
||||
bool result = false;
|
||||
|
||||
if (!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, false)) {
|
||||
@@ -12394,7 +12409,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props)
|
||||
|
||||
renderer->preferLowPower = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, false);
|
||||
|
||||
result = VULKAN_INTERNAL_PrepareVulkan(renderer, props);
|
||||
result = VULKAN_INTERNAL_PrepareVulkan(renderer, &features, props);
|
||||
if (result) {
|
||||
renderer->vkDestroyInstance(renderer->instance, NULL);
|
||||
}
|
||||
@@ -12409,6 +12424,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props)
|
||||
static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, SDL_PropertiesID props)
|
||||
{
|
||||
VulkanRenderer *renderer;
|
||||
VulkanFeatures features;
|
||||
|
||||
SDL_GPUDevice *result;
|
||||
Uint32 i;
|
||||
@@ -12433,19 +12449,13 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||
renderer->preferLowPower = preferLowPower;
|
||||
renderer->allowedFramesInFlight = 2;
|
||||
|
||||
if (!VULKAN_INTERNAL_PrepareVulkan(renderer, props)) {
|
||||
if (!VULKAN_INTERNAL_PrepareVulkan(renderer, &features, props)) {
|
||||
SET_STRING_ERROR("Failed to initialize Vulkan!");
|
||||
SDL_free(renderer);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Make sure we don't hold onto potentially unsafe pointers after initialization
|
||||
renderer->additionalDeviceExtensionCount = 0;
|
||||
renderer->additionalInstanceExtensionCount = 0;
|
||||
renderer->additionalDeviceExtensionNames = NULL;
|
||||
renderer->additionalInstanceExtensionNames = NULL;
|
||||
|
||||
renderer->props = SDL_CreateProperties();
|
||||
if (verboseLogs) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan");
|
||||
@@ -12546,8 +12556,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||
}
|
||||
}
|
||||
|
||||
if (!VULKAN_INTERNAL_CreateLogicalDevice(
|
||||
renderer)) {
|
||||
if (!VULKAN_INTERNAL_CreateLogicalDevice(renderer, &features)) {
|
||||
SET_STRING_ERROR("Failed to create logical device!");
|
||||
SDL_free(renderer);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
|
||||
Reference in New Issue
Block a user