summaryrefslogtreecommitdiffstats
path: root/drivers/vulkan/vulkan_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vulkan/vulkan_context.cpp')
-rw-r--r--drivers/vulkan/vulkan_context.cpp177
1 files changed, 113 insertions, 64 deletions
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 44455b927b..e4aab8d868 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -273,9 +273,9 @@ Error VulkanContext::_obtain_vulkan_version() {
uint32_t api_version;
VkResult res = func(&api_version);
if (res == VK_SUCCESS) {
- vulkan_major = VK_VERSION_MAJOR(api_version);
- vulkan_minor = VK_VERSION_MINOR(api_version);
- vulkan_patch = VK_VERSION_PATCH(api_version);
+ vulkan_major = VK_API_VERSION_MAJOR(api_version);
+ vulkan_minor = VK_API_VERSION_MINOR(api_version);
+ vulkan_patch = VK_API_VERSION_PATCH(api_version);
} else {
// according to the documentation this shouldn't fail with anything except a memory allocation error
// in which case we're in deep trouble anyway
@@ -514,45 +514,62 @@ Error VulkanContext::_check_capabilities() {
subgroup_capabilities.supportedStages = 0;
subgroup_capabilities.supportedOperations = 0;
subgroup_capabilities.quadOperationsInAllStages = false;
+ shader_capabilities.shader_float16_is_supported = false;
+ shader_capabilities.shader_int8_is_supported = false;
+ storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = false;
+ storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported = false;
+ storage_buffer_capabilities.storage_push_constant_16_is_supported = false;
+ storage_buffer_capabilities.storage_input_output_16 = false;
// check for extended features
- PFN_vkGetPhysicalDeviceFeatures2 device_features_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
- if (device_features_func == nullptr) {
+ PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
+ if (vkGetPhysicalDeviceFeatures2_func == nullptr) {
// In Vulkan 1.0 might be accessible under its original extension name
- device_features_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
+ vkGetPhysicalDeviceFeatures2_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
}
- if (device_features_func != nullptr) {
+ if (vkGetPhysicalDeviceFeatures2_func != nullptr) {
// check our extended features
- VkPhysicalDeviceMultiviewFeatures multiview_features;
- multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
- multiview_features.pNext = nullptr;
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+ /*pNext*/ nullptr,
+ /*shaderFloat16*/ false,
+ /*shaderInt8*/ false,
+ };
+
+ VkPhysicalDevice16BitStorageFeaturesKHR storage_feature = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
+ /*pNext*/ &shader_features,
+ /*storageBuffer16BitAccess*/ false,
+ /*uniformAndStorageBuffer16BitAccess*/ false,
+ /*storagePushConstant16*/ false,
+ /*storageInputOutput16*/ false,
+ };
+
+ VkPhysicalDeviceMultiviewFeatures multiview_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
+ /*pNext*/ &storage_feature,
+ /*multiview*/ false,
+ /*multiviewGeometryShader*/ false,
+ /*multiviewTessellationShader*/ false,
+ };
VkPhysicalDeviceFeatures2 device_features;
device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
device_features.pNext = &multiview_features;
- device_features_func(gpu, &device_features);
+ vkGetPhysicalDeviceFeatures2_func(gpu, &device_features);
+
multiview_capabilities.is_supported = multiview_features.multiview;
multiview_capabilities.geometry_shader_is_supported = multiview_features.multiviewGeometryShader;
multiview_capabilities.tessellation_shader_is_supported = multiview_features.multiviewTessellationShader;
- VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features;
- shader_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
- shader_features.pNext = nullptr;
-
- device_features.pNext = &shader_features;
-
- device_features_func(gpu, &device_features);
shader_capabilities.shader_float16_is_supported = shader_features.shaderFloat16;
+ shader_capabilities.shader_int8_is_supported = shader_features.shaderInt8;
- VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
- storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
- storage_feature.pNext = nullptr;
-
- device_features.pNext = &storage_feature;
-
- device_features_func(gpu, &device_features);
storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = storage_feature.storageBuffer16BitAccess;
+ storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported = storage_feature.uniformAndStorageBuffer16BitAccess;
+ storage_buffer_capabilities.storage_push_constant_16_is_supported = storage_feature.storagePushConstant16;
+ storage_buffer_capabilities.storage_input_output_16 = storage_feature.storageInputOutput16;
}
// check extended properties
@@ -860,7 +877,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
free(device_queue_props);
print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
- if (present_supported) { // Select first supported device of preffered type: Discrete > Integrated > Virtual > CPU > Other.
+ if (present_supported) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other.
switch (props.deviceType) {
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
if (type_selected < 4) {
@@ -1057,9 +1074,61 @@ Error VulkanContext::_create_device() {
queues[0].pQueuePriorities = queue_priorities;
queues[0].flags = 0;
+ // Before we retrieved what is supported, here we tell Vulkan we want to enable these features using the same structs.
+ void *nextptr = nullptr;
+
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+ /*pNext*/ nextptr,
+ /*shaderFloat16*/ shader_capabilities.shader_float16_is_supported,
+ /*shaderInt8*/ shader_capabilities.shader_int8_is_supported,
+ };
+ nextptr = &shader_features;
+
+ VkPhysicalDeviceVulkan11Features vulkan11features;
+ VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
+ VkPhysicalDeviceMultiviewFeatures multiview_features;
+ if (vulkan_major > 1 || vulkan_minor >= 2) {
+ // In Vulkan 1.2 and newer we use a newer struct to enable various features
+
+ vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
+ vulkan11features.pNext = nextptr;
+ vulkan11features.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
+ vulkan11features.uniformAndStorageBuffer16BitAccess = storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported;
+ vulkan11features.storagePushConstant16 = storage_buffer_capabilities.storage_push_constant_16_is_supported;
+ vulkan11features.storageInputOutput16 = storage_buffer_capabilities.storage_input_output_16;
+ vulkan11features.multiview = multiview_capabilities.is_supported;
+ vulkan11features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
+ vulkan11features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
+ vulkan11features.variablePointersStorageBuffer = 0;
+ vulkan11features.variablePointers = 0;
+ vulkan11features.protectedMemory = 0;
+ vulkan11features.samplerYcbcrConversion = 0;
+ vulkan11features.shaderDrawParameters = 0;
+ nextptr = &vulkan11features;
+ } else {
+ // On Vulkan 1.0 and 1.1 we use our older structs to initialise these features
+ storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
+ storage_feature.pNext = nextptr;
+ storage_feature.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
+ storage_feature.uniformAndStorageBuffer16BitAccess = storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported;
+ storage_feature.storagePushConstant16 = storage_buffer_capabilities.storage_push_constant_16_is_supported;
+ storage_feature.storageInputOutput16 = storage_buffer_capabilities.storage_input_output_16;
+ nextptr = &storage_feature;
+
+ if (vulkan_major == 1 && vulkan_minor == 1) {
+ multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
+ multiview_features.pNext = nextptr;
+ multiview_features.multiview = multiview_capabilities.is_supported;
+ multiview_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
+ multiview_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
+ nextptr = &multiview_features;
+ }
+ }
+
VkDeviceCreateInfo sdevice = {
/*sType*/ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- /*pNext*/ nullptr,
+ /*pNext*/ nextptr,
/*flags*/ 0,
/*queueCreateInfoCount*/ 1,
/*pQueueCreateInfos*/ queues,
@@ -1068,7 +1137,6 @@ Error VulkanContext::_create_device() {
/*enabledExtensionCount*/ enabled_extension_count,
/*ppEnabledExtensionNames*/ (const char *const *)extension_names,
/*pEnabledFeatures*/ &physical_device_features, // If specific features are required, pass them in here
-
};
if (separate_present_queue) {
queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -1080,36 +1148,6 @@ Error VulkanContext::_create_device() {
sdevice.queueCreateInfoCount = 2;
}
- VkPhysicalDeviceVulkan11Features vulkan11features;
- VkPhysicalDeviceMultiviewFeatures multiview_features;
- if (vulkan_major > 1 || vulkan_minor >= 2) {
- vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
- vulkan11features.pNext = nullptr;
- // !BAS! Need to figure out which ones of these we want enabled...
- vulkan11features.storageBuffer16BitAccess = 0;
- vulkan11features.uniformAndStorageBuffer16BitAccess = 0;
- vulkan11features.storagePushConstant16 = 0;
- vulkan11features.storageInputOutput16 = 0;
- vulkan11features.multiview = multiview_capabilities.is_supported;
- vulkan11features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
- vulkan11features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
- vulkan11features.variablePointersStorageBuffer = 0;
- vulkan11features.variablePointers = 0;
- vulkan11features.protectedMemory = 0;
- vulkan11features.samplerYcbcrConversion = 0;
- vulkan11features.shaderDrawParameters = 0;
-
- sdevice.pNext = &vulkan11features;
- } else if (vulkan_major == 1 && vulkan_minor == 1) {
- multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
- multiview_features.pNext = nullptr;
- multiview_features.multiview = multiview_capabilities.is_supported;
- multiview_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
- multiview_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
-
- sdevice.pNext = &multiview_features;
- }
-
err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -1348,6 +1386,12 @@ int VulkanContext::window_get_height(DisplayServer::WindowID p_window) {
return windows[p_window].height;
}
+bool VulkanContext::window_is_valid_swapchain(DisplayServer::WindowID p_window) {
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
+ Window *w = &windows[p_window];
+ return w->swapchain_image_resources != VK_NULL_HANDLE;
+}
+
VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
Window *w = &windows[p_window];
@@ -1360,7 +1404,11 @@ VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_wi
ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE);
Window *w = &windows[p_window];
//vulkan use of currentbuffer
- return w->swapchain_image_resources[w->current_buffer].framebuffer;
+ if (w->swapchain_image_resources != VK_NULL_HANDLE) {
+ return w->swapchain_image_resources[w->current_buffer].framebuffer;
+ } else {
+ return VK_NULL_HANDLE;
+ }
}
void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) {
@@ -1930,24 +1978,25 @@ Error VulkanContext::swap_buffers() {
}
VkSemaphore *semaphores_to_acquire = (VkSemaphore *)alloca(windows.size() * sizeof(VkSemaphore));
+ VkPipelineStageFlags *pipe_stage_flags = (VkPipelineStageFlags *)alloca(windows.size() * sizeof(VkPipelineStageFlags));
uint32_t semaphores_to_acquire_count = 0;
for (KeyValue<int, Window> &E : windows) {
Window *w = &E.value;
if (w->semaphore_acquired) {
- semaphores_to_acquire[semaphores_to_acquire_count++] = w->image_acquired_semaphores[frame_index];
+ semaphores_to_acquire[semaphores_to_acquire_count] = w->image_acquired_semaphores[frame_index];
+ pipe_stage_flags[semaphores_to_acquire_count] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ semaphores_to_acquire_count++;
}
}
- VkPipelineStageFlags pipe_stage_flags;
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.pNext = nullptr;
- submit_info.pWaitDstStageMask = &pipe_stage_flags;
- pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.waitSemaphoreCount = semaphores_to_acquire_count;
submit_info.pWaitSemaphores = semaphores_to_acquire;
+ submit_info.pWaitDstStageMask = pipe_stage_flags;
submit_info.commandBufferCount = commands_to_submit;
submit_info.pCommandBuffers = commands_ptr;
submit_info.signalSemaphoreCount = 1;
@@ -1963,7 +2012,7 @@ Error VulkanContext::swap_buffers() {
// present queue before presenting, waiting for the draw complete
// semaphore and signalling the ownership released semaphore when finished
VkFence nullFence = VK_NULL_HANDLE;
- pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ pipe_stage_flags[0] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &draw_complete_semaphores[frame_index];
submit_info.commandBufferCount = 0;