Improve Vulkan error messages to be more user-friendly
- Mention that error codes are VkResult error codes (as opposed to Godot error codes). - Mention passed values in more cases to help troubleshooting. - Mention common causes of "Vulkan device lost" in crash message. - Use consistent style across all errors.
This commit is contained in:
@@ -475,7 +475,7 @@ Error RenderingContextDriverVulkan::_initialize_instance_extensions() {
|
||||
|
||||
#ifdef DEV_ENABLED
|
||||
for (uint32_t i = 0; i < instance_extension_count; i++) {
|
||||
print_verbose(String("VULKAN: Found instance extension ") + String::utf8(instance_extensions[i].extensionName) + String("."));
|
||||
print_verbose(String("Vulkan: Found instance extension ") + String::utf8(instance_extensions[i].extensionName) + String("."));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -491,9 +491,9 @@ Error RenderingContextDriverVulkan::_initialize_instance_extensions() {
|
||||
for (KeyValue<CharString, bool> &requested_extension : requested_instance_extensions) {
|
||||
if (!enabled_instance_extension_names.has(requested_extension.key)) {
|
||||
if (requested_extension.value) {
|
||||
ERR_FAIL_V_MSG(ERR_BUG, String("Required extension ") + String::utf8(requested_extension.key) + String(" not found."));
|
||||
ERR_FAIL_V_MSG(ERR_BUG, String("Required Vulkan instance extension ") + String::utf8(requested_extension.key) + String(" not found."));
|
||||
} else {
|
||||
print_verbose(String("Optional extension ") + String::utf8(requested_extension.key) + String(" not found."));
|
||||
print_verbose(String("Optional Vulkan instance extension ") + String::utf8(requested_extension.key) + String(" not found."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,13 +617,13 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
|
||||
|
||||
uint32_t device_extension_count = 0;
|
||||
VkResult err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, nullptr);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(device_extension_count == 0, ERR_CANT_CREATE, "vkEnumerateDeviceExtensionProperties failed to find any extensions\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?");
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan device extension count (VkResult error %d).", err));
|
||||
ERR_FAIL_COND_V_MSG(device_extension_count == 0, ERR_CANT_CREATE, "Couldn't find any Vulkan device extensions. Do you have a compatible Vulkan installable client driver (ICD) installed?");
|
||||
|
||||
TightLocalVector<VkExtensionProperties> device_extensions;
|
||||
device_extensions.resize(device_extension_count);
|
||||
err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, device_extensions.ptr());
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan device extension properties (VkResult error %d).", err));
|
||||
|
||||
#if defined(SWAPPY_FRAME_PACING_ENABLED)
|
||||
if (swappy_frame_pacer_enable) {
|
||||
@@ -658,7 +658,7 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
|
||||
|
||||
#ifdef DEV_ENABLED
|
||||
for (uint32_t i = 0; i < device_extension_count; i++) {
|
||||
print_verbose(String("VULKAN: Found device extension ") + String::utf8(device_extensions[i].extensionName));
|
||||
print_verbose(String("Vulkan: Found device extension ") + String::utf8(device_extensions[i].extensionName));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -674,9 +674,9 @@ Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
|
||||
for (KeyValue<CharString, bool> &requested_extension : requested_device_extensions) {
|
||||
if (!enabled_device_extension_names.has(requested_extension.key)) {
|
||||
if (requested_extension.value) {
|
||||
ERR_FAIL_V_MSG(ERR_BUG, String("Required extension ") + String::utf8(requested_extension.key) + String(" not found."));
|
||||
ERR_FAIL_V_MSG(ERR_BUG, String("Required Vulkan device extension ") + String::utf8(requested_extension.key) + String(" not found."));
|
||||
} else {
|
||||
print_verbose(String("Optional extension ") + String::utf8(requested_extension.key) + String(" not found"));
|
||||
print_verbose(String("Optional Vulkan device extension ") + String::utf8(requested_extension.key) + String(" not found"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1410,10 +1410,10 @@ Error RenderingDeviceDriverVulkan::_initialize_device(const LocalVector<VkDevice
|
||||
|
||||
if (VulkanHooks::get_singleton() != nullptr) {
|
||||
bool device_created = VulkanHooks::get_singleton()->create_vulkan_device(&create_info, &vk_device);
|
||||
ERR_FAIL_COND_V(!device_created, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(!device_created, ERR_CANT_CREATE, "Couldn't create a Vulkan device through the VulkanHooks singleton.");
|
||||
} else {
|
||||
VkResult err = vkCreateDevice(physical_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DEVICE), &vk_device);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't create Vulkan device (VkResult error %d).", err));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < queue_families.size(); i++) {
|
||||
@@ -1474,7 +1474,7 @@ Error RenderingDeviceDriverVulkan::_initialize_allocator() {
|
||||
allocator_info.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
|
||||
}
|
||||
VkResult err = vmaCreateAllocator(&allocator_info, &allocator);
|
||||
ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "vmaCreateAllocator failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, vformat("Couldn't create Vulkan memory allocator (VkResult error %d).", err));
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -1619,7 +1619,7 @@ bool RenderingDeviceDriverVulkan::_recreate_image_semaphore(CommandQueue *p_comm
|
||||
VkSemaphoreCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VkResult err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, false);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, false, vformat("Couldn't create Vulkan semaphore (VkResult error %d).", err));
|
||||
|
||||
// Indicate the semaphore is free again and destroy the previous one before storing the new one.
|
||||
vkDestroySemaphore(vk_device, p_command_queue->image_semaphores[p_semaphore_index], VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
|
||||
@@ -1771,26 +1771,26 @@ Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t
|
||||
}
|
||||
|
||||
Error err = _initialize_device_extensions();
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan device extensions. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
err = _check_device_features();
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan device features. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
err = _check_device_capabilities();
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan device capabilities. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
LocalVector<VkDeviceQueueCreateInfo> queue_create_info;
|
||||
err = _add_queue_create_info(queue_create_info);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan device queue. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
err = _initialize_device(queue_create_info);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan device. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
err = _initialize_allocator();
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan memory allocator. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
err = _initialize_pipeline_cache();
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't initialize Vulkan pipeline cache. This may be caused by an incompatible or outdated graphics driver.");
|
||||
|
||||
max_descriptor_sets_per_pool = GLOBAL_GET("rendering/rendering_device/vulkan/max_descriptors_per_pool");
|
||||
|
||||
@@ -1814,7 +1814,7 @@ Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t
|
||||
|
||||
#if RECORD_PIPELINE_STATISTICS
|
||||
pipeline_statistics.file_access = FileAccess::open(RECORD_PIPELINE_STATISTICS_PATH, FileAccess::WRITE);
|
||||
ERR_FAIL_NULL_V_MSG(pipeline_statistics.file_access, ERR_CANT_CREATE, "Unable to write pipeline statistics file.");
|
||||
ERR_FAIL_NULL_V_MSG(pipeline_statistics.file_access, ERR_CANT_CREATE, "Couldn't write Vulkan pipeline statistics file.");
|
||||
|
||||
pipeline_statistics.file_access->store_csv_line({ "name", "hash", "stage", "spec", "glslang", "re-spirv", "time" });
|
||||
pipeline_statistics.file_access->flush();
|
||||
@@ -1848,7 +1848,7 @@ VmaPool RenderingDeviceDriverVulkan::_find_or_create_small_allocs_pool(uint32_t
|
||||
VmaPool pool = VK_NULL_HANDLE;
|
||||
VkResult res = vmaCreatePool(allocator, &pci, &pool);
|
||||
small_allocs_pools[p_mem_type_index] = pool; // Don't try to create it again if failed the first time.
|
||||
ERR_FAIL_COND_V_MSG(res, pool, "vmaCreatePool failed with error " + itos(res) + ".");
|
||||
ERR_FAIL_COND_V_MSG(res, pool, vformat("Couldn't create Vulkan memory allocator pool (VkResult error %d)", res));
|
||||
|
||||
return pool;
|
||||
}
|
||||
@@ -1944,14 +1944,14 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie
|
||||
alloc_create_info.preferredFlags &= ~vma_flags_to_remove;
|
||||
alloc_create_info.usage = vma_usage;
|
||||
VkResult err = vmaCreateBuffer(allocator, &create_info, &alloc_create_info, &vk_buffer, &allocation, &alloc_info);
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), vformat("Can't create buffer of size: %d (VkResult error %d).", p_size, err));
|
||||
} else {
|
||||
VkResult err = vkCreateBuffer(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER), &vk_buffer);
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), vformat("Can't create buffer of size: %d (VkResult error %d).", p_size, err));
|
||||
err = vmaAllocateMemoryForBuffer(allocator, vk_buffer, &alloc_create_info, &allocation, &alloc_info);
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't allocate memory for buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), vformat("Can't allocate memory for buffer of size: %d (VkResult error %d).", p_size, err));
|
||||
err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, nullptr);
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't bind memory to buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), vformat("Can't bind memory to buffer of size: %d (VkResult error %d).", p_size, err));
|
||||
}
|
||||
|
||||
// Bookkeep.
|
||||
@@ -1959,7 +1959,7 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie
|
||||
if (p_usage.has_flag(BUFFER_USAGE_DYNAMIC_PERSISTENT_BIT)) {
|
||||
void *persistent_ptr = nullptr;
|
||||
VkResult err = vmaMapMemory(allocator, allocation, &persistent_ptr);
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), "vmaMapMemory failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, BufferID(), vformat("Couldn't map Vulkan buffer memory (VkResult error %d).", err));
|
||||
|
||||
BufferDynamicInfo *dyn_buffer = VersatileResource::allocate<BufferDynamicInfo>(resources_allocator);
|
||||
buf_info = dyn_buffer;
|
||||
@@ -1991,7 +1991,7 @@ bool RenderingDeviceDriverVulkan::buffer_set_texel_format(BufferID p_buffer, Dat
|
||||
view_create_info.range = buf_info->allocation.size;
|
||||
|
||||
VkResult res = vkCreateBufferView(vk_device, &view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER_VIEW), &buf_info->vk_view);
|
||||
ERR_FAIL_COND_V_MSG(res, false, "Unable to create buffer view, error " + itos(res) + ".");
|
||||
ERR_FAIL_COND_V_MSG(res, false, vformat("Couldn't create Vulkan buffer view (VkResult error %d).", res));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2030,7 +2030,7 @@ uint8_t *RenderingDeviceDriverVulkan::buffer_map(BufferID p_buffer) {
|
||||
ERR_FAIL_COND_V_MSG(buf_info->is_dynamic(), nullptr, "Buffer must NOT have BUFFER_USAGE_DYNAMIC_PERSISTENT_BIT. Use buffer_persistent_map_advance() instead.");
|
||||
void *data_ptr = nullptr;
|
||||
VkResult err = vmaMapMemory(allocator, buf_info->allocation.handle, &data_ptr);
|
||||
ERR_FAIL_COND_V_MSG(err, nullptr, "vmaMapMemory failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, nullptr, vformat("Couldn't map buffer memory (VkResult error %d).", err));
|
||||
return (uint8_t *)data_ptr;
|
||||
}
|
||||
|
||||
@@ -2043,7 +2043,7 @@ uint8_t *RenderingDeviceDriverVulkan::buffer_persistent_map_advance(BufferID p_b
|
||||
BufferDynamicInfo *buf_info = (BufferDynamicInfo *)p_buffer.id;
|
||||
ERR_FAIL_COND_V_MSG(!buf_info->is_dynamic(), nullptr, "Buffer must have BUFFER_USAGE_DYNAMIC_PERSISTENT_BIT. Use buffer_map() instead.");
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_FAIL_COND_V_MSG(buf_info->last_frame_mapped == p_frames_drawn, nullptr, "Buffers with BUFFER_USAGE_DYNAMIC_PERSISTENT_BIT must only be mapped once per frame. Otherwise there could be race conditions with the GPU. Amalgamate all data uploading into one map(), use an extra buffer or remove the bit.");
|
||||
ERR_FAIL_COND_V_MSG(buf_info->last_frame_mapped == p_frames_drawn, nullptr, "Buffers with BUFFER_USAGE_DYNAMIC_PERSISTENT_BIT must only be mapped once per frame. Otherwise there could be race conditions with the GPU. Amalgamate all data uploading into one map(), use an extra buffer, or remove the bit.");
|
||||
buf_info->last_frame_mapped = p_frames_drawn;
|
||||
#endif
|
||||
buf_info->frame_idx = (buf_info->frame_idx + 1u) % frame_count;
|
||||
@@ -2296,14 +2296,14 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat &
|
||||
if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
|
||||
alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||
VkResult err = vmaCreateImage(allocator, &create_info, &alloc_create_info, &vk_image, &allocation, &alloc_info);
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "vmaCreateImage failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't create Vulkan image in memory for use with extra GPU memory tracking (VkResult error %d).", err));
|
||||
} else {
|
||||
VkResult err = vkCreateImage(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE), &vk_image);
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImage failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't create Vulkan image (VkResult error %d).", err));
|
||||
err = vmaAllocateMemoryForImage(allocator, vk_image, &alloc_create_info, &allocation, &alloc_info);
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't allocate memory for image, error: " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't allocate memory for Vulkan image (VkResult error %d).", err));
|
||||
err = vmaBindImageMemory2(allocator, allocation, 0, vk_image, nullptr);
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't bind memory to image, error: " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't bind memory to Vulkan image (VkResult error %d).", err));
|
||||
}
|
||||
|
||||
// Create view.
|
||||
@@ -2345,7 +2345,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat &
|
||||
vmaFreeMemory(allocator, allocation);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't create Vulkan image view (VkResult error %d).", err));
|
||||
}
|
||||
|
||||
// Bookkeep.
|
||||
@@ -2392,7 +2392,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_from_extension(uint64
|
||||
VkImageView vk_image_view = VK_NULL_HANDLE;
|
||||
VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &vk_image_view);
|
||||
if (err) {
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't create Vulkan image view for extension texture (VkResult error %d).", err));
|
||||
}
|
||||
|
||||
// Bookkeep.
|
||||
@@ -2447,7 +2447,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared(TextureID p_or
|
||||
|
||||
VkImageView new_vk_image_view = VK_NULL_HANDLE;
|
||||
VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &new_vk_image_view);
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't create Vulkan image view for shared texture (VkResult error %d).", err));
|
||||
|
||||
// Bookkeep.
|
||||
|
||||
@@ -2500,7 +2500,7 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared_from_slice(Tex
|
||||
|
||||
VkImageView new_vk_image_view = VK_NULL_HANDLE;
|
||||
VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &new_vk_image_view);
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, TextureID(), vformat("Couldn't create Vulkan image view for shared texture from slice (VkResult error %d).", err));
|
||||
|
||||
// Bookkeep.
|
||||
|
||||
@@ -2574,7 +2574,7 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::texture_get_data(TextureID p_textur
|
||||
|
||||
void *data_ptr = nullptr;
|
||||
VkResult err = vmaMapMemory(allocator, tex->allocation.handle, &data_ptr);
|
||||
ERR_FAIL_COND_V_MSG(err, Vector<uint8_t>(), "vmaMapMemory failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, Vector<uint8_t>(), vformat("Couldn't map Vulkan memory for texture (VkResult error %d).", err));
|
||||
|
||||
{
|
||||
uint8_t *w = image_data.ptrw();
|
||||
@@ -2709,7 +2709,7 @@ RDD::SamplerID RenderingDeviceDriverVulkan::sampler_create(const SamplerState &p
|
||||
|
||||
VkSampler vk_sampler = VK_NULL_HANDLE;
|
||||
VkResult res = vkCreateSampler(vk_device, &sampler_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SAMPLER), &vk_sampler);
|
||||
ERR_FAIL_COND_V_MSG(res, SamplerID(), "vkCreateSampler failed with error " + itos(res) + ".");
|
||||
ERR_FAIL_COND_V_MSG(res, SamplerID(), vformat("Couldn't create Vulkan sampler (VkResult error %d).", res));
|
||||
|
||||
return SamplerID(vk_sampler);
|
||||
}
|
||||
@@ -2967,7 +2967,7 @@ RDD::FenceID RenderingDeviceDriverVulkan::fence_create() {
|
||||
VkFenceCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
VkResult err = vkCreateFence(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FENCE), &vk_fence);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FenceID());
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, FenceID(), vformat("Couldn't create Vulkan fence (VkResult error %d).", err));
|
||||
|
||||
Fence *fence = memnew(Fence);
|
||||
fence->vk_fence = vk_fence;
|
||||
@@ -2980,11 +2980,11 @@ Error RenderingDeviceDriverVulkan::fence_wait(FenceID p_fence) {
|
||||
VkResult fence_status = vkGetFenceStatus(vk_device, fence->vk_fence);
|
||||
if (fence_status == VK_NOT_READY) {
|
||||
VkResult err = vkWaitForFences(vk_device, 1, &fence->vk_fence, VK_TRUE, UINT64_MAX);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, FAILED, vformat("Couldn't wait for Vulkan fence (VkResult error %d).", err));
|
||||
}
|
||||
|
||||
VkResult err = vkResetFences(vk_device, 1, &fence->vk_fence);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, FAILED, vformat("Couldn't reset Vulkan fence (VkResult error %d).", err));
|
||||
|
||||
if (fence->queue_signaled_from != nullptr) {
|
||||
// Release all semaphores that the command queue associated to the fence waited on the last time it was submitted.
|
||||
@@ -3021,7 +3021,7 @@ RDD::SemaphoreID RenderingDeviceDriverVulkan::semaphore_create() {
|
||||
VkSemaphoreCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VkResult err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, SemaphoreID());
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, SemaphoreID(), vformat("Couldn't create Vulkan semaphore (VkResult error %d).", err));
|
||||
|
||||
return SemaphoreID(semaphore);
|
||||
}
|
||||
@@ -3087,7 +3087,7 @@ RDD::CommandQueueID RenderingDeviceDriverVulkan::command_queue_create(CommandQue
|
||||
}
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(picked_queue_index >= queue_family.size(), CommandQueueID(), "A queue in the picked family could not be found.");
|
||||
ERR_FAIL_COND_V_MSG(picked_queue_index >= queue_family.size(), CommandQueueID(), "Couldn't find a Vulkan command queue in the picked family.");
|
||||
|
||||
#if defined(SWAPPY_FRAME_PACING_ENABLED)
|
||||
if (swappy_frame_pacer_enable) {
|
||||
@@ -3150,7 +3150,7 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
||||
pending_flushes.allocations.clear();
|
||||
pending_flushes.offsets.clear();
|
||||
pending_flushes.sizes.clear();
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, FAILED, vformat("Couldn't flush Vulkan memory allocations (VkResult error %d).", err));
|
||||
}
|
||||
|
||||
if (p_cmd_buffers.size() > 0) {
|
||||
@@ -3193,9 +3193,9 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
||||
|
||||
if (err == VK_ERROR_DEVICE_LOST) {
|
||||
print_lost_device_info();
|
||||
CRASH_NOW_MSG("Vulkan device was lost.");
|
||||
CRASH_NOW_MSG("Vulkan device was lost. This could be due to a driver issue, a hardware issue, or the driver resetting itself because it was unresponsive for too long (TDR).");
|
||||
}
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, FAILED, vformat("Couldn't submit to Vulkan queue (VkResult error %d).", err));
|
||||
|
||||
if (fence != nullptr && !command_queue->pending_semaphores_for_fence.is_empty()) {
|
||||
fence->queue_signaled_from = command_queue;
|
||||
@@ -3284,7 +3284,7 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
||||
ERR_FAIL_COND_V_MSG(
|
||||
err != VK_SUCCESS && err != VK_SUBOPTIMAL_KHR,
|
||||
FAILED,
|
||||
"QueuePresentKHR failed with error: " + get_vulkan_result(err));
|
||||
"Couldn't present to Vulkan queue (VkResult error " + get_vulkan_result(err) + ").");
|
||||
}
|
||||
|
||||
return OK;
|
||||
@@ -3329,7 +3329,7 @@ RDD::CommandPoolID RenderingDeviceDriverVulkan::command_pool_create(CommandQueue
|
||||
|
||||
VkCommandPool vk_command_pool = VK_NULL_HANDLE;
|
||||
VkResult res = vkCreateCommandPool(vk_device, &cmd_pool_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_COMMAND_POOL), &vk_command_pool);
|
||||
ERR_FAIL_COND_V_MSG(res, CommandPoolID(), "vkCreateCommandPool failed with error " + itos(res) + ".");
|
||||
ERR_FAIL_COND_V_MSG(res, CommandPoolID(), vformat("Couldn't create Vulkan command pool (VkResult error %d).", res));
|
||||
|
||||
CommandPool *command_pool = memnew(CommandPool);
|
||||
command_pool->vk_command_pool = vk_command_pool;
|
||||
@@ -3342,7 +3342,7 @@ bool RenderingDeviceDriverVulkan::command_pool_reset(CommandPoolID p_cmd_pool) {
|
||||
|
||||
CommandPool *command_pool = (CommandPool *)(p_cmd_pool.id);
|
||||
VkResult err = vkResetCommandPool(vk_device, command_pool->vk_command_pool, 0);
|
||||
ERR_FAIL_COND_V_MSG(err, false, "vkResetCommandPool failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, false, vformat("Couldn't reset Vulkan command pool (VkResult error %d).", err));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3378,7 +3378,7 @@ RDD::CommandBufferID RenderingDeviceDriverVulkan::command_buffer_create(CommandP
|
||||
|
||||
VkCommandBuffer vk_command_buffer = VK_NULL_HANDLE;
|
||||
VkResult err = vkAllocateCommandBuffers(vk_device, &cmd_buf_info, &vk_command_buffer);
|
||||
ERR_FAIL_COND_V_MSG(err, CommandBufferID(), "vkAllocateCommandBuffers failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, CommandBufferID(), vformat("Couldn't allocate Vulkan command buffer (VkResult error %d).", err));
|
||||
|
||||
CommandBufferInfo *command_buffer = VersatileResource::allocate<CommandBufferInfo>(resources_allocator);
|
||||
command_buffer->vk_command_buffer = vk_command_buffer;
|
||||
@@ -3394,7 +3394,7 @@ bool RenderingDeviceDriverVulkan::command_buffer_begin(CommandBufferID p_cmd_buf
|
||||
cmd_buf_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
|
||||
VkResult err = vkBeginCommandBuffer(command_buffer->vk_command_buffer, &cmd_buf_begin_info);
|
||||
ERR_FAIL_COND_V_MSG(err, false, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, false, vformat("Couldn't begin Vulkan command buffer (VkResult error %d).", err));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3416,7 +3416,7 @@ bool RenderingDeviceDriverVulkan::command_buffer_begin_secondary(CommandBufferID
|
||||
cmd_buf_begin_info.pInheritanceInfo = &inheritance_info;
|
||||
|
||||
VkResult err = vkBeginCommandBuffer(command_buffer->vk_command_buffer, &cmd_buf_begin_info);
|
||||
ERR_FAIL_COND_V_MSG(err, false, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, false, vformat("Couldn't begin Vulkan command buffer (VkResult error %d).", err));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3457,12 +3457,12 @@ bool RenderingDeviceDriverVulkan::_determine_swap_chain_format(RenderingContextD
|
||||
// Retrieve the formats supported by the surface.
|
||||
uint32_t format_count = 0;
|
||||
VkResult err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, nullptr);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, false);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, false, vformat("Couldn't retrieve Vulkan surface formats (VkResult error %d).", err));
|
||||
|
||||
TightLocalVector<VkSurfaceFormatKHR> formats;
|
||||
formats.resize(format_count);
|
||||
err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, formats.ptr());
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, false);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, false, vformat("Couldn't retrieve Vulkan surface formats (VkResult error %d).", err));
|
||||
|
||||
// If the format list includes just one entry of VK_FORMAT_UNDEFINED, the surface has no preferred format.
|
||||
if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED) {
|
||||
@@ -3602,14 +3602,14 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
|
||||
if (!context_driver->queue_family_supports_present(physical_device, command_queue->queue_family, swap_chain->surface)) {
|
||||
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Surface is not supported by device. Did the GPU go offline? Was the window created on another monitor? Check"
|
||||
"previous errors & try launching with --gpu-validation.");
|
||||
"previous errors and try launching with --gpu-validation.");
|
||||
}
|
||||
|
||||
// Retrieve the surface's capabilities.
|
||||
RenderingContextDriverVulkan::Surface *surface = (RenderingContextDriverVulkan::Surface *)(swap_chain->surface);
|
||||
VkSurfaceCapabilitiesKHR surface_capabilities = {};
|
||||
VkResult err = functions.GetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface->vk_surface, &surface_capabilities);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan surface capabilities (VkResult error %d).", err));
|
||||
|
||||
// No swapchain yet, this is the first time we're creating it.
|
||||
if (!swap_chain->vk_swapchain) {
|
||||
@@ -3653,11 +3653,11 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
TightLocalVector<VkPresentModeKHR> present_modes;
|
||||
uint32_t present_modes_count = 0;
|
||||
err = functions.GetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface->vk_surface, &present_modes_count, nullptr);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan surface present modes (VkResult error %d).", err));
|
||||
|
||||
present_modes.resize(present_modes_count);
|
||||
err = functions.GetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface->vk_surface, &present_modes_count, present_modes.ptr());
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan surface present modes (VkResult error %d).", err));
|
||||
|
||||
// Choose the present mode based on the display server setting.
|
||||
VkPresentModeKHR present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR;
|
||||
@@ -3723,7 +3723,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
RDD::ColorSpace rdd_color_space = COLOR_SPACE_REC709_NONLINEAR_SRGB;
|
||||
if (!_determine_swap_chain_format(swap_chain->surface, format, color_space, rdd_color_space)) {
|
||||
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Surface did not return any valid formats.");
|
||||
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Vulkan surface did not return any valid formats.");
|
||||
} else {
|
||||
swap_chain->format = format;
|
||||
swap_chain->color_space = color_space;
|
||||
@@ -3763,7 +3763,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
swap_create_info.presentMode = present_mode;
|
||||
swap_create_info.clipped = true;
|
||||
err = device_functions.CreateSwapchainKHR(vk_device, &swap_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SWAPCHAIN_KHR), &swap_chain->vk_swapchain);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't create Vulkan swapchain (VkResult error %d).", err));
|
||||
|
||||
#if defined(SWAPPY_FRAME_PACING_ENABLED)
|
||||
if (swappy_frame_pacer_enable) {
|
||||
@@ -3797,11 +3797,11 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
|
||||
uint32_t image_count = 0;
|
||||
err = device_functions.GetSwapchainImagesKHR(vk_device, swap_chain->vk_swapchain, &image_count, nullptr);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan swapchain images (VkResult error %d).", err));
|
||||
|
||||
swap_chain->images.resize(image_count);
|
||||
err = device_functions.GetSwapchainImagesKHR(vk_device, swap_chain->vk_swapchain, &image_count, swap_chain->images.ptr());
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't get Vulkan swapchain images (VkResult error %d).", err));
|
||||
|
||||
VkImageViewCreateInfo view_create_info = {};
|
||||
view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
@@ -3821,7 +3821,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
for (uint32_t i = 0; i < image_count; i++) {
|
||||
view_create_info.image = swap_chain->images[i];
|
||||
err = vkCreateImageView(vk_device, &view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &image_view);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't create Vulkan image view for swapchain image (VkResult error %d).", err));
|
||||
|
||||
swap_chain->image_views.push_back(image_view);
|
||||
}
|
||||
@@ -3859,7 +3859,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
|
||||
VkRenderPass vk_render_pass = VK_NULL_HANDLE;
|
||||
err = _create_render_pass(vk_device, &pass_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS), &vk_render_pass);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't create Vulkan render pass for swapchain (VkResult error %d).", err));
|
||||
|
||||
RenderPassInfo *render_pass_info = VersatileResource::allocate<RenderPassInfo>(resources_allocator);
|
||||
render_pass_info->vk_render_pass = vk_render_pass;
|
||||
@@ -3879,7 +3879,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
for (uint32_t i = 0; i < image_count; i++) {
|
||||
fb_create_info.pAttachments = &swap_chain->image_views[i];
|
||||
err = vkCreateFramebuffer(vk_device, &fb_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &vk_framebuffer);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, ERR_CANT_CREATE, vformat("Couldn't create Vulkan framebuffer for swapchain image (VkResult error %d).", err));
|
||||
|
||||
Framebuffer *framebuffer = memnew(Framebuffer);
|
||||
framebuffer->vk_framebuffer = vk_framebuffer;
|
||||
@@ -3894,7 +3894,7 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
|
||||
err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &vk_semaphore);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, FAILED, vformat("Couldn't create Vulkan semaphore for swapchain image (VkResult error %d).", err));
|
||||
|
||||
swap_chain->present_semaphores.push_back(vk_semaphore);
|
||||
}
|
||||
@@ -3925,7 +3925,7 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::swap_chain_acquire_framebuffer(C
|
||||
VkSemaphoreCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FramebufferID());
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, FramebufferID(), vformat("Couldn't create Vulkan semaphore for acquiring swapchain image (VkResult error %d).", err));
|
||||
|
||||
semaphore_index = command_queue->image_semaphores.size();
|
||||
command_queue->image_semaphores.push_back(semaphore);
|
||||
@@ -3947,7 +3947,7 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::swap_chain_acquire_framebuffer(C
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
// Out of date leaves the semaphore in a signaled state that will never finish, so it's necessary to recreate it.
|
||||
bool semaphore_recreated = _recreate_image_semaphore(command_queue, semaphore_index, true);
|
||||
ERR_FAIL_COND_V(!semaphore_recreated, FramebufferID());
|
||||
ERR_FAIL_COND_V_MSG(!semaphore_recreated, FramebufferID(), "Couldn't recreate Vulkan semaphore after swapchain becoming out of date.");
|
||||
|
||||
// Swap chain is out of date and must be recreated.
|
||||
r_resize_required = true;
|
||||
@@ -4058,7 +4058,7 @@ RDD::FramebufferID RenderingDeviceDriverVulkan::framebuffer_create(RenderPassID
|
||||
|
||||
VkFramebuffer vk_framebuffer = VK_NULL_HANDLE;
|
||||
VkResult err = vkCreateFramebuffer(vk_device, &framebuffer_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &vk_framebuffer);
|
||||
ERR_FAIL_COND_V_MSG(err, FramebufferID(), "vkCreateFramebuffer failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, FramebufferID(), vformat("Couldn't create Vulkan framebuffer (VkResult error %d).", err));
|
||||
|
||||
#if PRINT_NATIVE_COMMANDS
|
||||
print_line(vformat("vkCreateFramebuffer 0x%uX with %d attachments", uint64_t(vk_framebuffer), p_attachments.size()));
|
||||
@@ -4341,7 +4341,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_container(const Re
|
||||
|
||||
res = vkCreatePipelineLayout(vk_device, &pipeline_layout_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_LAYOUT), &shader_info.vk_pipeline_layout);
|
||||
if (res != VK_SUCCESS) {
|
||||
error_text = vformat("Error (%d) creating pipeline layout.", res);
|
||||
error_text = vformat("Couldn't create Vulkan pipeline layout (VkResult error %d).", res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4500,7 +4500,7 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_create(const
|
||||
VkDescriptorPool vk_pool = VK_NULL_HANDLE;
|
||||
VkResult res = vkCreateDescriptorPool(vk_device, &descriptor_set_pool_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL), &vk_pool);
|
||||
if (res) {
|
||||
ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateDescriptorPool failed with error " + itos(res) + ".");
|
||||
ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, vformat("Couldn't create Vulkan descriptor pool (VkResult error %d).", res));
|
||||
}
|
||||
|
||||
return vk_pool;
|
||||
@@ -4790,7 +4790,7 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView<Bou
|
||||
|
||||
// "Fragmented pool" and "out of memory pool" errors are handled by creating more pools. Any other error is unexpected.
|
||||
if (res != VK_ERROR_FRAGMENTED_POOL && res != VK_ERROR_OUT_OF_POOL_MEMORY) {
|
||||
ERR_FAIL_V_MSG(UniformSetID(), "Cannot allocate descriptor sets, error " + itos(res) + ".");
|
||||
ERR_FAIL_V_MSG(UniformSetID(), vformat("Couldn't allocate Vulkan descriptor sets (VkResult error %d).", res));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4803,7 +4803,7 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView<Bou
|
||||
// All errors are unexpected at this stage.
|
||||
if (res) {
|
||||
vkDestroyDescriptorPool(vk_device, descriptor_set_allocate_info.descriptorPool, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL));
|
||||
ERR_FAIL_V_MSG(UniformSetID(), "Cannot allocate descriptor sets, error " + itos(res) + ".");
|
||||
ERR_FAIL_V_MSG(UniformSetID(), vformat("Couldn't allocate Vulkan descriptor sets (VkResult error %d).", res));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5201,7 +5201,7 @@ size_t RenderingDeviceDriverVulkan::pipeline_cache_query_size() {
|
||||
// We're letting the cache grow unboundedly. We may want to set at limit and see if implementations use LRU or the like.
|
||||
// If we do, we won't be able to assume any longer that the cache is dirty if, and only if, it has grown.
|
||||
VkResult err = vkGetPipelineCacheData(vk_device, pipelines_cache.vk_cache, &pipelines_cache.current_size, nullptr);
|
||||
ERR_FAIL_COND_V_MSG(err, 0, "vkGetPipelineCacheData failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, 0, vformat("Couldn't get Vulkan pipeline cache data (VkResult error %d).", err));
|
||||
|
||||
return pipelines_cache.current_size;
|
||||
}
|
||||
@@ -5212,7 +5212,8 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::pipeline_cache_serialize() {
|
||||
pipelines_cache.buffer.resize(pipelines_cache.current_size + sizeof(PipelineCacheHeader));
|
||||
|
||||
VkResult err = vkGetPipelineCacheData(vk_device, pipelines_cache.vk_cache, &pipelines_cache.current_size, pipelines_cache.buffer.ptrw() + sizeof(PipelineCacheHeader));
|
||||
ERR_FAIL_COND_V(err != VK_SUCCESS && err != VK_INCOMPLETE, Vector<uint8_t>()); // Incomplete is OK because the cache may have grown since the size was queried (unless when exiting).
|
||||
// Incomplete is OK because the cache may have grown since the size was queried (unless when exiting).
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS && err != VK_INCOMPLETE, Vector<uint8_t>(), vformat("Couldn't get Vulkan pipeline cache data (VkResult error %d).", err));
|
||||
|
||||
// The real buffer size may now be bigger than the updated current_size.
|
||||
// We take into account the new size but keep the buffer resized in a worst-case fashion.
|
||||
@@ -5403,7 +5404,7 @@ RDD::RenderPassID RenderingDeviceDriverVulkan::render_pass_create(VectorView<Att
|
||||
|
||||
VkRenderPass vk_render_pass = VK_NULL_HANDLE;
|
||||
VkResult res = _create_render_pass(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS), &vk_render_pass);
|
||||
ERR_FAIL_COND_V_MSG(res, RenderPassID(), "vkCreateRenderPass2KHR failed with error " + itos(res) + ".");
|
||||
ERR_FAIL_COND_V_MSG(res, RenderPassID(), vformat("Couldn't create Vulkan render pass (VkResult error %d).", res));
|
||||
|
||||
RenderPassInfo *render_pass = VersatileResource::allocate<RenderPassInfo>(resources_allocator);
|
||||
render_pass->vk_render_pass = vk_render_pass;
|
||||
@@ -5771,7 +5772,12 @@ RDD::PipelineID RenderingDeviceDriverVulkan::render_pipeline_create(
|
||||
// Tessellation.
|
||||
VkPipelineTessellationStateCreateInfo tessellation_create_info = {};
|
||||
tessellation_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
|
||||
ERR_FAIL_COND_V(physical_device_properties.limits.maxTessellationPatchSize > 0 && (p_rasterization_state.patch_control_points < 1 || p_rasterization_state.patch_control_points > physical_device_properties.limits.maxTessellationPatchSize), PipelineID());
|
||||
ERR_FAIL_COND_V_MSG(
|
||||
physical_device_properties.limits.maxTessellationPatchSize > 0 && (p_rasterization_state.patch_control_points < 1 || p_rasterization_state.patch_control_points > physical_device_properties.limits.maxTessellationPatchSize),
|
||||
PipelineID(),
|
||||
vformat("Invalid Vulkan tessellation patch control point count: %d. It must be between 1 and %d.",
|
||||
p_rasterization_state.patch_control_points,
|
||||
physical_device_properties.limits.maxTessellationPatchSize));
|
||||
tessellation_create_info.patchControlPoints = p_rasterization_state.patch_control_points;
|
||||
|
||||
// Viewport.
|
||||
@@ -5958,7 +5964,7 @@ RDD::PipelineID RenderingDeviceDriverVulkan::render_pipeline_create(
|
||||
pipeline_create_info.stageCount = shader_info->vk_stages_create_info.size();
|
||||
|
||||
ERR_FAIL_COND_V_MSG(pipeline_create_info.stageCount == 0, PipelineID(),
|
||||
"Cannot create pipeline without shader module, please make sure shader modules are destroyed only after all associated pipelines are created.");
|
||||
"Can't create Vulkan pipeline without shader module. Make sure shader modules are destroyed only after all associated pipelines are created.");
|
||||
VkPipelineShaderStageCreateInfo *vk_pipeline_stages = ALLOCA_ARRAY(VkPipelineShaderStageCreateInfo, shader_info->vk_stages_create_info.size());
|
||||
|
||||
thread_local std::vector<uint8_t> respv_optimized_data;
|
||||
@@ -6083,7 +6089,7 @@ RDD::PipelineID RenderingDeviceDriverVulkan::render_pipeline_create(
|
||||
|
||||
VkPipeline vk_pipeline = VK_NULL_HANDLE;
|
||||
VkResult err = vkCreateGraphicsPipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE), &vk_pipeline);
|
||||
ERR_FAIL_COND_V_MSG(err, PipelineID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, PipelineID(), vformat("Couldn't create Vulkan graphics pipelines (VkResult error %d).", err));
|
||||
|
||||
#if RECORD_PIPELINE_STATISTICS
|
||||
{
|
||||
@@ -6280,7 +6286,7 @@ void RenderingDeviceDriverVulkan::_acceleration_structure_create(VkAccelerationS
|
||||
accel_create_info.size = p_size_info.accelerationStructureSize;
|
||||
accel_create_info.buffer = ((const BufferInfo *)buffer.id)->vk_buffer;
|
||||
VkResult err = vkCreateAccelerationStructureKHR(vk_device, &accel_create_info, nullptr, &r_accel_info->vk_acceleration_structure);
|
||||
ERR_FAIL_COND_MSG(err, "vkCreateAccelerationStructureKHR failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_MSG(err, vformat("Couldn't create Vulkan raytracing acceleration structure (VkResult error %d).", err));
|
||||
r_accel_info->build_info.dstAccelerationStructure = r_accel_info->vk_acceleration_structure;
|
||||
#endif
|
||||
}
|
||||
@@ -6288,7 +6294,7 @@ void RenderingDeviceDriverVulkan::_acceleration_structure_create(VkAccelerationS
|
||||
void RenderingDeviceDriverVulkan::acceleration_structure_free(AccelerationStructureID p_acceleration_structure) {
|
||||
#if VULKAN_RAYTRACING_ENABLED
|
||||
AccelerationStructureInfo *accel_info = (AccelerationStructureInfo *)p_acceleration_structure.id;
|
||||
ERR_FAIL_NULL_MSG(accel_info, "Acceleration structure input parameter is not valid.");
|
||||
ERR_FAIL_NULL_MSG(accel_info, "Vulkan raytracing acceleration structure input parameter is not valid.");
|
||||
if (accel_info->buffer) {
|
||||
buffer_free(accel_info->buffer);
|
||||
}
|
||||
@@ -6301,7 +6307,7 @@ void RenderingDeviceDriverVulkan::acceleration_structure_free(AccelerationStruct
|
||||
|
||||
uint32_t RenderingDeviceDriverVulkan::acceleration_structure_get_scratch_size_bytes(AccelerationStructureID p_acceleration_structure) {
|
||||
AccelerationStructureInfo *accel_info = (AccelerationStructureInfo *)p_acceleration_structure.id;
|
||||
ERR_FAIL_NULL_V_MSG(accel_info, 0, "Acceleration structure input parameter is not valid.");
|
||||
ERR_FAIL_NULL_V_MSG(accel_info, 0, "Vulkan raytracing acceleration structure input parameter is not valid.");
|
||||
return accel_info->scratch_size;
|
||||
}
|
||||
|
||||
@@ -6415,7 +6421,7 @@ RDD::RaytracingPipelineID RenderingDeviceDriverVulkan::raytracing_pipeline_creat
|
||||
}
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(!found_shader_stage, RaytracingPipelineID());
|
||||
ERR_FAIL_COND_V_MSG(!found_shader_stage, RaytracingPipelineID(), vformat("Shader \"%s\" doesn't have a stage compatible with the specified raytracing PipelineShaderStage.", shader_info->name));
|
||||
}
|
||||
|
||||
uint32_t shader_group_count = p_raygen_shader_indices.size() + p_miss_shader_indices.size() + p_hit_groups.size();
|
||||
@@ -6469,7 +6475,7 @@ RDD::RaytracingPipelineID RenderingDeviceDriverVulkan::raytracing_pipeline_creat
|
||||
|
||||
VkPipeline vk_pipeline = VK_NULL_HANDLE;
|
||||
VkResult err = vkCreateRayTracingPipelinesKHR(vk_device, VK_NULL_HANDLE, pipelines_cache.vk_cache, 1, &pipeline_create_info, nullptr, &vk_pipeline);
|
||||
ERR_FAIL_COND_V_MSG(err, RaytracingPipelineID(), "vkCreateRayTracingPipelinesKHR failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, RaytracingPipelineID(), vformat("Couldn't create Vulkan raytracing pipelines (VkResult error %d).", err));
|
||||
|
||||
return RaytracingPipelineID(vk_pipeline);
|
||||
#else
|
||||
@@ -6485,10 +6491,14 @@ void RenderingDeviceDriverVulkan::raytracing_pipeline_free(RaytracingPipelineID
|
||||
|
||||
bool RenderingDeviceDriverVulkan::raytracing_pipeline_get_shader_group_handles(RaytracingPipelineID p_pipeline, uint32_t p_group_index_offset, VectorView<uint32_t> p_group_indices, uint8_t *r_data, uint32_t p_data_stride_bytes) {
|
||||
#if VULKAN_RAYTRACING_ENABLED
|
||||
ERR_FAIL_COND_V_MSG(p_data_stride_bytes < raytracing_capabilities.shader_group_handle_size, false, "Data stride must be at least the size of shader group handles.");
|
||||
ERR_FAIL_COND_V_MSG(
|
||||
p_data_stride_bytes < raytracing_capabilities.shader_group_handle_size,
|
||||
false,
|
||||
vformat("Data stride (%d) must be greater than or equal to the size of the shader group handles (%d).", p_data_stride_bytes, raytracing_capabilities.shader_group_handle_size));
|
||||
|
||||
for (uint32_t i = 0; i < p_group_indices.size(); i++) {
|
||||
VkResult err = vkGetRayTracingShaderGroupHandlesKHR(vk_device, (VkPipeline)p_pipeline.id, p_group_index_offset + p_group_indices[i], 1, raytracing_capabilities.shader_group_handle_size, r_data);
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, false, "vkGetRayTracingShaderGroupHandlesKHR failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err != VK_SUCCESS, false, vformat("Couldn't get Vulkan raytracing shader group handles (VkResult error %d).", err));
|
||||
r_data += p_data_stride_bytes;
|
||||
}
|
||||
return true;
|
||||
@@ -6584,7 +6594,7 @@ RDD::PipelineID RenderingDeviceDriverVulkan::compute_pipeline_create(ShaderID p_
|
||||
|
||||
VkPipeline vk_pipeline = VK_NULL_HANDLE;
|
||||
VkResult err = vkCreateComputePipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE), &vk_pipeline);
|
||||
ERR_FAIL_COND_V_MSG(err, PipelineID(), "vkCreateComputePipelines failed with error " + itos(err) + ".");
|
||||
ERR_FAIL_COND_V_MSG(err, PipelineID(), vformat("Couldn't create Vulkan compute pipelines (VkResult error %d).", err));
|
||||
|
||||
return PipelineID(vk_pipeline);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user