From e252df0d5c991ab68b20b3e51949426a7326d351 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:03:40 -0400 Subject: [PATCH 01/12] Align main_loop_frame() and main_loop() to improve error handling / eliminate redundancy --- framework/platform/platform.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/platform/platform.cpp b/framework/platform/platform.cpp index 9f6877fbe..c704d51aa 100644 --- a/framework/platform/platform.cpp +++ b/framework/platform/platform.cpp @@ -151,6 +151,11 @@ ExitCode Platform::main_loop_frame() } window->process_events(); + + if (window->should_close() || close_requested) + { + return ExitCode::Close; + } } catch (std::exception &e) { @@ -175,13 +180,8 @@ ExitCode Platform::main_loop_frame() ExitCode Platform::main_loop() { - if (!app_requested()) - { - return ExitCode::NoSample; - } - ExitCode exit_code = ExitCode::Success; - while ((exit_code == ExitCode::Success) && !window->should_close() && !close_requested) + while (exit_code == ExitCode::Success) { exit_code = main_loop_frame(); } From 0df8018dad36203991509fa935a254a795751b15 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:06:24 -0400 Subject: [PATCH 02/12] Ensure render context is defined before calling render() within [HPP]ApiVulkanSample::update() --- framework/api_vulkan_sample.cpp | 6 +++++- framework/hpp_api_vulkan_sample.cpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/framework/api_vulkan_sample.cpp b/framework/api_vulkan_sample.cpp index 5a8ae55a5..f8431491f 100644 --- a/framework/api_vulkan_sample.cpp +++ b/framework/api_vulkan_sample.cpp @@ -92,7 +92,11 @@ void ApiVulkanSample::update(float delta_time) view_changed(); } - render(delta_time); + if (has_render_context()) + { + render(delta_time); + } + camera.update(delta_time); if (camera.moving()) { diff --git a/framework/hpp_api_vulkan_sample.cpp b/framework/hpp_api_vulkan_sample.cpp index bd8303fbf..fb8b97735 100644 --- a/framework/hpp_api_vulkan_sample.cpp +++ b/framework/hpp_api_vulkan_sample.cpp @@ -87,7 +87,11 @@ void HPPApiVulkanSample::update(float delta_time) view_changed(); } - render(delta_time); + if (has_render_context()) + { + render(delta_time); + } + camera.update(delta_time); if (camera.moving()) { From 1f5c4e72def11eb008521f90f1043e161bea5f96 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:14:24 -0400 Subject: [PATCH 03/12] Improve main_loop_frame() return/exit code handling within iOS renderLoop() --- app/ios/ViewController.mm | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/app/ios/ViewController.mm b/app/ios/ViewController.mm index 88717ffc7..f3ada527e 100644 --- a/app/ios/ViewController.mm +++ b/app/ios/ViewController.mm @@ -58,16 +58,17 @@ - (void)viewDidLoad { -(void) renderLoop { if(!_displayLink.isPaused && [UIApplication sharedApplication].applicationState == UIApplicationStateActive) { - _code = ((vkb::IosPlatform*)_context->userPlatform)->main_loop_frame(); - } -} + if(_code == vkb::ExitCode::Success) { + _code = ((vkb::IosPlatform*)_context->userPlatform)->main_loop_frame(); + } + else { + // On ExitCode error, remove displayLink from run loop and terminate any active sample or batch run + [_displayLink invalidate]; + ((vkb::IosPlatform*)_context->userPlatform)->terminate(_code); -- (void)dealloc { - [_displayLink invalidate]; - [_displayLink release]; - ((vkb::IosPlatform*)_context->userPlatform)->terminate(_code); - - [self.vulkan_view release]; - [super dealloc]; + // Not typically allowed for iOS apps, but exit here given this is an Xcode-controlled dev application + exit(0); + } + } } @end From e3b80b6200c49a33ddc9debc37f486a5fb45d9d4 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Tue, 17 Sep 2024 00:18:52 -0400 Subject: [PATCH 04/12] Add support for setting and getting iOS window content scale factor --- app/ios/ViewController.mm | 2 ++ framework/platform/ios/ios_window.h | 2 ++ framework/platform/ios/ios_window.mm | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/app/ios/ViewController.mm b/app/ios/ViewController.mm index f3ada527e..5f1f8bd41 100644 --- a/app/ios/ViewController.mm +++ b/app/ios/ViewController.mm @@ -46,6 +46,8 @@ - (void)viewDidLoad { argv[i] = s.UTF8String; } + self.vulkan_view.contentScaleFactor = UIScreen.mainScreen.nativeScale; + context = create_platform_context((int)args.count, const_cast(argv)); _context = (vkb::IosPlatformContext*)context.get(); _context->view = self.vulkan_view; diff --git a/framework/platform/ios/ios_window.h b/framework/platform/ios/ios_window.h index af3577049..5e63dfe76 100644 --- a/framework/platform/ios/ios_window.h +++ b/framework/platform/ios/ios_window.h @@ -65,6 +65,8 @@ class IosWindow : public Window float get_dpi_factor() const override; + float get_content_scale_factor() const override; + std::vector get_required_surface_extensions() const override; VulkanView * get_vulkan_view() {return view;} diff --git a/framework/platform/ios/ios_window.mm b/framework/platform/ios/ios_window.mm index 4f1050aac..982b46f68 100644 --- a/framework/platform/ios/ios_window.mm +++ b/framework/platform/ios/ios_window.mm @@ -72,6 +72,11 @@ return 1.0; } +float IosWindow::get_content_scale_factor() const +{ + return [[UIScreen mainScreen] nativeScale]; +} + std::vector IosWindow::get_required_surface_extensions() const { return {VK_EXT_METAL_SURFACE_EXTENSION_NAME}; From db28d7f37b069364317e391b268bf74afb0b908c Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:56:22 -0400 Subject: [PATCH 05/12] Adjust [HPP]Gui::draw() to work with iOS Simulator for vkCmdDrawIndexed() vertex offset limitations --- framework/gui.cpp | 37 ++++++++++++++++++++++++++++--------- framework/gui.h | 5 +++-- framework/hpp_gui.cpp | 35 ++++++++++++++++++++++++++++------- framework/hpp_gui.h | 5 +++-- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/framework/gui.cpp b/framework/gui.cpp index 9314dcd47..8ddcf67ac 100644 --- a/framework/gui.cpp +++ b/framework/gui.cpp @@ -440,7 +440,7 @@ bool Gui::update_buffers() return updated; } -void Gui::update_buffers(CommandBuffer &command_buffer, RenderFrame &render_frame) +BufferAllocationC Gui::update_buffers(CommandBuffer &command_buffer) { ImDrawData *draw_data = ImGui::GetDrawData(); @@ -478,6 +478,8 @@ void Gui::update_buffers(CommandBuffer &command_buffer, RenderFrame &render_fram index_allocation.update(index_data); command_buffer.bind_index_buffer(index_allocation.get_buffer(), index_allocation.get_offset(), VK_INDEX_TYPE_UINT16); + + return vertex_allocation; } void Gui::resize(const uint32_t width, const uint32_t height) const @@ -580,16 +582,22 @@ void Gui::draw(CommandBuffer &command_buffer) // Push constants command_buffer.push_constants(push_transform); + std::vector> vertex_buffers; + std::vector vertex_offsets; + // If a render context is used, then use the frames buffer pools to allocate GUI vertex/index data from if (!explicit_update) { - update_buffers(command_buffer, sample.get_render_context().get_active_frame()); + // Save vertex buffer allocation in case we need to rebind with vertex_offset, e.g. for iOS Simulator + auto vertex_allocation = update_buffers(command_buffer); + vertex_buffers.push_back(vertex_allocation.get_buffer()); + vertex_offsets.push_back(vertex_allocation.get_offset()); } else { - std::vector> buffers; - buffers.push_back(*vertex_buffer); - command_buffer.bind_vertex_buffers(0, buffers, {0}); + vertex_buffers.push_back(*vertex_buffer); + vertex_offsets.push_back(0); + command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); command_buffer.bind_index_buffer(*index_buffer, 0, VK_INDEX_TYPE_UINT16); } @@ -647,7 +655,13 @@ void Gui::draw(CommandBuffer &command_buffer) command_buffer.draw_indexed(cmd->ElemCount, 1, index_offset, vertex_offset, 0); index_offset += cmd->ElemCount; } +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + // iOS Simulator does not support vkCmdDrawIndexed() with vertex_offset > 0, so rebind vertex buffer instead + vertex_offsets.back() += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); +#else vertex_offset += cmd_list->VtxBuffer.Size; +#endif } } @@ -677,10 +691,9 @@ void Gui::draw(VkCommandBuffer command_buffer) push_transform = glm::scale(push_transform, glm::vec3(2.0f / io.DisplaySize.x, 2.0f / io.DisplaySize.y, 0.0f)); vkCmdPushConstants(command_buffer, pipeline_layout->get_handle(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &push_transform); - VkDeviceSize offsets[1] = {0}; - - VkBuffer vertex_buffer_handle = vertex_buffer->get_handle(); - vkCmdBindVertexBuffers(command_buffer, 0, 1, &vertex_buffer_handle, offsets); + VkDeviceSize vertex_offsets[1] = {0}; + VkBuffer vertex_buffer_handle = vertex_buffer->get_handle(); + vkCmdBindVertexBuffers(command_buffer, 0, 1, &vertex_buffer_handle, vertex_offsets); VkBuffer index_buffer_handle = index_buffer->get_handle(); vkCmdBindIndexBuffer(command_buffer, index_buffer_handle, 0, VK_INDEX_TYPE_UINT16); @@ -701,7 +714,13 @@ void Gui::draw(VkCommandBuffer command_buffer) vkCmdDrawIndexed(command_buffer, cmd->ElemCount, 1, index_offset, vertex_offset, 0); index_offset += cmd->ElemCount; } +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + // iOS Simulator does not support vkCmdDrawIndexed() with vertex_offset > 0, so rebind vertex buffer instead + vertex_offsets[0] += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + vkCmdBindVertexBuffers(command_buffer, 0, 1, &vertex_buffer_handle, vertex_offsets); +#else vertex_offset += cmd_list->VtxBuffer.Size; +#endif } } diff --git a/framework/gui.h b/framework/gui.h index 2b1daaa7f..340983ed8 100644 --- a/framework/gui.h +++ b/framework/gui.h @@ -256,9 +256,10 @@ class Gui /** * @brief Updates Vulkan buffers - * @param frame Frame to render into + * @param command_buffer Command buffer to draw into + * @return Vertex buffer allocation */ - void update_buffers(CommandBuffer &command_buffer, RenderFrame &render_frame); + BufferAllocationC update_buffers(CommandBuffer &command_buffer); static const double press_time_ms; diff --git a/framework/hpp_gui.cpp b/framework/hpp_gui.cpp index 458ac2cb2..74cc965e1 100644 --- a/framework/hpp_gui.cpp +++ b/framework/hpp_gui.cpp @@ -407,7 +407,7 @@ bool HPPGui::update_buffers() return updated; } -void HPPGui::update_buffers(vkb::core::HPPCommandBuffer &command_buffer) const +BufferAllocationCpp HPPGui::update_buffers(vkb::core::HPPCommandBuffer &command_buffer) const { ImDrawData *draw_data = ImGui::GetDrawData(); vkb::rendering::HPPRenderFrame &render_frame = sample.get_render_context().get_active_frame(); @@ -439,6 +439,8 @@ void HPPGui::update_buffers(vkb::core::HPPCommandBuffer &command_buffer) const index_allocation.update(index_data); command_buffer.bind_index_buffer(index_allocation.get_buffer(), index_allocation.get_offset(), vk::IndexType::eUint16); + + return vertex_allocation; } void HPPGui::resize(uint32_t width, uint32_t height) const @@ -537,16 +539,22 @@ void HPPGui::draw(vkb::core::HPPCommandBuffer &command_buffer) // Push constants command_buffer.push_constants(push_transform); + std::vector> vertex_buffers; + std::vector vertex_offsets; + // If a render context is used, then use the frames buffer pools to allocate GUI vertex/index data from if (!explicit_update) { - update_buffers(command_buffer); + // Save vertex buffer allocation in case we need to rebind with vertex_offset, e.g. for iOS Simulator + auto vertex_allocation = update_buffers(command_buffer); + vertex_buffers.push_back(vertex_allocation.get_buffer()); + vertex_offsets.push_back(vertex_allocation.get_offset()); } else { - std::vector> buffers; - buffers.push_back(*vertex_buffer); - command_buffer.bind_vertex_buffers(0, buffers, {0}); + vertex_buffers.push_back(*vertex_buffer); + vertex_offsets.push_back(0); + command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); command_buffer.bind_index_buffer(*index_buffer, 0, vk::IndexType::eUint16); } @@ -604,7 +612,13 @@ void HPPGui::draw(vkb::core::HPPCommandBuffer &command_buffer) command_buffer.draw_indexed(cmd->ElemCount, 1, index_offset, vertex_offset, 0); index_offset += cmd->ElemCount; } +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + // iOS Simulator does not support vkCmdDrawIndexed() with vertex_offset > 0, so rebind vertex buffer instead + vertex_offsets.back() += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); +#else vertex_offset += cmd_list->VtxBuffer.Size; +#endif } } @@ -630,8 +644,9 @@ void HPPGui::draw(vk::CommandBuffer command_buffer) const glm::mat4 push_transform = glm::scale(glm::translate(glm::mat4(1.0f), glm::vec3(-1.0f, -1.0f, 0.0f)), glm::vec3(2.0f / io.DisplaySize.x, 2.0f / io.DisplaySize.y, 0.0f)); command_buffer.pushConstants(pipeline_layout->get_handle(), vk::ShaderStageFlagBits::eVertex, 0, push_transform); - vk::DeviceSize offset = 0; - command_buffer.bindVertexBuffers(0, vertex_buffer->get_handle(), offset); + vk::DeviceSize vertex_offsets[1] = {0}; + vk::Buffer vertex_buffer_handle = vertex_buffer->get_handle(); + command_buffer.bindVertexBuffers(0, vertex_buffer_handle, vertex_offsets); command_buffer.bindIndexBuffer(index_buffer->get_handle(), 0, vk::IndexType::eUint16); @@ -653,7 +668,13 @@ void HPPGui::draw(vk::CommandBuffer command_buffer) const command_buffer.drawIndexed(cmd->ElemCount, 1, index_offset, vertex_offset, 0); index_offset += cmd->ElemCount; } +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + // iOS Simulator does not support vkCmdDrawIndexed() with vertex_offset > 0, so rebind vertex buffer instead + vertex_offsets[0] += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + command_buffer.bindVertexBuffers(0, vertex_buffer_handle, vertex_offsets); +#else vertex_offset += cmd_list->VtxBuffer.Size; +#endif } } diff --git a/framework/hpp_gui.h b/framework/hpp_gui.h index d45cc159b..446717646 100644 --- a/framework/hpp_gui.h +++ b/framework/hpp_gui.h @@ -223,9 +223,10 @@ class HPPGui private: /** * @brief Updates Vulkan buffers - * @param frame Frame to render into + * @param command_buffer Command buffer to draw into + * @return Vertex buffer allocation */ - void update_buffers(vkb::core::HPPCommandBuffer &command_buffer) const; + BufferAllocationCpp update_buffers(vkb::core::HPPCommandBuffer &command_buffer) const; private: /** From 059527d384a68495836335cffb9860687bdb0da0 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:42:28 -0400 Subject: [PATCH 06/12] Initialize pipelines to null handles for better startup error recovery in oit* samples --- .../api/hpp_oit_linked_lists/hpp_oit_linked_lists.h | 10 +++++----- samples/api/oit_depth_peeling/oit_depth_peeling.h | 12 ++++++------ samples/api/oit_linked_lists/oit_linked_lists.h | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/samples/api/hpp_oit_linked_lists/hpp_oit_linked_lists.h b/samples/api/hpp_oit_linked_lists/hpp_oit_linked_lists.h index c5cc7c5c1..f6b3f8398 100644 --- a/samples/api/hpp_oit_linked_lists/hpp_oit_linked_lists.h +++ b/samples/api/hpp_oit_linked_lists/hpp_oit_linked_lists.h @@ -100,16 +100,16 @@ class HPPOITLinkedLists : public HPPApiVulkanSample glm::uint fragment_max_count = 0U; vk::RenderPass gather_render_pass = nullptr; - vk::Framebuffer gather_framebuffer; + vk::Framebuffer gather_framebuffer = nullptr; vk::DescriptorSetLayout descriptor_set_layout = nullptr; vk::DescriptorPool descriptor_pool = nullptr; vk::DescriptorSet descriptor_set = nullptr; - vk::PipelineLayout pipeline_layout = nullptr; - vk::Pipeline gather_pipeline; - vk::Pipeline background_pipeline; - vk::Pipeline combine_pipeline; + vk::PipelineLayout pipeline_layout = nullptr; + vk::Pipeline gather_pipeline = nullptr; + vk::Pipeline background_pipeline = nullptr; + vk::Pipeline combine_pipeline = nullptr; bool sort_fragments = true; bool camera_auto_rotation = false; diff --git a/samples/api/oit_depth_peeling/oit_depth_peeling.h b/samples/api/oit_depth_peeling/oit_depth_peeling.h index 80a1ad801..ef8d3ad48 100644 --- a/samples/api/oit_depth_peeling/oit_depth_peeling.h +++ b/samples/api/oit_depth_peeling/oit_depth_peeling.h @@ -93,12 +93,12 @@ class OITDepthPeeling : public ApiVulkanSample VkDescriptorPool descriptor_pool = VK_NULL_HANDLE; - VkPipelineLayout gather_pipeline_layout; - VkPipeline gather_first_pipeline; - VkPipeline gather_pipeline; - VkPipelineLayout combine_pipeline_layout; - VkPipeline combine_pipeline; - VkPipeline background_pipeline; + VkPipelineLayout gather_pipeline_layout = VK_NULL_HANDLE; + VkPipeline gather_first_pipeline = VK_NULL_HANDLE; + VkPipeline gather_pipeline = VK_NULL_HANDLE; + VkPipelineLayout combine_pipeline_layout = VK_NULL_HANDLE; + VkPipeline combine_pipeline = VK_NULL_HANDLE; + VkPipeline background_pipeline = VK_NULL_HANDLE; int32_t camera_auto_rotation = false; float background_grayscale = 0.3f; diff --git a/samples/api/oit_linked_lists/oit_linked_lists.h b/samples/api/oit_linked_lists/oit_linked_lists.h index 4c1cc59b7..e55bf6eff 100644 --- a/samples/api/oit_linked_lists/oit_linked_lists.h +++ b/samples/api/oit_linked_lists/oit_linked_lists.h @@ -102,10 +102,10 @@ class OITLinkedLists : public ApiVulkanSample VkDescriptorPool descriptor_pool = VK_NULL_HANDLE; VkDescriptorSet descriptor_set = VK_NULL_HANDLE; - VkPipelineLayout pipeline_layout; - VkPipeline gather_pipeline; - VkPipeline background_pipeline; - VkPipeline combine_pipeline; + VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; + VkPipeline gather_pipeline = VK_NULL_HANDLE; + VkPipeline background_pipeline = VK_NULL_HANDLE; + VkPipeline combine_pipeline = VK_NULL_HANDLE; int32_t sort_fragments = true; int32_t camera_auto_rotation = false; From cd3ebbc5c2c1d47cd35d3bb56d9ae9f46c2387dd Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:46:48 -0400 Subject: [PATCH 07/12] Use Vulkan API 1.0 support funcs for Vulkan API 1.0 sample host_image_copy --- samples/extensions/host_image_copy/host_image_copy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/extensions/host_image_copy/host_image_copy.cpp b/samples/extensions/host_image_copy/host_image_copy.cpp index e6828a606..5d47bd018 100644 --- a/samples/extensions/host_image_copy/host_image_copy.cpp +++ b/samples/extensions/host_image_copy/host_image_copy.cpp @@ -100,7 +100,7 @@ void HostImageCopy::load_texture() VkFormatProperties2 format_properties_2{}; format_properties_2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; format_properties_2.pNext = &format_properties_3; - vkGetPhysicalDeviceFormatProperties2(get_device().get_gpu().get_handle(), image_format, &format_properties_2); + vkGetPhysicalDeviceFormatProperties2KHR(get_device().get_gpu().get_handle(), image_format, &format_properties_2); if ((format_properties_3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0) { From 35c2ab16512027874f27204b1a8d26016ee68795 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Sat, 21 Sep 2024 00:07:27 -0400 Subject: [PATCH 08/12] Disable Metal Arg Buffers on iOS Simulator for samples: layout_transitions, pipeline_barriers, subpasses --- .../layout_transitions/layout_transitions.cpp | 21 +++++++++++++++++++ .../pipeline_barriers/pipeline_barriers.cpp | 21 +++++++++++++++++++ samples/performance/subpasses/subpasses.cpp | 21 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/samples/performance/layout_transitions/layout_transitions.cpp b/samples/performance/layout_transitions/layout_transitions.cpp index 505f05f40..adef27483 100644 --- a/samples/performance/layout_transitions/layout_transitions.cpp +++ b/samples/performance/layout_transitions/layout_transitions.cpp @@ -36,6 +36,27 @@ LayoutTransitions::LayoutTransitions() config.insert(0, reinterpret_cast(layout_transition_type), LayoutTransitionType::UNDEFINED); config.insert(1, reinterpret_cast(layout_transition_type), LayoutTransitionType::LAST_LAYOUT); + +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + // On iOS Simulator use layer setting to disable MoltenVK Metal argument buffers + add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); + + VkLayerSettingEXT layerSetting; + layerSetting.pLayerName = "MoltenVK"; + layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; + layerSetting.type = VK_LAYER_SETTING_TYPE_INT32_EXT; + layerSetting.valueCount = 1; + + // Make this static so layer setting reference remains valid after leaving constructor scope + static const int32_t useMetalArgumentBuffers = 0; + layerSetting.pValues = &useMetalArgumentBuffers; + + add_layer_setting(layerSetting); + + // On iOS Simulator also set environment variable as fallback in case layer settings not available at runtime with older SDKs + // Will not work in batch mode, but is the best we can do short of using the deprecated MoltenVK private config API + setenv("MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", "0", 1); +#endif } bool LayoutTransitions::prepare(const vkb::ApplicationOptions &options) diff --git a/samples/performance/pipeline_barriers/pipeline_barriers.cpp b/samples/performance/pipeline_barriers/pipeline_barriers.cpp index a7859c2c8..49ff7e31b 100644 --- a/samples/performance/pipeline_barriers/pipeline_barriers.cpp +++ b/samples/performance/pipeline_barriers/pipeline_barriers.cpp @@ -38,6 +38,27 @@ PipelineBarriers::PipelineBarriers() config.insert(0, reinterpret_cast(dependency_type), DependencyType::BOTTOM_TO_TOP); config.insert(1, reinterpret_cast(dependency_type), DependencyType::FRAG_TO_VERT); config.insert(2, reinterpret_cast(dependency_type), DependencyType::FRAG_TO_FRAG); + +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + // On iOS Simulator use layer setting to disable MoltenVK Metal argument buffers + add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); + + VkLayerSettingEXT layerSetting; + layerSetting.pLayerName = "MoltenVK"; + layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; + layerSetting.type = VK_LAYER_SETTING_TYPE_INT32_EXT; + layerSetting.valueCount = 1; + + // Make this static so layer setting reference remains valid after leaving constructor scope + static const int32_t useMetalArgumentBuffers = 0; + layerSetting.pValues = &useMetalArgumentBuffers; + + add_layer_setting(layerSetting); + + // On iOS Simulator also set environment variable as fallback in case layer settings not available at runtime with older SDKs + // Will not work in batch mode, but is the best we can do short of using the deprecated MoltenVK private config API + setenv("MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", "0", 1); +#endif } bool PipelineBarriers::prepare(const vkb::ApplicationOptions &options) diff --git a/samples/performance/subpasses/subpasses.cpp b/samples/performance/subpasses/subpasses.cpp index 0d5444d36..d258b1175 100644 --- a/samples/performance/subpasses/subpasses.cpp +++ b/samples/performance/subpasses/subpasses.cpp @@ -50,6 +50,27 @@ Subpasses::Subpasses() config.insert(3, configs[Config::RenderTechnique].value, 0); config.insert(3, configs[Config::TransientAttachments].value, 0); config.insert(3, configs[Config::GBufferSize].value, 1); + +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + // On iOS Simulator use layer setting to disable MoltenVK Metal argument buffers + add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); + + VkLayerSettingEXT layerSetting; + layerSetting.pLayerName = "MoltenVK"; + layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; + layerSetting.type = VK_LAYER_SETTING_TYPE_INT32_EXT; + layerSetting.valueCount = 1; + + // Make this static so layer setting reference remains valid after leaving constructor scope + static const int32_t useMetalArgumentBuffers = 0; + layerSetting.pValues = &useMetalArgumentBuffers; + + add_layer_setting(layerSetting); + + // On iOS Simulator also set environment variable as fallback in case layer settings not available at runtime with older SDKs + // Will not work in batch mode, but is the best we can do short of using the deprecated MoltenVK private config API + setenv("MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", "0", 1); +#endif } std::unique_ptr Subpasses::create_render_target(vkb::core::Image &&swapchain_image) From cf483bf4e0b8b8cdc1a1742a7d8bc50d856be096 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:21:05 -0400 Subject: [PATCH 09/12] Make sure [HPP]Gui::update_buffers always returns a BufferAllocationC[pp] --- framework/gui.cpp | 18 ++++++++++++------ framework/hpp_gui.cpp | 16 +++++++++++----- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/framework/gui.cpp b/framework/gui.cpp index 8ddcf67ac..fef6663f3 100644 --- a/framework/gui.cpp +++ b/framework/gui.cpp @@ -446,7 +446,7 @@ BufferAllocationC Gui::update_buffers(CommandBuffer &command_buffer) if (!draw_data) { - return; + return BufferAllocationC{}; } size_t vertex_buffer_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); @@ -454,7 +454,7 @@ BufferAllocationC Gui::update_buffers(CommandBuffer &command_buffer) if ((vertex_buffer_size == 0) || (index_buffer_size == 0)) { - return; + return BufferAllocationC{}; } std::vector vertex_data(vertex_buffer_size); @@ -590,8 +590,11 @@ void Gui::draw(CommandBuffer &command_buffer) { // Save vertex buffer allocation in case we need to rebind with vertex_offset, e.g. for iOS Simulator auto vertex_allocation = update_buffers(command_buffer); - vertex_buffers.push_back(vertex_allocation.get_buffer()); - vertex_offsets.push_back(vertex_allocation.get_offset()); + if (!vertex_allocation.empty()) + { + vertex_buffers.push_back(vertex_allocation.get_buffer()); + vertex_offsets.push_back(vertex_allocation.get_offset()); + } } else { @@ -657,8 +660,11 @@ void Gui::draw(CommandBuffer &command_buffer) } #if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR // iOS Simulator does not support vkCmdDrawIndexed() with vertex_offset > 0, so rebind vertex buffer instead - vertex_offsets.back() += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); - command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); + if (!vertex_offsets.empty()) + { + vertex_offsets.back() += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); + } #else vertex_offset += cmd_list->VtxBuffer.Size; #endif diff --git a/framework/hpp_gui.cpp b/framework/hpp_gui.cpp index 74cc965e1..7b9d97878 100644 --- a/framework/hpp_gui.cpp +++ b/framework/hpp_gui.cpp @@ -414,7 +414,7 @@ BufferAllocationCpp HPPGui::update_buffers(vkb::core::HPPCommandBuffer &command_ if (!draw_data || (draw_data->TotalVtxCount == 0) || (draw_data->TotalIdxCount == 0)) { - return; + return BufferAllocationCpp{}; } size_t vertex_buffer_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); @@ -547,8 +547,11 @@ void HPPGui::draw(vkb::core::HPPCommandBuffer &command_buffer) { // Save vertex buffer allocation in case we need to rebind with vertex_offset, e.g. for iOS Simulator auto vertex_allocation = update_buffers(command_buffer); - vertex_buffers.push_back(vertex_allocation.get_buffer()); - vertex_offsets.push_back(vertex_allocation.get_offset()); + if (!vertex_allocation.empty()) + { + vertex_buffers.push_back(vertex_allocation.get_buffer()); + vertex_offsets.push_back(vertex_allocation.get_offset()); + } } else { @@ -614,8 +617,11 @@ void HPPGui::draw(vkb::core::HPPCommandBuffer &command_buffer) } #if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR // iOS Simulator does not support vkCmdDrawIndexed() with vertex_offset > 0, so rebind vertex buffer instead - vertex_offsets.back() += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); - command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); + if (!vertex_offsets.empty()) + { + vertex_offsets.back() += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); + command_buffer.bind_vertex_buffers(0, vertex_buffers, vertex_offsets); + } #else vertex_offset += cmd_list->VtxBuffer.Size; #endif From 431ccf206b3bde281ade0549056fc60621bd3cb6 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:32:23 -0400 Subject: [PATCH 10/12] Assert valid render context before calling render() within [HPP]ApiVulkanSample::update() --- framework/api_vulkan_sample.cpp | 7 ++----- framework/hpp_api_vulkan_sample.cpp | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/framework/api_vulkan_sample.cpp b/framework/api_vulkan_sample.cpp index f8431491f..82c8c8691 100644 --- a/framework/api_vulkan_sample.cpp +++ b/framework/api_vulkan_sample.cpp @@ -92,11 +92,8 @@ void ApiVulkanSample::update(float delta_time) view_changed(); } - if (has_render_context()) - { - render(delta_time); - } - + assert(has_render_context()); + render(delta_time); camera.update(delta_time); if (camera.moving()) { diff --git a/framework/hpp_api_vulkan_sample.cpp b/framework/hpp_api_vulkan_sample.cpp index fb8b97735..b71832234 100644 --- a/framework/hpp_api_vulkan_sample.cpp +++ b/framework/hpp_api_vulkan_sample.cpp @@ -87,11 +87,8 @@ void HPPApiVulkanSample::update(float delta_time) view_changed(); } - if (has_render_context()) - { - render(delta_time); - } - + assert(has_render_context()); + render(delta_time); camera.update(delta_time); if (camera.moving()) { From ae5e98d0389a2ce85180d48a2ee630e416a143d1 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Mon, 23 Sep 2024 12:13:54 -0400 Subject: [PATCH 11/12] Revert API 1.1 support func change in sample host_image_copy to relocate in a separate PR --- samples/extensions/host_image_copy/host_image_copy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/extensions/host_image_copy/host_image_copy.cpp b/samples/extensions/host_image_copy/host_image_copy.cpp index 5d47bd018..e6828a606 100644 --- a/samples/extensions/host_image_copy/host_image_copy.cpp +++ b/samples/extensions/host_image_copy/host_image_copy.cpp @@ -100,7 +100,7 @@ void HostImageCopy::load_texture() VkFormatProperties2 format_properties_2{}; format_properties_2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; format_properties_2.pNext = &format_properties_3; - vkGetPhysicalDeviceFormatProperties2KHR(get_device().get_gpu().get_handle(), image_format, &format_properties_2); + vkGetPhysicalDeviceFormatProperties2(get_device().get_gpu().get_handle(), image_format, &format_properties_2); if ((format_properties_3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0) { From 2af1107e5dedd25710cfbdd1e3c7c533abf0c3d9 Mon Sep 17 00:00:00 2001 From: SRSaunders <82544213+SRSaunders@users.noreply.github.com> Date: Mon, 23 Sep 2024 12:21:09 -0400 Subject: [PATCH 12/12] Revert Metal Arg Buffers change on iOS Simulator for samples: layout_transitions, pipeline_barriers, subpasses --- .../layout_transitions/layout_transitions.cpp | 21 ------------------- .../pipeline_barriers/pipeline_barriers.cpp | 21 ------------------- samples/performance/subpasses/subpasses.cpp | 21 ------------------- 3 files changed, 63 deletions(-) diff --git a/samples/performance/layout_transitions/layout_transitions.cpp b/samples/performance/layout_transitions/layout_transitions.cpp index adef27483..505f05f40 100644 --- a/samples/performance/layout_transitions/layout_transitions.cpp +++ b/samples/performance/layout_transitions/layout_transitions.cpp @@ -36,27 +36,6 @@ LayoutTransitions::LayoutTransitions() config.insert(0, reinterpret_cast(layout_transition_type), LayoutTransitionType::UNDEFINED); config.insert(1, reinterpret_cast(layout_transition_type), LayoutTransitionType::LAST_LAYOUT); - -#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR - // On iOS Simulator use layer setting to disable MoltenVK Metal argument buffers - add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); - - VkLayerSettingEXT layerSetting; - layerSetting.pLayerName = "MoltenVK"; - layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; - layerSetting.type = VK_LAYER_SETTING_TYPE_INT32_EXT; - layerSetting.valueCount = 1; - - // Make this static so layer setting reference remains valid after leaving constructor scope - static const int32_t useMetalArgumentBuffers = 0; - layerSetting.pValues = &useMetalArgumentBuffers; - - add_layer_setting(layerSetting); - - // On iOS Simulator also set environment variable as fallback in case layer settings not available at runtime with older SDKs - // Will not work in batch mode, but is the best we can do short of using the deprecated MoltenVK private config API - setenv("MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", "0", 1); -#endif } bool LayoutTransitions::prepare(const vkb::ApplicationOptions &options) diff --git a/samples/performance/pipeline_barriers/pipeline_barriers.cpp b/samples/performance/pipeline_barriers/pipeline_barriers.cpp index 49ff7e31b..a7859c2c8 100644 --- a/samples/performance/pipeline_barriers/pipeline_barriers.cpp +++ b/samples/performance/pipeline_barriers/pipeline_barriers.cpp @@ -38,27 +38,6 @@ PipelineBarriers::PipelineBarriers() config.insert(0, reinterpret_cast(dependency_type), DependencyType::BOTTOM_TO_TOP); config.insert(1, reinterpret_cast(dependency_type), DependencyType::FRAG_TO_VERT); config.insert(2, reinterpret_cast(dependency_type), DependencyType::FRAG_TO_FRAG); - -#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR - // On iOS Simulator use layer setting to disable MoltenVK Metal argument buffers - add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); - - VkLayerSettingEXT layerSetting; - layerSetting.pLayerName = "MoltenVK"; - layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; - layerSetting.type = VK_LAYER_SETTING_TYPE_INT32_EXT; - layerSetting.valueCount = 1; - - // Make this static so layer setting reference remains valid after leaving constructor scope - static const int32_t useMetalArgumentBuffers = 0; - layerSetting.pValues = &useMetalArgumentBuffers; - - add_layer_setting(layerSetting); - - // On iOS Simulator also set environment variable as fallback in case layer settings not available at runtime with older SDKs - // Will not work in batch mode, but is the best we can do short of using the deprecated MoltenVK private config API - setenv("MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", "0", 1); -#endif } bool PipelineBarriers::prepare(const vkb::ApplicationOptions &options) diff --git a/samples/performance/subpasses/subpasses.cpp b/samples/performance/subpasses/subpasses.cpp index d258b1175..0d5444d36 100644 --- a/samples/performance/subpasses/subpasses.cpp +++ b/samples/performance/subpasses/subpasses.cpp @@ -50,27 +50,6 @@ Subpasses::Subpasses() config.insert(3, configs[Config::RenderTechnique].value, 0); config.insert(3, configs[Config::TransientAttachments].value, 0); config.insert(3, configs[Config::GBufferSize].value, 1); - -#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR - // On iOS Simulator use layer setting to disable MoltenVK Metal argument buffers - add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); - - VkLayerSettingEXT layerSetting; - layerSetting.pLayerName = "MoltenVK"; - layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; - layerSetting.type = VK_LAYER_SETTING_TYPE_INT32_EXT; - layerSetting.valueCount = 1; - - // Make this static so layer setting reference remains valid after leaving constructor scope - static const int32_t useMetalArgumentBuffers = 0; - layerSetting.pValues = &useMetalArgumentBuffers; - - add_layer_setting(layerSetting); - - // On iOS Simulator also set environment variable as fallback in case layer settings not available at runtime with older SDKs - // Will not work in batch mode, but is the best we can do short of using the deprecated MoltenVK private config API - setenv("MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", "0", 1); -#endif } std::unique_ptr Subpasses::create_render_target(vkb::core::Image &&swapchain_image)