summaryrefslogtreecommitdiff
path: root/drivers/vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vulkan')
-rw-r--r--drivers/vulkan/SCsub143
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp286
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h13
-rw-r--r--drivers/vulkan/vulkan_context.cpp111
-rw-r--r--drivers/vulkan/vulkan_context.h13
5 files changed, 363 insertions, 203 deletions
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub
index 6a2a57d18c..8fe75367a8 100644
--- a/drivers/vulkan/SCsub
+++ b/drivers/vulkan/SCsub
@@ -3,116 +3,45 @@
Import("env")
thirdparty_obj = []
+thirdparty_dir = "#thirdparty/vulkan"
+thirdparty_volk_dir = "#thirdparty/volk"
-# FIXME: Refactor all this to reduce code duplication.
-if env["platform"] == "android":
- # Use NDK Vulkan headers
- thirdparty_dir = env["ANDROID_NDK_ROOT"] + "/sources/third_party/vulkan/src"
- thirdparty_includes = [
- thirdparty_dir,
- thirdparty_dir + "/include",
- thirdparty_dir + "/layers",
- thirdparty_dir + "/layers/generated",
- ]
- env.Prepend(CPPPATH=thirdparty_includes)
-
- # Build Vulkan memory allocator
- env_thirdparty = env.Clone()
- env_thirdparty.disable_warnings()
-
- thirdparty_dir = "#thirdparty/vulkan"
- vma_sources = [thirdparty_dir + "/android/vk_mem_alloc.cpp"]
- env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
+# Use bundled Vulkan headers
+env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"])
+
+if env["use_volk"]:
+ env.AppendUnique(CPPDEFINES=["USE_VOLK"])
+ env.Prepend(CPPPATH=[thirdparty_volk_dir])
+if env["platform"] == "android":
+ env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"])
elif env["platform"] == "iphone":
- # Use bundled Vulkan headers
- thirdparty_dir = "#thirdparty/vulkan"
- env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include", thirdparty_dir + "/loader"])
-
- # Build Vulkan memory allocator
- env_thirdparty = env.Clone()
- env_thirdparty.disable_warnings()
-
- vma_sources = [thirdparty_dir + "/vk_mem_alloc.cpp"]
- env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
-
-elif env["builtin_vulkan"]:
- # Use bundled Vulkan headers
- thirdparty_dir = "#thirdparty/vulkan"
- env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include", thirdparty_dir + "/loader"])
-
- # Build Vulkan loader library
- env_thirdparty = env.Clone()
- env_thirdparty.disable_warnings()
-
- loader_sources = [
- "cJSON.c",
- "debug_utils.c",
- "dev_ext_trampoline.c",
- "loader.c",
- "murmurhash.c",
- "phys_dev_ext.c",
- "trampoline.c",
- "unknown_ext_chain.c",
- "wsi.c",
- "extension_manual.c",
- ]
- vma_sources = [thirdparty_dir + "/vk_mem_alloc.cpp"]
-
- if env["platform"] == "windows":
- loader_sources.append("dirent_on_windows.c")
- env_thirdparty.AppendUnique(
- CPPDEFINES=[
- "VK_USE_PLATFORM_WIN32_KHR",
- "VULKAN_NON_CMAKE_BUILD",
- "WIN32_LEAN_AND_MEAN",
- 'API_NAME=\\"%s\\"' % "Vulkan",
- ]
- )
- if not env.msvc: # Windows 7+, missing in mingw headers
- env_thirdparty.AppendUnique(
- CPPDEFINES=["CM_GETIDLIST_FILTER_CLASS=0x00000200", "CM_GETIDLIST_FILTER_PRESENT=0x00000100"]
- )
- elif env["platform"] == "osx":
- env_thirdparty.AppendUnique(
- CPPDEFINES=[
- "VK_USE_PLATFORM_MACOS_MVK",
- "VULKAN_NON_CMAKE_BUILD",
- 'SYSCONFDIR=\\"%s\\"' % "/etc",
- 'FALLBACK_DATA_DIRS=\\"%s\\"' % "/usr/local/share:/usr/share",
- 'FALLBACK_CONFIG_DIRS=\\"%s\\"' % "/etc/xdg",
- ]
- )
- elif env["platform"] == "linuxbsd":
- env_thirdparty.AppendUnique(
- CPPDEFINES=[
- "VK_USE_PLATFORM_XLIB_KHR",
- "VULKAN_NON_CMAKE_BUILD",
- 'SYSCONFDIR=\\"%s\\"' % "/etc",
- 'FALLBACK_DATA_DIRS=\\"%s\\"' % "/usr/local/share:/usr/share",
- 'FALLBACK_CONFIG_DIRS=\\"%s\\"' % "/etc/xdg",
- ]
- )
- import platform
-
- if platform.system() == "Linux":
- # In glibc since 2.17 and musl libc since 1.1.24. Used by loader.c.
- env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
-
- loader_sources = [thirdparty_dir + "/loader/" + file for file in loader_sources]
- env_thirdparty.add_source_files(thirdparty_obj, loader_sources)
- env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
-
-else: # Always build VMA.
- thirdparty_dir = "#thirdparty/vulkan"
- env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"])
-
- # Build Vulkan loader library
- env_thirdparty = env.Clone()
- env_thirdparty.disable_warnings()
- vma_sources = [thirdparty_dir + "/vk_mem_alloc.cpp"]
-
- env_thirdparty.add_source_files(thirdparty_obj, vma_sources)
+ env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_IOS_MVK"])
+elif env["platform"] == "linuxbsd":
+ env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_XLIB_KHR"])
+elif env["platform"] == "osx":
+ env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_MACOS_MVK"])
+elif env["platform"] == "windows":
+ env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_WIN32_KHR"])
+
+# Build Vulkan memory allocator and volk
+env_thirdparty_vma = env.Clone()
+env_thirdparty_vma.disable_warnings()
+thirdparty_sources_vma = [thirdparty_dir + "/vk_mem_alloc.cpp"]
+
+if env["use_volk"]:
+ env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_STATIC_VULKAN_FUNCTIONS=1"])
+ env_thirdparty_volk = env.Clone()
+ env_thirdparty_volk.disable_warnings()
+
+ thirdparty_sources_volk = [thirdparty_volk_dir + "/volk.c"]
+ env_thirdparty_volk.add_source_files(thirdparty_obj, thirdparty_sources_volk)
+elif env["platform"] == "android":
+ # Our current NDK version only provides old Vulkan headers,
+ # so we have to limit VMA.
+ env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1000000"])
+
+env_thirdparty_vma.add_source_files(thirdparty_obj, thirdparty_sources_vma)
env.drivers_sources += thirdparty_obj
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 9ee2a28240..a4324f0a2c 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1804,6 +1804,10 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
}
+ if (p_format.usage_bits & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT) {
+ image_create_info.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
+ }
+
if (p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT) {
image_create_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
}
@@ -2134,6 +2138,10 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
}
}
+ if (texture.usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
+ }
+
if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
usage_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
}
@@ -2732,6 +2740,14 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) {
return texture_owner.owns(p_texture);
}
+Size2i RenderingDeviceVulkan::texture_size(RID p_texture) {
+ _THREAD_SAFE_METHOD_
+
+ Texture *tex = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND_V(!tex, Size2i());
+ return Size2i(tex->width, tex->height);
+}
+
Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
@@ -3275,8 +3291,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
for (int i = 0; i < p_attachments.size(); i++) {
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE);
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE);
- ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT)),
- VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (depth, stencil or resolve) bit set.");
+ ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)),
+ VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (color, depth, input or stencil) bit set.");
VkAttachmentDescription description = {};
description.flags = 0;
@@ -3291,13 +3307,25 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
// Also, each UNDEFINED will do an immediate layout transition (write), s.t. we must ensure execution synchronization vs.
// the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that
// stage
+
switch (is_depth ? p_initial_depth_action : p_initial_action) {
case INITIAL_ACTION_CLEAR_REGION:
case INITIAL_ACTION_CLEAR: {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- dependency_from_external.srcStageMask |= reading_stages;
+ if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ dependency_from_external.srcStageMask |= reading_stages;
+ } else {
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
+ dependency_from_external.srcStageMask |= reading_stages;
+ }
} break;
case INITIAL_ACTION_KEEP: {
if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
@@ -3355,7 +3383,58 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
}
- switch (is_depth ? p_final_depth_action : p_final_action) {
+ bool used_last = false;
+
+ {
+ int last_pass = p_passes.size() - 1;
+
+ if (is_depth) {
+ //likely missing depth resolve?
+ if (p_passes[last_pass].depth_attachment == i) {
+ used_last = true;
+ }
+ } else {
+ if (p_passes[last_pass].resolve_attachments.size()) {
+ //if using resolve attachments, check resolve attachments
+ for (int j = 0; j < p_passes[last_pass].resolve_attachments.size(); j++) {
+ if (p_passes[last_pass].resolve_attachments[j] == i) {
+ used_last = true;
+ break;
+ }
+ }
+ } else {
+ for (int j = 0; j < p_passes[last_pass].color_attachments.size(); j++) {
+ if (p_passes[last_pass].color_attachments[j] == i) {
+ used_last = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!used_last) {
+ for (int j = 0; j < p_passes[last_pass].preserve_attachments.size(); j++) {
+ if (p_passes[last_pass].preserve_attachments[j] == i) {
+ used_last = true;
+ break;
+ }
+ }
+ }
+ }
+
+ FinalAction final_action = p_final_action;
+ FinalAction final_depth_action = p_final_depth_action;
+
+ if (!used_last) {
+ if (is_depth) {
+ final_depth_action = FINAL_ACTION_DISCARD;
+
+ } else {
+ final_action = FINAL_ACTION_DISCARD;
+ }
+ }
+
+ switch (is_depth ? final_depth_action : final_action) {
case FINAL_ACTION_READ: {
if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -3473,7 +3552,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
} else {
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), input attachment (" + itos(j) + ").");
- ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as depth, but it's not usable as input attachment.");
+ ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it isn't marked as an input texture.");
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
reference.attachment = attachment;
reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -3497,32 +3576,17 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
} else {
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachment (" + itos(j) + ").");
ERR_FAIL_COND_V_MSG(pass->color_attachments[j] == FramebufferPass::ATTACHMENT_UNUSED, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachment (" + itos(j) + "), the respective color attachment is marked as unused.");
- ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as depth, but it's not usable as resolve attachment.");
+ ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachment, it isn't marked as a color texture.");
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
bool multisample = p_attachments[attachment].samples > TEXTURE_SAMPLES_1;
ERR_FAIL_COND_V_MSG(multisample, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachments can't be multisample.");
reference.attachment = attachment;
- reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
attachment_last_pass[attachment] = i;
}
resolve_references.push_back(reference);
}
- LocalVector<uint32_t> &preserve_references = preserve_reference_array[i];
-
- for (int j = 0; j < pass->preserve_attachments.size(); j++) {
- int32_t attachment = pass->preserve_attachments[j];
-
- ERR_FAIL_COND_V_MSG(attachment == FramebufferPass::ATTACHMENT_UNUSED, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + "). Preserve attachments can't be unused.");
-
- ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + ").");
- ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
-
- attachment_last_pass[attachment] = i;
-
- preserve_references.push_back(attachment);
- }
-
VkAttachmentReference &depth_stencil_reference = depth_reference_array[i];
if (pass->depth_attachment != FramebufferPass::ATTACHMENT_UNUSED) {
@@ -3546,6 +3610,22 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
}
+ LocalVector<uint32_t> &preserve_references = preserve_reference_array[i];
+
+ for (int j = 0; j < pass->preserve_attachments.size(); j++) {
+ int32_t attachment = pass->preserve_attachments[j];
+
+ ERR_FAIL_COND_V_MSG(attachment == FramebufferPass::ATTACHMENT_UNUSED, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + "). Preserve attachments can't be unused.");
+
+ ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + ").");
+
+ if (attachment_last_pass[attachment] != i) {
+ //preserve can still be used to keep depth or color from being discarded after use
+ attachment_last_pass[attachment] = i;
+ preserve_references.push_back(attachment);
+ }
+ }
+
VkSubpassDescription &subpass = subpasses[i];
subpass.flags = 0;
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
@@ -3632,8 +3712,10 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
render_pass_create_info.pDependencies = nullptr;
}
+ // These are only used if we use multiview but we need to define them in scope.
const uint32_t view_mask = (1 << p_view_count) - 1;
const uint32_t correlation_mask = (1 << p_view_count) - 1;
+ Vector<uint32_t> view_masks;
VkRenderPassMultiviewCreateInfo render_pass_multiview_create_info;
if (p_view_count > 1) {
@@ -3645,10 +3727,15 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
// Make sure we limit this to the number of views we support.
ERR_FAIL_COND_V_MSG(p_view_count > capabilities.max_view_count, VK_NULL_HANDLE, "Hardware does not support requested number of views for Multiview render pass");
+ // Set view masks for each subpass
+ for (uint32_t i = 0; i < subpasses.size(); i++) {
+ view_masks.push_back(view_mask);
+ };
+
render_pass_multiview_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
render_pass_multiview_create_info.pNext = nullptr;
- render_pass_multiview_create_info.subpassCount = 1;
- render_pass_multiview_create_info.pViewMasks = &view_mask;
+ render_pass_multiview_create_info.subpassCount = subpasses.size();
+ render_pass_multiview_create_info.pViewMasks = view_masks.ptr();
render_pass_multiview_create_info.dependencyCount = 0;
render_pass_multiview_create_info.pViewOffsets = nullptr;
render_pass_multiview_create_info.correlationMaskCount = 1;
@@ -3746,7 +3833,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
VkRenderPass render_pass;
VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
- ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateRenderPass for empty fb failed with error " + itos(res) + ".");
+ ERR_FAIL_COND_V_MSG(res, 0, "vkCreateRenderPass for empty fb failed with error " + itos(res) + ".");
if (render_pass == VK_NULL_HANDLE) { //was likely invalid
return INVALID_ID;
@@ -4363,7 +4450,10 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
}
#endif
-#define SHADER_BINARY_VERSION 1
+//version 1: initial
+//version 2: Added shader name
+
+#define SHADER_BINARY_VERSION 2
String RenderingDeviceVulkan::shader_get_binary_cache_key() const {
return "Vulkan-SV" + itos(SHADER_BINARY_VERSION);
@@ -4397,9 +4487,10 @@ struct RenderingDeviceVulkanShaderBinaryData {
uint32_t push_constant_size;
uint32_t push_constants_vk_stage;
uint32_t stage_count;
+ uint32_t shader_name_len;
};
-Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv) {
+Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, const String &p_shader_name) {
RenderingDeviceVulkanShaderBinaryData binary_data;
binary_data.vertex_input_mask = 0;
binary_data.fragment_outputs = 0;
@@ -4506,6 +4597,7 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
info.type = UNIFORM_TYPE_INPUT_ATTACHMENT;
+ need_array_dimensions = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
ERR_PRINT("Acceleration structure not supported.");
@@ -4755,9 +4847,19 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
binary_data.set_count = uniform_info.size();
binary_data.stage_count = p_spirv.size();
+ CharString shader_name_utf = p_shader_name.utf8();
+
+ binary_data.shader_name_len = shader_name_utf.length();
+
uint32_t total_size = sizeof(uint32_t) * 3; //header + version + main datasize;
total_size += sizeof(RenderingDeviceVulkanShaderBinaryData);
+ total_size += binary_data.shader_name_len;
+
+ if ((binary_data.shader_name_len % 4) != 0) { //alignment rules are really strange
+ total_size += 4 - (binary_data.shader_name_len % 4);
+ }
+
for (int i = 0; i < uniform_info.size(); i++) {
total_size += sizeof(uint32_t);
total_size += uniform_info[i].size() * sizeof(RenderingDeviceVulkanShaderBinaryDataBinding);
@@ -4784,6 +4886,12 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve
offset += sizeof(uint32_t);
memcpy(binptr + offset, &binary_data, sizeof(RenderingDeviceVulkanShaderBinaryData));
offset += sizeof(RenderingDeviceVulkanShaderBinaryData);
+ memcpy(binptr + offset, shader_name_utf.ptr(), binary_data.shader_name_len);
+ offset += binary_data.shader_name_len;
+
+ if ((binary_data.shader_name_len % 4) != 0) { //alignment rules are really strange
+ offset += 4 - (binary_data.shader_name_len % 4);
+ }
for (int i = 0; i < uniform_info.size(); i++) {
int count = uniform_info[i].size();
@@ -4854,6 +4962,16 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
read_offset += sizeof(uint32_t) * 3 + bin_data_size;
+ String name;
+
+ if (binary_data.shader_name_len) {
+ name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
+ read_offset += binary_data.shader_name_len;
+ if ((binary_data.shader_name_len % 4) != 0) { //alignment rules are really strange
+ read_offset += 4 - (binary_data.shader_name_len % 4);
+ }
+ }
+
Vector<Vector<VkDescriptorSetLayoutBinding>> set_bindings;
Vector<Vector<UniformInfo>> uniform_info;
@@ -5008,6 +5126,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_
shader.compute_local_size[1] = compute_local_size[1];
shader.compute_local_size[2] = compute_local_size[2];
shader.specialization_constants = specialization_constants;
+ shader.name = name;
String error_text;
@@ -5490,7 +5609,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.sampler = *sampler;
img_info.imageView = texture->view;
- if (texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT)) {
+ if (texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) {
UniformSet::AttachableTexture attachable_texture;
attachable_texture.bind = set_uniform.binding;
attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.ids[j + 1];
@@ -5543,7 +5662,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
img_info.sampler = VK_NULL_HANDLE;
img_info.imageView = texture->view;
- if (texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT)) {
+ if (texture->usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) {
UniformSet::AttachableTexture attachable_texture;
attachable_texture.bind = set_uniform.binding;
attachable_texture.texture = texture->owner.is_valid() ? texture->owner : uniform.ids[j];
@@ -6369,7 +6488,6 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
specialization_info.write[i].pData = data_ptr;
specialization_info.write[i].mapEntryCount = specialization_map_entries[i].size();
specialization_info.write[i].pMapEntries = specialization_map_entries[i].ptr();
-
pipeline_stages.write[i].pSpecializationInfo = specialization_info.ptr() + i;
}
}
@@ -6396,7 +6514,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
RenderPipeline pipeline;
VkResult err = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline.pipeline);
- ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + ".");
+ ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + " for shader '" + shader->name + "'.");
pipeline.set_formats = shader->set_formats;
pipeline.push_constant_stages = shader->push_constant.push_constants_vk_stage;
@@ -7416,6 +7534,10 @@ void RenderingDeviceVulkan::draw_list_disable_scissor(DrawListID p_list) {
vkCmdSetScissor(dl->command_buffer, 0, 1, &scissor);
}
+uint32_t RenderingDeviceVulkan::draw_list_get_current_pass() {
+ return draw_list_current_subpass;
+}
+
RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_switch_to_next_pass() {
ERR_FAIL_COND_V(draw_list == nullptr, INVALID_ID);
ERR_FAIL_COND_V(draw_list_current_subpass >= draw_list_subpass_count - 1, INVALID_FORMAT_ID);
@@ -7466,7 +7588,7 @@ Error RenderingDeviceVulkan::_draw_list_allocate(const Rect2i &p_viewport, uint3
VkCommandPoolCreateInfo cmd_pool_info;
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cmd_pool_info.pNext = nullptr;
- cmd_pool_info.queueFamilyIndex = context->get_graphics_queue();
+ cmd_pool_info.queueFamilyIndex = context->get_graphics_queue_family_index();
cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
VkResult res = vkCreateCommandPool(device, &cmd_pool_info, nullptr, &split_draw_list_allocators.write[i].command_pool);
@@ -7843,13 +7965,13 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
textures_to_storage[i]->used_in_compute = false;
textures_to_storage[i]->used_in_raster = false;
- textures_to_storage[i]->used_in_compute = false;
+ textures_to_storage[i]->used_in_transfer = false;
} else {
src_access_flags = 0;
textures_to_storage[i]->used_in_compute = false;
textures_to_storage[i]->used_in_raster = false;
- textures_to_storage[i]->used_in_compute = false;
+ textures_to_storage[i]->used_in_transfer = false;
textures_to_storage[i]->used_in_frame = frames_drawn;
}
@@ -8710,6 +8832,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
memset(&allocatorInfo, 0, sizeof(VmaAllocatorCreateInfo));
allocatorInfo.physicalDevice = p_context->get_physical_device();
allocatorInfo.device = device;
+ allocatorInfo.instance = p_context->get_instance();
vmaCreateAllocator(&allocatorInfo, &allocator);
}
@@ -8723,7 +8846,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
VkCommandPoolCreateInfo cmd_pool_info;
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cmd_pool_info.pNext = nullptr;
- cmd_pool_info.queueFamilyIndex = p_context->get_graphics_queue();
+ cmd_pool_info.queueFamilyIndex = p_context->get_graphics_queue_family_index();
cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
VkResult res = vkCreateCommandPool(device, &cmd_pool_info, nullptr, &frames[i].command_pool);
@@ -8844,6 +8967,7 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) {
}
void RenderingDeviceVulkan::capture_timestamp(const String &p_name) {
+ ERR_FAIL_COND_MSG(draw_list != nullptr, "Capturing timestamps during draw list creation is not allowed. Offending timestap was: " + p_name);
ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements);
//this should be optional for profiling, else it will slow things down
@@ -8892,6 +9016,92 @@ void RenderingDeviceVulkan::capture_timestamp(const String &p_name) {
frames[frame].timestamp_count++;
}
+uint64_t RenderingDeviceVulkan::get_driver_resource(DriverResource p_resource, RID p_rid, uint64_t p_index) {
+ _THREAD_SAFE_METHOD_
+
+ switch (p_resource) {
+ case DRIVER_RESOURCE_VULKAN_DEVICE: {
+ return (uint64_t)context->get_device();
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE: {
+ return (uint64_t)context->get_physical_device();
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_INSTANCE: {
+ return (uint64_t)context->get_instance();
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_QUEUE: {
+ return (uint64_t)context->get_graphics_queue();
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_QUEUE_FAMILY_INDEX: {
+ return context->get_graphics_queue_family_index();
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_IMAGE: {
+ Texture *tex = texture_owner.getornull(p_rid);
+ ERR_FAIL_NULL_V(tex, 0);
+
+ return (uint64_t)tex->image;
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_IMAGE_VIEW: {
+ Texture *tex = texture_owner.getornull(p_rid);
+ ERR_FAIL_NULL_V(tex, 0);
+
+ return (uint64_t)tex->view;
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT: {
+ Texture *tex = texture_owner.getornull(p_rid);
+ ERR_FAIL_NULL_V(tex, 0);
+
+ return vulkan_formats[tex->format];
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_SAMPLER: {
+ VkSampler *sampler = sampler_owner.getornull(p_rid);
+ ERR_FAIL_NULL_V(sampler, 0);
+
+ return uint64_t(*sampler);
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_DESCRIPTOR_SET: {
+ UniformSet *uniform_set = uniform_set_owner.getornull(p_rid);
+ ERR_FAIL_NULL_V(uniform_set, 0);
+
+ return uint64_t(uniform_set->descriptor_set);
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_BUFFER: {
+ Buffer *buffer = nullptr;
+ if (vertex_buffer_owner.owns(p_rid)) {
+ buffer = vertex_buffer_owner.getornull(p_rid);
+ } else if (index_buffer_owner.owns(p_rid)) {
+ buffer = index_buffer_owner.getornull(p_rid);
+ } else if (uniform_buffer_owner.owns(p_rid)) {
+ buffer = uniform_buffer_owner.getornull(p_rid);
+ } else if (texture_buffer_owner.owns(p_rid)) {
+ buffer = &texture_buffer_owner.getornull(p_rid)->buffer;
+ } else if (storage_buffer_owner.owns(p_rid)) {
+ buffer = storage_buffer_owner.getornull(p_rid);
+ }
+
+ ERR_FAIL_NULL_V(buffer, 0);
+
+ return uint64_t(buffer->buffer);
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_COMPUTE_PIPELINE: {
+ ComputePipeline *compute_pipeline = compute_pipeline_owner.getornull(p_rid);
+ ERR_FAIL_NULL_V(compute_pipeline, 0);
+
+ return uint64_t(compute_pipeline->pipeline);
+ }; break;
+ case DRIVER_RESOURCE_VULKAN_RENDER_PIPELINE: {
+ RenderPipeline *render_pipeline = render_pipeline_owner.getornull(p_rid);
+ ERR_FAIL_NULL_V(render_pipeline, 0);
+
+ return uint64_t(render_pipeline->pipeline);
+ }; break;
+ default: {
+ // not supported for this driver
+ return 0;
+ }; break;
+ }
+}
+
uint32_t RenderingDeviceVulkan::get_captured_timestamps_count() const {
return frames[frame].timestamp_result_count;
}
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index f9ff61310a..cf0b725cfc 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -44,7 +44,11 @@
#endif
#include "vk_mem_alloc.h"
+#ifdef USE_VOLK
+#include <volk.h>
+#else
#include <vulkan/vulkan.h>
+#endif
class VulkanContext;
@@ -635,6 +639,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
Vector<VkPipelineShaderStageCreateInfo> pipeline_stages;
Vector<SpecializationConstant> specialization_constants;
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
+ String name; //used for debug
};
String _shader_uniform_debug(RID p_shader, int p_set = -1);
@@ -808,7 +813,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
// When using split command lists, this is
// implemented internally using secondary command
// buffers. As they can be created in threads,
- // each needs it's own command pool.
+ // each needs its own command pool.
struct SplitDrawListAllocator {
VkCommandPool command_pool = VK_NULL_HANDLE;
@@ -1039,6 +1044,7 @@ public:
virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const;
virtual bool texture_is_shared(RID p_texture);
virtual bool texture_is_valid(RID p_texture);
+ virtual Size2i texture_size(RID p_texture);
virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL);
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL);
@@ -1084,7 +1090,7 @@ public:
/****************/
virtual String shader_get_binary_cache_key() const;
- virtual Vector<uint8_t> shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv);
+ virtual Vector<uint8_t> shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, const String &p_shader_name = "");
virtual RID shader_create_from_bytecode(const Vector<uint8_t> &p_shader_binary);
@@ -1149,6 +1155,7 @@ public:
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect);
virtual void draw_list_disable_scissor(DrawListID p_list);
+ virtual uint32_t draw_list_get_current_pass();
virtual DrawListID draw_list_switch_to_next_pass();
virtual Error draw_list_switch_to_next_pass_split(uint32_t p_splits, DrawListID *r_split_ids);
@@ -1220,6 +1227,8 @@ public:
virtual String get_device_name() const;
virtual String get_device_pipeline_cache_uuid() const;
+ virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0);
+
RenderingDeviceVulkan();
~RenderingDeviceVulkan();
};
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index d35c519320..bb0123e536 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -275,22 +275,21 @@ Error VulkanContext::_obtain_vulkan_version() {
if (res == VK_SUCCESS) {
vulkan_major = VK_VERSION_MAJOR(api_version);
vulkan_minor = VK_VERSION_MINOR(api_version);
- uint32_t vulkan_patch = VK_VERSION_PATCH(api_version);
-
- print_line("Vulkan API " + itos(vulkan_major) + "." + itos(vulkan_minor) + "." + itos(vulkan_patch));
+ vulkan_patch = VK_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
ERR_FAIL_V(ERR_CANT_CREATE);
}
} else {
- print_line("vkEnumerateInstanceVersion not available, assuming Vulkan 1.0");
+ print_line("vkEnumerateInstanceVersion not available, assuming Vulkan 1.0.");
}
// we don't go above 1.2
if ((vulkan_major > 1) || (vulkan_major == 1 && vulkan_minor > 2)) {
vulkan_major = 1;
vulkan_minor = 2;
+ vulkan_patch = 0;
}
return OK;
@@ -577,26 +576,22 @@ Error VulkanContext::_check_capabilities() {
multiview_capabilities.max_view_count = multiviewProperties.maxMultiviewViewCount;
multiview_capabilities.max_instance_count = multiviewProperties.maxMultiviewInstanceIndex;
-#ifdef DEBUG_ENABLED
- print_line("- Vulkan multiview supported:");
- print_line(" max view count: " + itos(multiview_capabilities.max_view_count));
- print_line(" max instances: " + itos(multiview_capabilities.max_instance_count));
+ print_verbose("- Vulkan multiview supported:");
+ print_verbose(" max view count: " + itos(multiview_capabilities.max_view_count));
+ print_verbose(" max instances: " + itos(multiview_capabilities.max_instance_count));
} else {
- print_line("- Vulkan multiview not supported");
-#endif
+ print_verbose("- Vulkan multiview not supported");
}
-#ifdef DEBUG_ENABLED
- print_line("- Vulkan subgroup:");
- print_line(" size: " + itos(subgroup_capabilities.size));
- print_line(" stages: " + subgroup_capabilities.supported_stages_desc());
- print_line(" supported ops: " + subgroup_capabilities.supported_operations_desc());
+ print_verbose("- Vulkan subgroup:");
+ print_verbose(" size: " + itos(subgroup_capabilities.size));
+ print_verbose(" stages: " + subgroup_capabilities.supported_stages_desc());
+ print_verbose(" supported ops: " + subgroup_capabilities.supported_operations_desc());
if (subgroup_capabilities.quadOperationsInAllStages) {
- print_line(" quad operations in all stages");
+ print_verbose(" quad operations in all stages");
}
} else {
- print_line("- Couldn't call vkGetPhysicalDeviceProperties2");
-#endif
+ print_verbose("- Couldn't call vkGetPhysicalDeviceProperties2");
}
return OK;
@@ -685,6 +680,10 @@ Error VulkanContext::_create_physical_device() {
inst_initialized = true;
+#ifdef USE_VOLK
+ volkLoadInstance(inst);
+#endif
+
/* Make initial call to query gpu_count, then second call for gpu info*/
err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -737,10 +736,11 @@ Error VulkanContext::_create_physical_device() {
} vendor_names[] = {
{ 0x1002, "AMD" },
{ 0x1010, "ImgTec" },
+ { 0x106B, "Apple" },
{ 0x10DE, "NVIDIA" },
{ 0x13B5, "ARM" },
{ 0x5143, "Qualcomm" },
- { 0x8086, "INTEL" },
+ { 0x8086, "Intel" },
{ 0, nullptr },
};
device_name = gpu_props.deviceName;
@@ -757,9 +757,11 @@ Error VulkanContext::_create_physical_device() {
vendor_idx++;
}
}
-#ifdef DEBUG_ENABLED
- print_line("Using Vulkan Device #" + itos(device_index) + ": " + device_vendor + " - " + device_name);
-#endif
+
+ print_line(
+ "Vulkan API " + itos(vulkan_major) + "." + itos(vulkan_minor) + "." + itos(vulkan_patch) +
+ " - " + "Using Vulkan Device #" + itos(device_index) + ": " + device_vendor + " - " + device_name);
+
device_api_version = gpu_props.apiVersion;
err = vkEnumerateDeviceExtensionProperties(gpu, nullptr, &device_extension_count, nullptr);
@@ -975,37 +977,35 @@ Error VulkanContext::_create_device() {
sdevice.queueCreateInfoCount = 2;
}
-#ifdef VK_VERSION_1_2
VkPhysicalDeviceVulkan11Features vulkan11features;
-
- 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;
-#elif VK_VERSION_1_1
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;
- 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;
-#endif
+ sdevice.pNext = &multiview_features;
+ }
err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -1672,6 +1672,11 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
Error VulkanContext::initialize() {
+#ifdef USE_VOLK
+ if (volkInitialize() != VK_SUCCESS) {
+ return FAILED;
+ }
+#endif
Error err = _create_physical_device();
if (err) {
return err;
@@ -2024,7 +2029,11 @@ int VulkanContext::get_swapchain_image_count() const {
return swapchainImageCount;
}
-uint32_t VulkanContext::get_graphics_queue() const {
+VkQueue VulkanContext::get_graphics_queue() const {
+ return graphics_queue;
+}
+
+uint32_t VulkanContext::get_graphics_queue_family_index() const {
return graphics_queue_family_index;
}
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 83e9524046..ae7c697be8 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -38,7 +38,11 @@
#include "core/templates/rid_owner.h"
#include "servers/display_server.h"
+#ifdef USE_VOLK
+#include <volk.h>
+#else
#include <vulkan/vulkan.h>
+#endif
class VulkanContext {
public:
@@ -81,6 +85,7 @@ private:
// Vulkan 1.0 doesn't return version info so we assume this by default until we know otherwise
uint32_t vulkan_major = 1;
uint32_t vulkan_minor = 0;
+ uint32_t vulkan_patch = 0;
SubgroupCapabilities subgroup_capabilities;
MultiviewCapabilities multiview_capabilities;
@@ -229,10 +234,6 @@ protected:
Error _get_preferred_validation_layers(uint32_t *count, const char *const **names);
- VkInstance _get_instance() {
- return inst;
- }
-
public:
uint32_t get_vulkan_major() const { return vulkan_major; };
uint32_t get_vulkan_minor() const { return vulkan_minor; };
@@ -241,8 +242,10 @@ public:
VkDevice get_device();
VkPhysicalDevice get_physical_device();
+ VkInstance get_instance() { return inst; }
int get_swapchain_image_count() const;
- uint32_t get_graphics_queue() const;
+ VkQueue get_graphics_queue() const;
+ uint32_t get_graphics_queue_family_index() const;
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
int window_get_width(DisplayServer::WindowID p_window = 0);