diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/vulkan/SCsub | 143 | ||||
| -rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 146 | ||||
| -rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 5 | ||||
| -rw-r--r-- | drivers/vulkan/vulkan_context.cpp | 9 | ||||
| -rw-r--r-- | drivers/vulkan/vulkan_context.h | 9 | ||||
| -rw-r--r-- | drivers/windows/file_access_windows.cpp | 22 |
6 files changed, 184 insertions, 150 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..dbe932f74c 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; } @@ -3275,8 +3283,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 +3299,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 +3375,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 +3544,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 +3568,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 +3602,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 +3704,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 +3719,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 +3825,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; @@ -4506,6 +4585,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."); @@ -5490,7 +5570,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 +5623,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]; @@ -7416,6 +7496,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); @@ -8710,6 +8794,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); } @@ -8844,6 +8929,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 diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index f9ff61310a..6175369285 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; @@ -1149,6 +1153,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); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index a9d0fb6fed..87749450c4 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -681,6 +681,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); @@ -1669,6 +1673,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; diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 83e9524046..fe09d4c497 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: @@ -229,10 +233,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,6 +241,7 @@ 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; diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index f504bad60d..775c999b15 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -35,6 +35,7 @@ #include "core/os/os.h" #include "core/string/print_string.h" +#include <share.h> // _SH_DENYNO #include <shlwapi.h> #include <windows.h> @@ -77,8 +78,8 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { return ERR_INVALID_PARAMETER; } - /* pretty much every implementation that uses fopen as primary - backend supports utf8 encoding */ + /* Pretty much every implementation that uses fopen as primary + backend supports utf8 encoding. */ struct _stat st; if (_wstat((LPCWSTR)(path.utf16().get_data()), &st) == 0) { @@ -113,10 +114,10 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { path = path + ".tmp"; } - errno_t errcode = _wfopen_s(&f, (LPCWSTR)(path.utf16().get_data()), mode_string); + f = _wfsopen((LPCWSTR)(path.utf16().get_data()), mode_string, _SH_DENYNO); if (f == nullptr) { - switch (errcode) { + switch (errno) { case ENOENT: { last_error = ERR_FILE_NOT_FOUND; } break; @@ -157,10 +158,10 @@ void FileAccessWindows::close() { #else if (!PathFileExistsW((LPCWSTR)(save_path.utf16().get_data()))) { #endif - //creating new file + // Creating new file rename_error = _wrename((LPCWSTR)((save_path + ".tmp").utf16().get_data()), (LPCWSTR)(save_path.utf16().get_data())) != 0; } else { - //atomic replace for existing file + // Atomic replace for existing file rename_error = !ReplaceFileW((LPCWSTR)(save_path.utf16().get_data()), (LPCWSTR)((save_path + ".tmp").utf16().get_data()), nullptr, 2 | 4, nullptr, nullptr); } if (rename_error) { @@ -205,6 +206,7 @@ void FileAccessWindows::seek(uint64_t p_position) { void FileAccessWindows::seek_end(int64_t p_position) { ERR_FAIL_COND(!f); + if (_fseeki64(f, p_position, SEEK_END)) { check_errors(); } @@ -237,6 +239,7 @@ bool FileAccessWindows::eof_reached() const { uint8_t FileAccessWindows::get_8() const { ERR_FAIL_COND_V(!f, 0); + if (flags == READ_WRITE || flags == WRITE_READ) { if (prev_op == WRITE) { fflush(f); @@ -273,6 +276,7 @@ Error FileAccessWindows::get_error() const { void FileAccessWindows::flush() { ERR_FAIL_COND(!f); + fflush(f); if (prev_op == WRITE) { prev_op = 0; @@ -281,6 +285,7 @@ void FileAccessWindows::flush() { void FileAccessWindows::store_8(uint8_t p_dest) { ERR_FAIL_COND(!f); + if (flags == READ_WRITE || flags == WRITE_READ) { if (prev_op == READ) { if (last_error != ERR_FILE_EOF) { @@ -295,6 +300,7 @@ void FileAccessWindows::store_8(uint8_t p_dest) { void FileAccessWindows::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND(!f); ERR_FAIL_COND(!p_src && p_length > 0); + if (flags == READ_WRITE || flags == WRITE_READ) { if (prev_op == READ) { if (last_error != ERR_FILE_EOF) { @@ -307,10 +313,8 @@ void FileAccessWindows::store_buffer(const uint8_t *p_src, uint64_t p_length) { } bool FileAccessWindows::file_exists(const String &p_name) { - FILE *g; - //printf("opening file %s\n", p_fname.utf8().get_data()); String filename = fix_path(p_name); - _wfopen_s(&g, (LPCWSTR)(filename.utf16().get_data()), L"rb"); + FILE *g = _wfsopen((LPCWSTR)(filename.utf16().get_data()), L"rb", _SH_DENYNO); if (g == nullptr) { return false; } else { |