From 9344ef1396b4e80b0166dbd4e8ce1ac88ef18869 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Mon, 17 Jul 2023 21:50:00 +0300 Subject: [PATCH 01/64] Optionally enable dynamic state extension in Vulkan::Device only when it is supported --- .../Include/Methane/Graphics/Vulkan/Device.h | 6 +- .../Methane/Graphics/Vulkan/Device.cpp | 59 +++++++++---------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h index 1c6167ec3..ce834050e 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h @@ -99,6 +99,8 @@ class Device final const vk::PhysicalDevice& GetNativePhysicalDevice() const noexcept { return m_vk_physical_device; } const vk::Device& GetNativeDevice() const noexcept { return m_vk_unique_device.get(); } const vk::QueueFamilyProperties& GetNativeQueueFamilyProperties(uint32_t queue_family_index) const; + bool IsExtensionSupported(std::string_view required_extension) const; + bool IsDynamicStateSupported() const noexcept { return m_is_dynamic_state_supported; } private: using QueueFamilyReservationByType = std::map>; @@ -107,9 +109,11 @@ class Device final std::vector& reserved_queues_count_per_family, const vk::SurfaceKHR& vk_surface = vk::SurfaceKHR()); - bool IsExtensionSupported(const std::vector& required_extensions) const; + Rhi::DeviceFeatureMask GetSupportedFeatures() const; vk::PhysicalDevice m_vk_physical_device; + const std::set m_supported_extension_names; + const bool m_is_dynamic_state_supported = false; std::vector m_vk_queue_family_properties; vk::UniqueDevice m_vk_unique_device; QueueFamilyReservationByType m_queue_family_reservation_by_type; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp index 89085c5e6..78a574ac8 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp @@ -52,6 +52,8 @@ namespace Methane::Graphics::Vulkan //#define VK_GOOGLE_SPIRV_EXTENSIONS_ENABLED //#endif +#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset" + static const std::vector g_common_device_extensions{ VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, #ifdef METHANE_GPU_INSTRUMENTATION_ENABLED @@ -66,14 +68,6 @@ static const std::vector g_common_device_extensions{ #endif }; -static const std::vector g_render_device_extensions{ - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME -}; - -static const std::vector g_present_device_extensions = { - VK_KHR_SWAPCHAIN_EXTENSION_NAME -}; - template std::optional FindQueueFamily(const std::vector& vk_queue_family_properties, vk::QueueFlags queue_flags, uint32_t queues_count, @@ -154,16 +148,16 @@ static vk::QueueFlags GetQueueFlagsByType(Rhi::CommandListType cmd_list_type) } } -static bool IsDeviceExtensionSupported(const vk::PhysicalDevice& vk_physical_device, const std::vector& required_extensions) +static std::set GetDeviceSupportedExtensionNames(const vk::PhysicalDevice& vk_physical_device) { META_FUNCTION_TASK(); - std::set extensions(required_extensions.begin(), required_extensions.end()); + std::set supported_extensions; const std::vector vk_device_extension_properties = vk_physical_device.enumerateDeviceExtensionProperties(); for(const vk::ExtensionProperties& vk_extension_props : vk_device_extension_properties) { - extensions.erase(vk_extension_props.extensionName); + supported_extensions.insert(vk_extension_props.extensionName); } - return extensions.empty(); + return supported_extensions; } QueueFamilyReservation::QueueFamilyReservation(uint32_t family_index, vk::QueueFlags queue_flags, uint32_t queues_count, bool can_present_to_window) @@ -218,26 +212,17 @@ void QueueFamilyReservation::IncrementQueuesCount(uint32_t extra_queues_count) n m_priorities.resize(m_queues_count, 0.F); } -Rhi::DeviceFeatureMask Device::GetSupportedFeatures(const vk::PhysicalDevice& vk_physical_device) -{ - META_FUNCTION_TASK(); - vk::PhysicalDeviceFeatures vk_device_features = vk_physical_device.getFeatures(); - Rhi::DeviceFeatureMask device_features; - device_features.SetBit(Rhi::DeviceFeature::PresentToWindow, IsDeviceExtensionSupported(vk_physical_device, g_present_device_extensions)); - device_features.SetBit(Rhi::DeviceFeature::AnisotropicFiltering, vk_device_features.samplerAnisotropy); - device_features.SetBit(Rhi::DeviceFeature::ImageCubeArray, vk_device_features.imageCubeArray); - return device_features; -} - Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKHR& vk_surface, const Capabilities& capabilities) : Base::Device(vk_physical_device.getProperties().deviceName, IsSoftwarePhysicalDevice(vk_physical_device), capabilities) , m_vk_physical_device(vk_physical_device) + , m_supported_extension_names(GetDeviceSupportedExtensionNames(vk_physical_device)) + , m_is_dynamic_state_supported(IsExtensionSupported(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) , m_vk_queue_family_properties(vk_physical_device.getQueueFamilyProperties()) { META_FUNCTION_TASK(); - if (const Rhi::DeviceFeatureMask device_supported_features = Device::GetSupportedFeatures(vk_physical_device); + if (const Rhi::DeviceFeatureMask device_supported_features = GetSupportedFeatures(); !device_supported_features.HasBits(capabilities.features)) throw IncompatibleException("Supported Device features are incompatible with the required capabilities"); @@ -264,14 +249,17 @@ Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKH { if (capabilities.features.HasBit(Rhi::DeviceFeature::PresentToWindow)) { - enabled_extension_names.insert(enabled_extension_names.end(), g_present_device_extensions.begin(), g_present_device_extensions.end()); + enabled_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + } + if (m_is_dynamic_state_supported) + { + enabled_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } - enabled_extension_names.insert(enabled_extension_names.end(), g_render_device_extensions.begin(), g_render_device_extensions.end()); } - if (IsExtensionSupported({ "VK_KHR_portability_subset" })) + if (IsExtensionSupported(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) { - enabled_extension_names.emplace_back("VK_KHR_portability_subset"); + enabled_extension_names.emplace_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); } std::vector raw_enabled_extension_names; @@ -327,10 +315,10 @@ bool Device::SetName(std::string_view name) return true; } -bool Device::IsExtensionSupported(const std::vector& required_extensions) const +bool Device::IsExtensionSupported(std::string_view required_extension) const { META_FUNCTION_TASK(); - return IsDeviceExtensionSupported(m_vk_physical_device, required_extensions); + return m_supported_extension_names.count(required_extension); } const QueueFamilyReservation* Device::GetQueueFamilyReservationPtr(Rhi::CommandListType cmd_list_type) const noexcept @@ -418,4 +406,15 @@ void Device::ReserveQueueFamily(Rhi::CommandListType cmd_list_type, uint32_t que *vk_queue_family_index, queues_count, magic_enum::enum_name(cmd_list_type)); } +Rhi::DeviceFeatureMask Device::GetSupportedFeatures() const +{ + META_FUNCTION_TASK(); + vk::PhysicalDeviceFeatures vk_device_features = m_vk_physical_device.getFeatures(); + Rhi::DeviceFeatureMask device_features; + device_features.SetBit(Rhi::DeviceFeature::PresentToWindow, IsExtensionSupported(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); + device_features.SetBit(Rhi::DeviceFeature::AnisotropicFiltering, vk_device_features.samplerAnisotropy); + device_features.SetBit(Rhi::DeviceFeature::ImageCubeArray, vk_device_features.imageCubeArray); + return device_features; +} + } // namespace Methane::Graphics::Vulkan From 514f2f58415e759ab89ed1e719d356924fd6183c Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Tue, 18 Jul 2023 22:28:15 +0300 Subject: [PATCH 02/64] Add monolithic Pipeline state support for Vulkan when dynamic state extension is not available --- .../Data/Types/Include/Methane/Data/Rect.hpp | 5 + .../Methane/Graphics/Base/RenderCommandList.h | 50 +++---- .../Graphics/Base/RenderCommandList.cpp | 4 +- .../Include/Methane/Graphics/RHI/IViewState.h | 1 + .../Methane/Graphics/RHI/IViewState.cpp | 14 +- .../Methane/Graphics/Vulkan/RenderState.h | 32 ++++- .../Methane/Graphics/Vulkan/ViewState.h | 3 + .../Graphics/Vulkan/RenderCommandList.cpp | 16 +-- .../Methane/Graphics/Vulkan/RenderState.cpp | 134 +++++++++++++----- .../Methane/Graphics/Vulkan/ViewState.cpp | 8 +- .../Types/Include/Methane/Graphics/Volume.hpp | 5 + 11 files changed, 186 insertions(+), 86 deletions(-) diff --git a/Modules/Data/Types/Include/Methane/Data/Rect.hpp b/Modules/Data/Types/Include/Methane/Data/Rect.hpp index 789a03bf2..269e5376b 100644 --- a/Modules/Data/Types/Include/Methane/Data/Rect.hpp +++ b/Modules/Data/Types/Include/Methane/Data/Rect.hpp @@ -388,6 +388,11 @@ struct Rect return std::tie(origin, size) != std::tie(other.origin, other.size); } + bool operator<(const Rect& other) const noexcept + { + return std::tie(origin, size) < std::tie(other.origin, other.size); + } + template std::enable_if_t, Rect> operator*(M multiplier) const noexcept(std::is_unsigned_v) { diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h index 5a9b44eef..185c264f6 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h @@ -49,29 +49,31 @@ class BufferSet; class Buffer; class Texture; +struct RenderDrawingState +{ + enum class Change : uint32_t + { + PrimitiveType + }; + + using ChangeMask = Data::EnumMask; + + Ptrs render_pass_attachment_ptrs; + Ptr render_state_ptr; + Ptr vertex_buffer_set_ptr; + Ptr index_buffer_ptr; + Opt primitive_type_opt; + ViewState* view_state_ptr = nullptr; + Rhi::RenderStateGroupMask render_state_groups; + ChangeMask changes; +}; + class RenderCommandList : public Rhi::IRenderCommandList , public CommandList { public: - struct DrawingState - { - enum class Change : uint32_t - { - PrimitiveType - }; - - using ChangeMask = Data::EnumMask; - - Ptrs render_pass_attachments_ptr; - Ptr render_state_ptr; - Ptr vertex_buffer_set_ptr; - Ptr index_buffer_ptr; - Opt primitive_type_opt; - ViewState* view_state_ptr = nullptr; - Rhi::RenderStateGroupMask render_state_groups; - ChangeMask changes; - }; + using DrawingState = RenderDrawingState; static Ptr CreateForSynchronization(Rhi::ICommandQueue& cmd_queue); @@ -97,17 +99,17 @@ class RenderCommandList void Draw(Primitive primitive_type, uint32_t vertex_count, uint32_t start_vertex, uint32_t instance_count, uint32_t start_instance) override; - bool HasPass() const noexcept { return !!m_render_pass_ptr; } - RenderPass* GetPassPtr() const noexcept { return m_render_pass_ptr.get(); } - RenderPass& GetPass(); + RenderPass& GetPass(); + RenderPass* GetPassPtr() const noexcept { return m_render_pass_ptr.get(); } + bool HasPass() const noexcept { return !!m_render_pass_ptr; } + const DrawingState& GetDrawingState() const noexcept { return m_drawing_state; } protected: // CommandList overrides void ResetCommandState() override; - DrawingState& GetDrawingState() { return m_drawing_state; } - const DrawingState& GetDrawingState() const { return m_drawing_state; } - bool IsParallel() const { return m_is_parallel; } + DrawingState& GetDrawingState() noexcept { return m_drawing_state; } + bool IsParallel() const noexcept { return m_is_parallel; } inline void UpdateDrawingState(Primitive primitive_type); inline void ValidateDrawVertexBuffers(uint32_t draw_start_vertex, uint32_t draw_vertex_count = 0) const; diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp index 58cc22e3f..1a8f49752 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp @@ -68,7 +68,7 @@ void RenderCommandList::Reset(IDebugGroup* debug_group_ptr) if (m_render_pass_ptr) { META_LOG("{}", static_cast(m_render_pass_ptr->GetPattern().GetSettings())); - m_drawing_state.render_pass_attachments_ptr = m_render_pass_ptr->GetNonFrameBufferAttachmentTextures(); + m_drawing_state.render_pass_attachment_ptrs = m_render_pass_ptr->GetNonFrameBufferAttachmentTextures(); } } @@ -266,7 +266,7 @@ void RenderCommandList::ResetCommandState() CommandList::ResetCommandState(); - m_drawing_state.render_pass_attachments_ptr.clear(); + m_drawing_state.render_pass_attachment_ptrs.clear(); m_drawing_state.render_state_ptr.reset(); m_drawing_state.vertex_buffer_set_ptr.reset(); m_drawing_state.index_buffer_ptr.reset(); diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h index d3857a2c2..f42e48a91 100644 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h @@ -35,6 +35,7 @@ struct ViewSettings [[nodiscard]] bool operator==(const ViewSettings& other) const noexcept; [[nodiscard]] bool operator!=(const ViewSettings& other) const noexcept; + [[nodiscard]] bool operator<(const ViewSettings& other) const noexcept; [[nodiscard]] explicit operator std::string() const; }; diff --git a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IViewState.cpp b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IViewState.cpp index bbcebad98..cef6c872a 100644 --- a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IViewState.cpp +++ b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IViewState.cpp @@ -33,14 +33,22 @@ namespace Methane::Graphics::Rhi bool ViewSettings::operator==(const ViewSettings& other) const noexcept { META_FUNCTION_TASK(); - return viewports == other.viewports && - scissor_rects == other.scissor_rects; + return std::tie(viewports, scissor_rects) == + std::tie(other.viewports, other.scissor_rects); } bool ViewSettings::operator!=(const ViewSettings& other) const noexcept { META_FUNCTION_TASK(); - return !operator==(other); + return std::tie(viewports, scissor_rects) != + std::tie(other.viewports, other.scissor_rects); +} + +bool ViewSettings::operator<(const ViewSettings& other) const noexcept +{ + META_FUNCTION_TASK(); + return std::tie(viewports, scissor_rects) < + std::tie(other.viewports, other.scissor_rects); } ViewSettings::operator std::string() const diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h index 7eda69463..5a2705fa2 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h @@ -23,19 +23,35 @@ Vulkan implementation of the render state interface. #pragma once +#include #include #include +#include + +namespace Methane::Graphics::Rhi +{ +enum class RenderPrimitive; +} + +namespace Methane::Graphics::Base +{ +struct RenderDrawingState; +} + namespace Methane::Graphics::Vulkan { struct IContext; +class ViewState; class RenderState final : public Base::RenderState { public: + static vk::PrimitiveTopology GetVulkanPrimitiveTopology(Rhi::RenderPrimitive primitive_type); + RenderState(const Base::RenderContext& context, const Settings& settings); // IRenderState interface @@ -47,11 +63,21 @@ class RenderState final // IObject interface bool SetName(std::string_view name) override; - const vk::Pipeline& GetNativePipeline() const noexcept { return m_vk_unique_pipeline.get(); } + bool IsNativePipelineDynamic() const noexcept { return m_is_pipeline_dynamic; } + const vk::Pipeline& GetNativePipelineDynamic() const; + const vk::Pipeline& GetNativePipelineMonolithic(const ViewState& viewState, Rhi::RenderPrimitive renderPrimitive); + const vk::Pipeline& GetNativePipelineMonolithic(const Base::RenderDrawingState& drawing_state); private: - const IContext& m_vk_context; - vk::UniquePipeline m_vk_unique_pipeline; + vk::UniquePipeline CreateNativePipeline(const ViewState* viewState = nullptr, Opt renderPrimitive = {}); + + using PipelineId = std::tuple; + using MonolithicPipelineById = std::map; + + const IContext& m_vk_context; + const bool m_is_pipeline_dynamic; + vk::UniquePipeline m_vk_pipeline_dynamic; + MonolithicPipelineById m_vk_pipeline_monolithic_by_id; }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ViewState.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ViewState.h index 60c6bc02d..878dd6fc5 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ViewState.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ViewState.h @@ -50,9 +50,12 @@ class ViewState final const std::vector& GetNativeViewports() const noexcept { return m_vk_viewports; } const std::vector& GetNativeScissorRects() const noexcept { return m_vk_scissor_rects; } + const vk::PipelineViewportStateCreateInfo& GetNativeViewportStateCreateInfo() const noexcept { return m_vk_viewport_state_info; } + private: std::vector m_vk_viewports; std::vector m_vk_scissor_rects; + vk::PipelineViewportStateCreateInfo m_vk_viewport_state_info; }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp index 3621b00e4..cfe2e4d70 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp @@ -48,20 +48,6 @@ Ptr RenderCommandList::CreateForSynchronization(Rhi::IC namespace Methane::Graphics::Vulkan { -vk::PrimitiveTopology GetVulkanPrimitiveTopology(Rhi::RenderPrimitive primitive_type) -{ - META_FUNCTION_TASK(); - switch(primitive_type) - { - case Rhi::RenderPrimitive::Point: return vk::PrimitiveTopology::ePointList; - case Rhi::RenderPrimitive::Line: return vk::PrimitiveTopology::eLineList; - case Rhi::RenderPrimitive::LineStrip: return vk::PrimitiveTopology::eLineStrip; - case Rhi::RenderPrimitive::Triangle: return vk::PrimitiveTopology::eTriangleList; - case Rhi::RenderPrimitive::TriangleStrip: return vk::PrimitiveTopology::eTriangleStrip; - default: META_UNEXPECTED_ARG_RETURN(primitive_type, vk::PrimitiveTopology::ePointList); - } -} - static vk::IndexType GetVulkanIndexTypeByStride(Data::Size index_stride_bytes) { META_FUNCTION_TASK(); @@ -213,7 +199,7 @@ void RenderCommandList::UpdatePrimitiveTopology(Primitive primitive) if (DrawingState& drawing_state = GetDrawingState(); drawing_state.changes.HasAnyBit(DrawingState::Change::PrimitiveType)) { - const vk::PrimitiveTopology vk_primitive_topology = GetVulkanPrimitiveTopology(primitive); + const vk::PrimitiveTopology vk_primitive_topology = RenderState::GetVulkanPrimitiveTopology(primitive); GetNativeCommandBufferDefault().setPrimitiveTopologyEXT(vk_primitive_topology); drawing_state.changes.SetBitOff(DrawingState::Change::PrimitiveType); } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index eccd22ee0..7c559d809 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -28,6 +28,7 @@ Vulkan implementation of the render state interface. #include #include #include +#include #include #include @@ -36,6 +37,7 @@ Vulkan implementation of the render state interface. #include #include +#include namespace Methane::Graphics::Vulkan { @@ -174,9 +176,24 @@ static vk::ColorComponentFlags BlendingColorChannelsToVulkan(Rhi::BlendingColorC return color_component_flags; } +vk::PrimitiveTopology RenderState::GetVulkanPrimitiveTopology(Rhi::RenderPrimitive primitive_type) +{ + META_FUNCTION_TASK(); + switch(primitive_type) + { + case Rhi::RenderPrimitive::Point: return vk::PrimitiveTopology::ePointList; + case Rhi::RenderPrimitive::Line: return vk::PrimitiveTopology::eLineList; + case Rhi::RenderPrimitive::LineStrip: return vk::PrimitiveTopology::eLineStrip; + case Rhi::RenderPrimitive::Triangle: return vk::PrimitiveTopology::eTriangleList; + case Rhi::RenderPrimitive::TriangleStrip: return vk::PrimitiveTopology::eTriangleStrip; + default: META_UNEXPECTED_ARG_RETURN(primitive_type, vk::PrimitiveTopology::ePointList); + } +} + RenderState::RenderState(const Base::RenderContext& context, const Settings& settings) : Base::RenderState(context, settings) , m_vk_context(dynamic_cast(GetRenderContext())) + , m_is_pipeline_dynamic(m_vk_context.GetVulkanDevice().IsDynamicStateSupported()) { META_FUNCTION_TASK(); Reset(settings); @@ -187,6 +204,68 @@ void RenderState::Reset(const Settings& settings) META_FUNCTION_TASK(); Base::RenderState::Reset(settings); + if (m_is_pipeline_dynamic) + { + m_vk_pipeline_dynamic = CreateNativePipeline(); + } + else + { + m_vk_pipeline_monolithic_by_id.clear(); + } +} + +void RenderState::Apply(Base::RenderCommandList& render_command_list, Groups /*state_groups*/) +{ + META_FUNCTION_TASK(); + const auto& vulkan_render_command_list = static_cast(render_command_list); + const vk::Pipeline& vk_pipeline_state = m_is_pipeline_dynamic + ? GetNativePipelineDynamic() + : GetNativePipelineMonolithic(vulkan_render_command_list.GetDrawingState()); + vulkan_render_command_list.GetNativeCommandBufferDefault().bindPipeline(vk::PipelineBindPoint::eGraphics, vk_pipeline_state); +} + +bool RenderState::SetName(std::string_view name) +{ + META_FUNCTION_TASK(); + if (!Base::RenderState::SetName(name)) + return false; + + SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), m_vk_pipeline_dynamic.get(), name); + return true; +} + +const vk::Pipeline& RenderState::GetNativePipelineDynamic() const +{ + META_FUNCTION_TASK(); + META_CHECK_ARG_TRUE_DESCR(m_is_pipeline_dynamic, "dynamic pipeline is not supported by device"); + return m_vk_pipeline_dynamic.get(); +} + +const vk::Pipeline& RenderState::GetNativePipelineMonolithic(const ViewState& view_state, Rhi::RenderPrimitive render_primitive) +{ + META_FUNCTION_TASK(); + const PipelineId pipeline_id = std::tie(view_state.GetSettings(), render_primitive); + const auto pipeline_monolithic_by_id_it = m_vk_pipeline_monolithic_by_id.find(pipeline_id); + if (pipeline_monolithic_by_id_it == m_vk_pipeline_monolithic_by_id.end()) + { + return m_vk_pipeline_monolithic_by_id.try_emplace(pipeline_id, CreateNativePipeline(&view_state, render_primitive)).first->second.get(); + } + return pipeline_monolithic_by_id_it->second.get(); +} + +const vk::Pipeline& RenderState::GetNativePipelineMonolithic(const Base::RenderDrawingState& drawing_state) +{ + META_FUNCTION_TASK(); + META_CHECK_ARG_NOT_NULL_DESCR(drawing_state.view_state_ptr, "view state is not set in render command list drawing state"); + META_CHECK_ARG_TRUE_DESCR(drawing_state.primitive_type_opt.has_value(), "primitive type is not set in render command list drawing state"); + return GetNativePipelineMonolithic(static_cast(*drawing_state.view_state_ptr), drawing_state.primitive_type_opt.value()); +} + +vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state_ptr, Opt render_primitive_opt) +{ + META_FUNCTION_TASK(); + const Settings& settings = GetSettings(); + vk::PipelineRasterizationStateCreateInfo rasterizer_info( vk::PipelineRasterizationStateCreateFlags{}, false, // depthClampEnable @@ -247,19 +326,19 @@ void RenderState::Reset(const Settings& settings) std::transform(settings.blending.render_targets.begin(), settings.blending.render_targets.begin() + blend_attachments_count, std::back_inserter(attachment_blend_states), - [](const Blending::RenderTarget& rt_blending) - { - return vk::PipelineColorBlendAttachmentState( - rt_blending.blend_enabled, - BlendingFactorToVulkan(rt_blending.source_rgb_blend_factor), - BlendingFactorToVulkan(rt_blending.dest_rgb_blend_factor), - BlendingOperationToVulkan(rt_blending.rgb_blend_op), - BlendingFactorToVulkan(rt_blending.source_alpha_blend_factor), - BlendingFactorToVulkan(rt_blending.dest_alpha_blend_factor), - BlendingOperationToVulkan(rt_blending.alpha_blend_op), - BlendingColorChannelsToVulkan(rt_blending.color_write) - ); - } + [](const Blending::RenderTarget& rt_blending) + { + return vk::PipelineColorBlendAttachmentState( + rt_blending.blend_enabled, + BlendingFactorToVulkan(rt_blending.source_rgb_blend_factor), + BlendingFactorToVulkan(rt_blending.dest_rgb_blend_factor), + BlendingOperationToVulkan(rt_blending.rgb_blend_op), + BlendingFactorToVulkan(rt_blending.source_alpha_blend_factor), + BlendingFactorToVulkan(rt_blending.dest_alpha_blend_factor), + BlendingOperationToVulkan(rt_blending.alpha_blend_op), + BlendingColorChannelsToVulkan(rt_blending.color_write) + ); + } ); vk::PipelineColorBlendStateCreateInfo blending_info( @@ -270,15 +349,13 @@ void RenderState::Reset(const Settings& settings) settings.blending_color.AsArray() ); - // Fake state, actual PrimitiveTopology is set dynamically vk::PipelineInputAssemblyStateCreateInfo assembly_info( vk::PipelineInputAssemblyStateCreateFlags{}, - vk::PrimitiveTopology::eTriangleList, + render_primitive_opt ? GetVulkanPrimitiveTopology(*render_primitive_opt) : vk::PrimitiveTopology::eTriangleList, false ); - // Fake viewport state, actual state is set dynamically - vk::PipelineViewportStateCreateInfo viewport_info( + vk::PipelineViewportStateCreateInfo empty_viewport_info( vk::PipelineViewportStateCreateFlags{}, 0, nullptr, 0, nullptr ); @@ -305,36 +382,19 @@ void RenderState::Reset(const Settings& settings) &vk_vertex_input_state_info, &assembly_info, nullptr, // no tesselation support yet - &viewport_info, + view_state_ptr ? &view_state_ptr->GetNativeViewportStateCreateInfo() : &empty_viewport_info, &rasterizer_info, &multisample_info, &depth_stencil_info, &blending_info, - &dynamic_info, + m_is_pipeline_dynamic && !view_state_ptr ? &dynamic_info : nullptr, program.GetNativePipelineLayout(), render_pattern.GetNativeRenderPass() ); auto pipe = m_vk_context.GetVulkanDevice().GetNativeDevice().createGraphicsPipelineUnique(nullptr, vk_pipeline_create_info); META_CHECK_ARG_EQUAL_DESCR(pipe.result, vk::Result::eSuccess, "Vulkan pipeline creation has failed"); - m_vk_unique_pipeline = std::move(pipe.value); -} - -void RenderState::Apply(Base::RenderCommandList& render_command_list, Groups /*state_groups*/) -{ - META_FUNCTION_TASK(); - const auto& vulkan_render_command_list = static_cast(render_command_list); - vulkan_render_command_list.GetNativeCommandBufferDefault().bindPipeline(vk::PipelineBindPoint::eGraphics, GetNativePipeline()); -} - -bool RenderState::SetName(std::string_view name) -{ - META_FUNCTION_TASK(); - if (!Base::RenderState::SetName(name)) - return false; - - SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), m_vk_unique_pipeline.get(), name); - return true; + return std::move(pipe.value); } } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp index 307f06e90..ed55d0c87 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp @@ -91,6 +91,7 @@ ViewState::ViewState(const Settings& settings) : Base::ViewState(settings) , m_vk_viewports(ViewportsToVulkan(settings.viewports)) , m_vk_scissor_rects(ScissorRectsToVulkan(settings.scissor_rects)) + , m_vk_viewport_state_info({}, m_vk_viewports, m_vk_scissor_rects) { } bool ViewState::Reset(const Settings& settings) @@ -99,8 +100,9 @@ bool ViewState::Reset(const Settings& settings) if (!Base::ViewState::Reset(settings)) return false; - m_vk_viewports = ViewportsToVulkan(settings.viewports); - m_vk_scissor_rects = ScissorRectsToVulkan(settings.scissor_rects); + m_vk_viewports = ViewportsToVulkan(settings.viewports); + m_vk_scissor_rects = ScissorRectsToVulkan(settings.scissor_rects); + m_vk_viewport_state_info = vk::PipelineViewportStateCreateInfo({}, m_vk_viewports, m_vk_scissor_rects); return true; } @@ -111,6 +113,7 @@ bool ViewState::SetViewports(const Viewports& viewports) return false; m_vk_viewports = ViewportsToVulkan(GetSettings().viewports); + m_vk_viewport_state_info.setViewports(m_vk_viewports); return true; } @@ -121,6 +124,7 @@ bool ViewState::SetScissorRects(const ScissorRects& scissor_rects) return false; m_vk_scissor_rects = ScissorRectsToVulkan(GetSettings().scissor_rects); + m_vk_viewport_state_info.setScissors(m_vk_scissor_rects); return true; } diff --git a/Modules/Graphics/Types/Include/Methane/Graphics/Volume.hpp b/Modules/Graphics/Types/Include/Methane/Graphics/Volume.hpp index 051838e8e..f277af18b 100644 --- a/Modules/Graphics/Types/Include/Methane/Graphics/Volume.hpp +++ b/Modules/Graphics/Types/Include/Methane/Graphics/Volume.hpp @@ -345,6 +345,11 @@ struct Volume // NOSONAR - class has more than 35 methods return std::tie(origin, size) != std::tie(other.origin, other.size); } + bool operator<(const Volume& other) const noexcept + { + return std::tie(origin, size) < std::tie(other.origin, other.size); + } + template std::enable_if_t, Volume> operator*(M multiplier) const noexcept(std::is_unsigned_v) { From 2079fa65e1313fabd858a01882b015570ed96da2 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Wed, 19 Jul 2023 21:59:22 +0300 Subject: [PATCH 03/64] Deferred applying of the monolithic pipeline state for Vulkan --- .../Methane/Graphics/Base/RenderState.h | 9 +++- .../Graphics/Base/RenderCommandList.cpp | 22 +++++++--- .../Methane/Graphics/Base/RenderState.cpp | 3 +- .../Graphics/Vulkan/RenderCommandList.h | 4 ++ .../Methane/Graphics/Vulkan/RenderState.h | 3 +- .../Graphics/Vulkan/RenderCommandList.cpp | 4 ++ .../Methane/Graphics/Vulkan/RenderState.cpp | 43 +++++++++++++------ .../Methane/Graphics/Vulkan/ViewState.cpp | 6 ++- 8 files changed, 71 insertions(+), 23 deletions(-) diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderState.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderState.h index c1f42ce87..98a94db7d 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderState.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderState.h @@ -38,7 +38,7 @@ class RenderState , public Rhi::IRenderState { public: - RenderState(const RenderContext& context, const Settings& settings); + RenderState(const RenderContext& context, const Settings& settings, bool is_deferred = false); // IRenderState overrides const Settings& GetSettings() const noexcept override { return m_settings; } @@ -48,6 +48,7 @@ class RenderState virtual void Apply(RenderCommandList& command_list, Groups apply_groups) = 0; const RenderContext& GetRenderContext() const noexcept { return m_context; } + bool IsDeferred() const noexcept { return m_is_deferred; } protected: Rhi::IProgram& GetProgram(); @@ -55,6 +56,12 @@ class RenderState private: const RenderContext& m_context; Settings m_settings; + + // Deferred state is applied on first Draw, instead of SetRenderState call + // This is required for Vulkan without dynamic state support (on mobile platforms): + // Vulkan monolithic pipeline state is created by settings of RenderState, ViewState and PrimitiveType + // and is applied on first Draw call when whole state is fully defined + const bool m_is_deferred; }; } // namespace Methane::Graphics::Base diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp index 1a8f49752..67591a27b 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp @@ -111,13 +111,16 @@ void RenderCommandList::SetRenderState(Rhi::IRenderState& render_state, Rhi::Ren changed_states |= ~m_drawing_state.render_state_groups; auto& render_state_base = static_cast(render_state); - render_state_base.Apply(*this, changed_states & state_groups); + if (!render_state_base.IsDeferred()) + { + render_state_base.Apply(*this, changed_states & state_groups); + } Ptr render_state_object_ptr = render_state_base.GetBasePtr(); m_drawing_state.render_state_ptr = std::static_pointer_cast(render_state_object_ptr); m_drawing_state.render_state_groups |= state_groups; - if (render_state_changed) + if (render_state_changed && !render_state_base.IsDeferred()) { RetainResource(render_state_object_ptr); } @@ -280,11 +283,18 @@ void RenderCommandList::UpdateDrawingState(Primitive primitive_type) { META_FUNCTION_TASK(); DrawingState& drawing_state = GetDrawingState(); - if (drawing_state.primitive_type_opt && *drawing_state.primitive_type_opt == primitive_type) - return; + if (!drawing_state.primitive_type_opt || *drawing_state.primitive_type_opt == primitive_type) + { + drawing_state.changes |= DrawingState::Change::PrimitiveType; + drawing_state.primitive_type_opt = primitive_type; + } - drawing_state.changes |= DrawingState::Change::PrimitiveType; - drawing_state.primitive_type_opt = primitive_type; + if (m_drawing_state.render_state_ptr && m_drawing_state.render_state_ptr->IsDeferred()) + { + m_drawing_state.render_state_ptr->Apply(*this, m_drawing_state.render_state_groups); + RetainResource(m_drawing_state.render_state_ptr); + m_drawing_state.render_state_groups = {}; + } } void RenderCommandList::ValidateDrawVertexBuffers(uint32_t draw_start_vertex, uint32_t draw_vertex_count) const diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderState.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderState.cpp index 8dacb8e97..169dc9fe2 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderState.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderState.cpp @@ -30,9 +30,10 @@ Base implementation of the render state interface. namespace Methane::Graphics::Base { -RenderState::RenderState(const RenderContext& context, const Settings& settings) +RenderState::RenderState(const RenderContext& context, const Settings& settings, bool is_deferred) : m_context(context) , m_settings(settings) + , m_is_deferred(is_deferred) { } void RenderState::Reset(const Settings& settings) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h index 506d5fd19..148087090 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h @@ -61,6 +61,8 @@ class RenderCommandList final // NOSONAR - inheritance hierarchy is greater than void Draw(Primitive primitive, uint32_t vertex_count, uint32_t start_vertex, uint32_t instance_count, uint32_t start_instance) override; + bool IsDynamicStateSupported() const noexcept { return m_is_dynamic_state_supported; } + private: // IRenderPassCallback void OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) override; @@ -68,6 +70,8 @@ class RenderCommandList final // NOSONAR - inheritance hierarchy is greater than void UpdatePrimitiveTopology(Primitive primitive); RenderPass& GetVulkanPass(); + + const bool m_is_dynamic_state_supported; }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h index 5a2705fa2..0ca49e7b5 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h @@ -63,7 +63,7 @@ class RenderState final // IObject interface bool SetName(std::string_view name) override; - bool IsNativePipelineDynamic() const noexcept { return m_is_pipeline_dynamic; } + bool IsNativePipelineDynamic() const noexcept { return !Base::RenderState::IsDeferred(); } const vk::Pipeline& GetNativePipelineDynamic() const; const vk::Pipeline& GetNativePipelineMonolithic(const ViewState& viewState, Rhi::RenderPrimitive renderPrimitive); const vk::Pipeline& GetNativePipelineMonolithic(const Base::RenderDrawingState& drawing_state); @@ -75,7 +75,6 @@ class RenderState final using MonolithicPipelineById = std::map; const IContext& m_vk_context; - const bool m_is_pipeline_dynamic; vk::UniquePipeline m_vk_pipeline_dynamic; MonolithicPipelineById m_vk_pipeline_monolithic_by_id; }; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp index cfe2e4d70..35195122c 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp @@ -72,10 +72,12 @@ static vk::CommandBufferInheritanceInfo CreateRenderCommandBufferInheritanceInfo RenderCommandList::RenderCommandList(CommandQueue& command_queue) : CommandList(vk::CommandBufferInheritanceInfo(), command_queue) + , m_is_dynamic_state_supported(GetVulkanCommandQueue().GetVulkanDevice().IsDynamicStateSupported()) { } RenderCommandList::RenderCommandList(CommandQueue& command_queue, RenderPass& render_pass) : CommandList(CreateRenderCommandBufferInheritanceInfo(render_pass), command_queue, render_pass) + , m_is_dynamic_state_supported(GetVulkanCommandQueue().GetVulkanDevice().IsDynamicStateSupported()) { META_FUNCTION_TASK(); static_cast&>(render_pass).Connect(*this); @@ -83,6 +85,7 @@ RenderCommandList::RenderCommandList(CommandQueue& command_queue, RenderPass& re RenderCommandList::RenderCommandList(ParallelRenderCommandList& parallel_render_command_list, bool is_beginning_cmd_list) : CommandList(CreateRenderCommandBufferInheritanceInfo(parallel_render_command_list.GetVulkanPass()), parallel_render_command_list, is_beginning_cmd_list) + , m_is_dynamic_state_supported(GetVulkanCommandQueue().GetVulkanDevice().IsDynamicStateSupported()) { META_FUNCTION_TASK(); static_cast&>(parallel_render_command_list.GetVulkanPass()).Connect(*this); @@ -197,6 +200,7 @@ void RenderCommandList::UpdatePrimitiveTopology(Primitive primitive) { META_FUNCTION_TASK(); if (DrawingState& drawing_state = GetDrawingState(); + m_is_dynamic_state_supported && drawing_state.changes.HasAnyBit(DrawingState::Change::PrimitiveType)) { const vk::PrimitiveTopology vk_primitive_topology = RenderState::GetVulkanPrimitiveTopology(primitive); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index 7c559d809..ad8f1e472 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -191,9 +191,9 @@ vk::PrimitiveTopology RenderState::GetVulkanPrimitiveTopology(Rhi::RenderPrimiti } RenderState::RenderState(const Base::RenderContext& context, const Settings& settings) - : Base::RenderState(context, settings) + : Base::RenderState(context, settings, + !dynamic_cast(context).GetVulkanDevice().IsDynamicStateSupported()) , m_vk_context(dynamic_cast(GetRenderContext())) - , m_is_pipeline_dynamic(m_vk_context.GetVulkanDevice().IsDynamicStateSupported()) { META_FUNCTION_TASK(); Reset(settings); @@ -204,7 +204,7 @@ void RenderState::Reset(const Settings& settings) META_FUNCTION_TASK(); Base::RenderState::Reset(settings); - if (m_is_pipeline_dynamic) + if (IsNativePipelineDynamic()) { m_vk_pipeline_dynamic = CreateNativePipeline(); } @@ -218,7 +218,7 @@ void RenderState::Apply(Base::RenderCommandList& render_command_list, Groups /*s { META_FUNCTION_TASK(); const auto& vulkan_render_command_list = static_cast(render_command_list); - const vk::Pipeline& vk_pipeline_state = m_is_pipeline_dynamic + const vk::Pipeline& vk_pipeline_state = IsNativePipelineDynamic() ? GetNativePipelineDynamic() : GetNativePipelineMonolithic(vulkan_render_command_list.GetDrawingState()); vulkan_render_command_list.GetNativeCommandBufferDefault().bindPipeline(vk::PipelineBindPoint::eGraphics, vk_pipeline_state); @@ -230,20 +230,31 @@ bool RenderState::SetName(std::string_view name) if (!Base::RenderState::SetName(name)) return false; - SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), m_vk_pipeline_dynamic.get(), name); + if (IsNativePipelineDynamic()) + { + SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), m_vk_pipeline_dynamic.get(), name); + } + else + { + for(const auto& [pipeline_id, vk_pipeline_monolithic] : m_vk_pipeline_monolithic_by_id) + { + SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), vk_pipeline_monolithic.get(), name); + } + } return true; } const vk::Pipeline& RenderState::GetNativePipelineDynamic() const { META_FUNCTION_TASK(); - META_CHECK_ARG_TRUE_DESCR(m_is_pipeline_dynamic, "dynamic pipeline is not supported by device"); + META_CHECK_ARG_TRUE_DESCR(IsNativePipelineDynamic(), "dynamic pipeline is not supported by device"); return m_vk_pipeline_dynamic.get(); } const vk::Pipeline& RenderState::GetNativePipelineMonolithic(const ViewState& view_state, Rhi::RenderPrimitive render_primitive) { META_FUNCTION_TASK(); + META_CHECK_ARG_FALSE_DESCR(IsNativePipelineDynamic(), "dynamic pipeline should be used"); const PipelineId pipeline_id = std::tie(view_state.GetSettings(), render_primitive); const auto pipeline_monolithic_by_id_it = m_vk_pipeline_monolithic_by_id.find(pipeline_id); if (pipeline_monolithic_by_id_it == m_vk_pipeline_monolithic_by_id.end()) @@ -360,11 +371,17 @@ vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state 0, nullptr, 0, nullptr ); - const std::vector dynamic_states = { - vk::DynamicState::eViewportWithCountEXT, - vk::DynamicState::eScissorWithCountEXT, - vk::DynamicState::ePrimitiveTopologyEXT, - }; + std::vector dynamic_states; + if (view_state_ptr) + { + dynamic_states.push_back(vk::DynamicState::eViewportWithCountEXT); + dynamic_states.push_back(vk::DynamicState::eScissorWithCountEXT); + } + if (render_primitive_opt) + { + dynamic_states.push_back(vk::DynamicState::ePrimitiveTopologyEXT); + } + vk::PipelineDynamicStateCreateInfo dynamic_info( vk::PipelineDynamicStateCreateFlags{}, dynamic_states @@ -387,13 +404,15 @@ vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state &multisample_info, &depth_stencil_info, &blending_info, - m_is_pipeline_dynamic && !view_state_ptr ? &dynamic_info : nullptr, + IsNativePipelineDynamic() ? &dynamic_info : nullptr, program.GetNativePipelineLayout(), render_pattern.GetNativeRenderPass() ); auto pipe = m_vk_context.GetVulkanDevice().GetNativeDevice().createGraphicsPipelineUnique(nullptr, vk_pipeline_create_info); META_CHECK_ARG_EQUAL_DESCR(pipe.result, vk::Result::eSuccess, "Vulkan pipeline creation has failed"); + + SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), pipe.value.get(), Base::Object::GetName()); return std::move(pipe.value); } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp index ed55d0c87..7109fbebf 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp @@ -131,7 +131,11 @@ bool ViewState::SetScissorRects(const ScissorRects& scissor_rects) void ViewState::Apply(Base::RenderCommandList& command_list) { META_FUNCTION_TASK(); - const vk::CommandBuffer& vk_command_buffer = static_cast(command_list).GetNativeCommandBufferDefault(); + auto& vulkan_command_list = static_cast(command_list); + if (!vulkan_command_list.IsDynamicStateSupported()) + return; + + const vk::CommandBuffer& vk_command_buffer = vulkan_command_list.GetNativeCommandBufferDefault(); vk_command_buffer.setViewportWithCountEXT(m_vk_viewports); vk_command_buffer.setScissorWithCountEXT(m_vk_scissor_rects); } From ddaf570877104382539e4c19c723fab63c408797 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Thu, 20 Jul 2023 22:21:51 +0300 Subject: [PATCH 04/64] Fix extension names set in Vulkan device --- .../Interface/Include/Methane/Graphics/RHI/IDevice.h | 6 +++--- .../Vulkan/Include/Methane/Graphics/Vulkan/Device.h | 3 ++- .../Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp | 11 ++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IDevice.h b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IDevice.h index eb2615562..941d41def 100644 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IDevice.h +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IDevice.h @@ -61,9 +61,9 @@ struct DeviceCaps DeviceFeature::AnisotropicFiltering, DeviceFeature::ImageCubeArray, }; - uint32_t render_queues_count { 1U }; - uint32_t transfer_queues_count { 1U }; - uint32_t compute_queues_count { 1U }; + uint32_t render_queues_count { 1U }; + uint32_t transfer_queues_count { 1U }; + uint32_t compute_queues_count { 1U }; DeviceCaps& SetFeatures(DeviceFeatureMask new_features) noexcept; DeviceCaps& SetRenderQueuesCount(uint32_t new_render_queues_count) noexcept; diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h index ce834050e..ec69ce43d 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Device.h @@ -112,7 +112,8 @@ class Device final Rhi::DeviceFeatureMask GetSupportedFeatures() const; vk::PhysicalDevice m_vk_physical_device; - const std::set m_supported_extension_names; + const std::vector m_supported_extension_names_storage; + const std::set m_supported_extension_names_set; const bool m_is_dynamic_state_supported = false; std::vector m_vk_queue_family_properties; vk::UniqueDevice m_vk_unique_device; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp index 78a574ac8..2c119df43 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp @@ -148,14 +148,14 @@ static vk::QueueFlags GetQueueFlagsByType(Rhi::CommandListType cmd_list_type) } } -static std::set GetDeviceSupportedExtensionNames(const vk::PhysicalDevice& vk_physical_device) +static std::vector GetDeviceSupportedExtensionNames(const vk::PhysicalDevice& vk_physical_device) { META_FUNCTION_TASK(); - std::set supported_extensions; + std::vector supported_extensions; const std::vector vk_device_extension_properties = vk_physical_device.enumerateDeviceExtensionProperties(); for(const vk::ExtensionProperties& vk_extension_props : vk_device_extension_properties) { - supported_extensions.insert(vk_extension_props.extensionName); + supported_extensions.emplace_back(vk_extension_props.extensionName.operator std::string()); } return supported_extensions; } @@ -217,7 +217,8 @@ Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKH IsSoftwarePhysicalDevice(vk_physical_device), capabilities) , m_vk_physical_device(vk_physical_device) - , m_supported_extension_names(GetDeviceSupportedExtensionNames(vk_physical_device)) + , m_supported_extension_names_storage(GetDeviceSupportedExtensionNames(vk_physical_device)) + , m_supported_extension_names_set(m_supported_extension_names_storage.begin(), m_supported_extension_names_storage.end()) , m_is_dynamic_state_supported(IsExtensionSupported(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) , m_vk_queue_family_properties(vk_physical_device.getQueueFamilyProperties()) { @@ -318,7 +319,7 @@ bool Device::SetName(std::string_view name) bool Device::IsExtensionSupported(std::string_view required_extension) const { META_FUNCTION_TASK(); - return m_supported_extension_names.count(required_extension); + return m_supported_extension_names_set.count(required_extension); } const QueueFamilyReservation* Device::GetQueueFamilyReservationPtr(Rhi::CommandListType cmd_list_type) const noexcept From bbfc935c7c489767a0d8b552f0cfdca03ef88396 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Thu, 20 Jul 2023 22:25:48 +0300 Subject: [PATCH 05/64] Fix dynamic state flags in the Pipeline create info --- .../Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index ad8f1e472..eb62746ec 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -372,12 +372,12 @@ vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state ); std::vector dynamic_states; - if (view_state_ptr) + if (!view_state_ptr) { dynamic_states.push_back(vk::DynamicState::eViewportWithCountEXT); dynamic_states.push_back(vk::DynamicState::eScissorWithCountEXT); } - if (render_primitive_opt) + if (!render_primitive_opt) { dynamic_states.push_back(vk::DynamicState::ePrimitiveTopologyEXT); } From b47497fdce5b11bec85a63b6b227b4de02e26b69 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Fri, 21 Jul 2023 22:23:53 +0300 Subject: [PATCH 06/64] Fix more Vulkan bugs related to monolythic pipeline state --- .../Methane/Graphics/Base/RenderCommandList.h | 3 +- .../Graphics/Base/RenderCommandList.cpp | 18 +++- .../Methane/Graphics/Vulkan/Device.cpp | 14 ++- .../Graphics/Vulkan/RenderCommandList.cpp | 10 +- .../Methane/Graphics/Vulkan/ViewState.cpp | 2 +- .../Sources/Methane/UserInterface/Text.cpp | 101 +++++++++--------- 6 files changed, 84 insertions(+), 64 deletions(-) diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h index 185c264f6..109c9ecbb 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderCommandList.h @@ -53,7 +53,8 @@ struct RenderDrawingState { enum class Change : uint32_t { - PrimitiveType + PrimitiveType, + ViewState }; using ChangeMask = Data::EnumMask; diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp index 67591a27b..765517d5a 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp @@ -132,17 +132,16 @@ void RenderCommandList::SetViewState(Rhi::IViewState& view_state) VerifyEncodingState(); DrawingState& drawing_state = GetDrawingState(); - const ViewState* p_prev_view_state = drawing_state.view_state_ptr; - drawing_state.view_state_ptr = static_cast(&view_state); - - if (p_prev_view_state && p_prev_view_state->GetSettings() == view_state.GetSettings()) + if (drawing_state.view_state_ptr && drawing_state.view_state_ptr->GetSettings() == view_state.GetSettings()) { META_LOG("{} Command list '{}' view state is already set up", magic_enum::enum_name(GetType()), GetName()); return; } META_LOG("{} Command list '{}' SET VIEW STATE:\n{}", magic_enum::enum_name(GetType()), GetName(), static_cast(drawing_state.view_state_ptr->GetSettings())); + drawing_state.view_state_ptr = static_cast(&view_state); drawing_state.view_state_ptr->Apply(*this); + drawing_state.changes |= DrawingState::Change::ViewState; } bool RenderCommandList::SetVertexBuffers(Rhi::IBufferSet& vertex_buffers, bool set_resource_barriers) @@ -289,11 +288,20 @@ void RenderCommandList::UpdateDrawingState(Primitive primitive_type) drawing_state.primitive_type_opt = primitive_type; } - if (m_drawing_state.render_state_ptr && m_drawing_state.render_state_ptr->IsDeferred()) + if (m_drawing_state.render_state_ptr && + m_drawing_state.render_state_ptr->IsDeferred() && + (static_cast(m_drawing_state.render_state_groups) || + drawing_state.changes.HasAnyBit(DrawingState::Change::PrimitiveType) || + drawing_state.changes.HasAnyBit(DrawingState::Change::ViewState))) { + // Apply render state in deferred mode right before the Draw call, + // only in case when any render state groups or view state or primitive type has changed m_drawing_state.render_state_ptr->Apply(*this, m_drawing_state.render_state_groups); RetainResource(m_drawing_state.render_state_ptr); + m_drawing_state.render_state_groups = {}; + drawing_state.changes.SetBitOff(DrawingState::Change::PrimitiveType); + drawing_state.changes.SetBitOff(DrawingState::Change::ViewState); } } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp index 2c119df43..11ac02004 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp @@ -214,8 +214,8 @@ void QueueFamilyReservation::IncrementQueuesCount(uint32_t extra_queues_count) n Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKHR& vk_surface, const Capabilities& capabilities) : Base::Device(vk_physical_device.getProperties().deviceName, - IsSoftwarePhysicalDevice(vk_physical_device), - capabilities) + IsSoftwarePhysicalDevice(vk_physical_device), + capabilities) , m_vk_physical_device(vk_physical_device) , m_supported_extension_names_storage(GetDeviceSupportedExtensionNames(vk_physical_device)) , m_supported_extension_names_set(m_supported_extension_names_storage.begin(), m_supported_extension_names_storage.end()) @@ -273,10 +273,16 @@ Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKH vk_device_features.imageCubeArray = capabilities.features.HasBit(Rhi::DeviceFeature::ImageCubeArray); // Add descriptions of enabled device features: - vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT vk_device_dynamic_state_feature(true); + vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT vk_device_dynamic_state_feature(m_is_dynamic_state_supported); vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR vk_device_timeline_semaphores_feature(true); vk::PhysicalDeviceHostQueryResetFeatures vk_device_host_query_reset_feature(true); - vk::DeviceCreateInfo vk_device_info(vk::DeviceCreateFlags{}, vk_queue_create_infos, { }, raw_enabled_extension_names, &vk_device_features); + vk::DeviceCreateInfo vk_device_info( + vk::DeviceCreateFlags{}, + vk_queue_create_infos, + { }, + raw_enabled_extension_names, + &vk_device_features + ); vk_device_info.setPNext(&vk_device_dynamic_state_feature); vk_device_dynamic_state_feature.setPNext(&vk_device_timeline_semaphores_feature); vk_device_timeline_semaphores_feature.setPNext(&vk_device_host_query_reset_feature); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp index 35195122c..2b8e138c4 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp @@ -199,9 +199,13 @@ void RenderCommandList::OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) void RenderCommandList::UpdatePrimitiveTopology(Primitive primitive) { META_FUNCTION_TASK(); - if (DrawingState& drawing_state = GetDrawingState(); - m_is_dynamic_state_supported && - drawing_state.changes.HasAnyBit(DrawingState::Change::PrimitiveType)) + DrawingState& drawing_state = GetDrawingState(); + if (!drawing_state.changes.HasAnyBit(DrawingState::Change::PrimitiveType)) + return; + + drawing_state.primitive_type_opt = primitive; + + if (m_is_dynamic_state_supported) { const vk::PrimitiveTopology vk_primitive_topology = RenderState::GetVulkanPrimitiveTopology(primitive); GetNativeCommandBufferDefault().setPrimitiveTopologyEXT(vk_primitive_topology); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp index 7109fbebf..c4351f786 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp @@ -131,7 +131,7 @@ bool ViewState::SetScissorRects(const ScissorRects& scissor_rects) void ViewState::Apply(Base::RenderCommandList& command_list) { META_FUNCTION_TASK(); - auto& vulkan_command_list = static_cast(command_list); + auto& vulkan_command_list = static_cast(command_list); if (!vulkan_command_list.IsDynamicStateSupported()) return; diff --git a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp index 5cf425ebe..3301d929f 100644 --- a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp +++ b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp @@ -266,11 +266,11 @@ class TextFrameResources META_CHECK_ARG_TRUE(m_uniforms_buffer.IsInitialized()); m_program_bindings = state.GetProgram().CreateBindings({ - { { rhi::ShaderType::Vertex, "g_uniforms" }, { { m_uniforms_buffer.GetInterface() } } }, - { { rhi::ShaderType::Pixel, "g_constants" }, { { const_buffer.GetInterface() } } }, - { { rhi::ShaderType::Pixel, "g_texture" }, { { m_atlas_texture.GetInterface() } } }, - { { rhi::ShaderType::Pixel, "g_sampler" }, { { atlas_sampler.GetInterface() } } }, - }); + { { rhi::ShaderType::Vertex, "g_uniforms" }, { { m_uniforms_buffer.GetInterface() } } }, + { { rhi::ShaderType::Pixel, "g_constants" }, { { const_buffer.GetInterface() } } }, + { { rhi::ShaderType::Pixel, "g_texture" }, { { m_atlas_texture.GetInterface() } } }, + { { rhi::ShaderType::Pixel, "g_sampler" }, { { atlas_sampler.GetInterface() } } }, + }); m_program_bindings.SetName(fmt::format("{} Text Bindings {}", text_name, m_frame_index)); } }; @@ -321,33 +321,34 @@ class Text::Impl // NOSONAR - class destructor is required else { rhi::RenderState::Settings state_settings - { - rhi::Program(m_ui_context.GetRenderContext(), - rhi::Program::Settings - { - rhi::Program::ShaderSet - { - { rhi::ShaderType::Vertex, { Data::ShaderProvider::Get(), { "Text", "TextVS" }, {} } }, - { rhi::ShaderType::Pixel, { Data::ShaderProvider::Get(), { "Text", "TextPS" }, {} } }, - }, - rhi::ProgramInputBufferLayouts - { - rhi::Program::InputBufferLayout - { - rhi::Program::InputBufferLayout::ArgumentSemantics{ "POSITION", "TEXCOORD" } - } - }, - rhi::ProgramArgumentAccessors - { - { { rhi::ShaderType::Vertex, "g_uniforms" }, rhi::ProgramArgumentAccessor::Type::Mutable }, - { { rhi::ShaderType::Pixel, "g_constants" }, rhi::ProgramArgumentAccessor::Type::Mutable }, - { { rhi::ShaderType::Pixel, "g_texture" }, rhi::ProgramArgumentAccessor::Type::Mutable }, - { { rhi::ShaderType::Pixel, "g_sampler" }, rhi::ProgramArgumentAccessor::Type::Constant }, - }, - render_pattern.GetAttachmentFormats() - }), - render_pattern - }; + { + rhi::Program( + m_ui_context.GetRenderContext(), + rhi::Program::Settings + { + rhi::Program::ShaderSet + { + { rhi::ShaderType::Vertex, { Data::ShaderProvider::Get(), { "Text", "TextVS" }, {} } }, + { rhi::ShaderType::Pixel, { Data::ShaderProvider::Get(), { "Text", "TextPS" }, {} } }, + }, + rhi::ProgramInputBufferLayouts + { + rhi::Program::InputBufferLayout + { + rhi::Program::InputBufferLayout::ArgumentSemantics{ "POSITION", "TEXCOORD" } + } + }, + rhi::ProgramArgumentAccessors + { + { { rhi::ShaderType::Vertex, "g_uniforms" }, rhi::ProgramArgumentAccessor::Type::Mutable }, + { { rhi::ShaderType::Pixel, "g_constants" }, rhi::ProgramArgumentAccessor::Type::Mutable }, + { { rhi::ShaderType::Pixel, "g_texture" }, rhi::ProgramArgumentAccessor::Type::Mutable }, + { { rhi::ShaderType::Pixel, "g_sampler" }, rhi::ProgramArgumentAccessor::Type::Constant }, + }, + render_pattern.GetAttachmentFormats() + }), + render_pattern + }; state_settings.program.SetName("Text Shading"); state_settings.depth.enabled = false; state_settings.depth.write_enabled = false; @@ -368,12 +369,12 @@ class Text::Impl // NOSONAR - class destructor is required const FrameRect viewport_rect = m_text_mesh_ptr ? GetAlignedViewportRect() : m_frame_rect.AsBase(); m_view_state = rhi::ViewState({ - { gfx::GetFrameViewport(viewport_rect) }, - { gfx::GetFrameScissorRect(viewport_rect) } - }); + { gfx::GetFrameViewport(viewport_rect) }, + { gfx::GetFrameScissorRect(viewport_rect) } + }); static const std::string s_sampler_name = "Font Atlas Sampler"; - if (const auto atlas_sampler_ptr = std::dynamic_pointer_cast(gfx_objects_registry.GetGraphicsObject(s_sampler_name)); + if (const auto atlas_sampler_ptr = std::dynamic_pointer_cast(gfx_objects_registry.GetGraphicsObject(s_sampler_name)); atlas_sampler_ptr) { m_atlas_sampler = rhi::Sampler(atlas_sampler_ptr); @@ -381,9 +382,9 @@ class Text::Impl // NOSONAR - class destructor is required else { m_atlas_sampler = m_ui_context.GetRenderContext().CreateSampler({ - rhi::ISampler::Filter(rhi::ISampler::Filter::MinMag::Linear), - rhi::ISampler::Address(rhi::ISampler::Address::Mode::ClampToZero), - }); + rhi::ISampler::Filter(rhi::ISampler::Filter::MinMag::Linear), + rhi::ISampler::Address(rhi::ISampler::Address::Mode::ClampToZero), + }); m_atlas_sampler.SetName(s_sampler_name); gfx_objects_registry.AddGraphicsObject(m_atlas_sampler.GetInterface()); @@ -397,17 +398,17 @@ class Text::Impl // NOSONAR - class destructor is required Impl(Context& ui_context, const rhi::RenderPattern& render_pattern, const Font& font, const SettingsUtf8& settings) : Impl(ui_context, render_pattern, font, SettingsUtf32 - { - settings.name, - Font::ConvertUtf8To32(settings.text), - settings.rect, - settings.layout, - settings.color, - settings.incremental_update, - settings.adjust_vertical_content_offset, - settings.mesh_buffers_reservation_multiplier, - settings.state_name - } + { + settings.name, + Font::ConvertUtf8To32(settings.text), + settings.rect, + settings.layout, + settings.color, + settings.incremental_update, + settings.adjust_vertical_content_offset, + settings.mesh_buffers_reservation_multiplier, + settings.state_name + } ) { } From dbd3c06072576bf2c8117a184e99ae7350056ba1 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 22 Jul 2023 12:57:51 +0300 Subject: [PATCH 07/64] Fix string typos --- .../Graphics/Primitives/Include/Methane/Graphics/ImageLoader.h | 2 +- .../Primitives/Sources/Methane/Graphics/ImageLoader.cpp | 2 +- .../RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp | 2 +- .../Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp | 2 +- .../RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Texture.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/Graphics/Primitives/Include/Methane/Graphics/ImageLoader.h b/Modules/Graphics/Primitives/Include/Methane/Graphics/ImageLoader.h index 0d4012a46..a4bbd08ef 100644 --- a/Modules/Graphics/Primitives/Include/Methane/Graphics/ImageLoader.h +++ b/Modules/Graphics/Primitives/Include/Methane/Graphics/ImageLoader.h @@ -17,7 +17,7 @@ limitations under the License. ******************************************************************************* FILE: Methane/Graphics/ImageLoader.h -ForImage Loader creates textures from images loaded via data provider and +Image Loader creates textures from images loaded via data provider and by decoding them from popular image formats. ******************************************************************************/ diff --git a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp index c8fddf517..b8a608854 100644 --- a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp +++ b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp @@ -17,7 +17,7 @@ limitations under the License. ******************************************************************************* FILE: Methane/Graphics/ImageLoader.cpp -ForImage Loader creates textures from images loaded via data provider and +Image Loader creates textures from images loaded via data provider and by decoding them from popular image formats. ******************************************************************************/ diff --git a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp index c9f48dc5c..7fe8e53bf 100644 --- a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp +++ b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp @@ -361,7 +361,7 @@ bool Texture::SetName(std::string_view name) void Texture::SetData(Rhi::ICommandQueue& target_cmd_queue, const SubResources& sub_resources) { META_FUNCTION_TASK(); - META_CHECK_ARG_NOT_NULL_DESCR(m_cp_upload_resource, "Only ForImage textures support data upload from CPU."); + META_CHECK_ARG_NOT_NULL_DESCR(m_cp_upload_resource, "Only Image textures support data upload from CPU."); Base::Texture::SetData(target_cmd_queue, sub_resources); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index 3a7556c86..c9b6fc7dd 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -408,7 +408,7 @@ void RenderContext::ResetNativeObjectNames() const if (!vk_unique_frame_semaphore) continue; - const std::string frame_semaphore_name = fmt::format("{} Frame {} ForImage Available", GetName(), frame_index); + const std::string frame_semaphore_name = fmt::format("{} Frame {} Image Available", GetName(), frame_index); SetVulkanObjectName(m_vk_device, vk_unique_frame_semaphore.get(), frame_semaphore_name.c_str()); frame_index++; } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Texture.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Texture.cpp index dd36c3742..4b247cfaa 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Texture.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Texture.cpp @@ -178,7 +178,7 @@ static Ptr CreateNativeImageViewDescriptor( view_id.subresource_count.GetBaseLayerCount()) )); - const std::string view_name = fmt::format("{} ForImage View for {} usage", texture_name, Data::GetEnumMaskName(view_id.usage)); + const std::string view_name = fmt::format("{} Image View for {} usage", texture_name, Data::GetEnumMaskName(view_id.usage)); SetVulkanObjectName(vk_device, image_view_desc.vk_view.get(), view_name.c_str()); image_view_desc.vk_desc = vk::DescriptorImageInfo( From 65475ec26a3eab2ec395fe1ef89371b37eea7abd Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 22 Jul 2023 15:01:37 +0300 Subject: [PATCH 08/64] Invalidate frame buffer of the command buffer on render pass update --- .../RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp | 2 +- .../Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp index 6b4ba421f..c0d58104b 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp @@ -294,7 +294,6 @@ class CommandList ); } -private: vk::UniqueCommandPool CreateVulkanCommandPool(uint32_t queue_family_index) { META_FUNCTION_TASK(); @@ -348,6 +347,7 @@ class CommandList return m_vk_command_buffer_begin_infos[magic_enum::enum_index(cmd_buffer_type).value()]; } +private: vk::Device m_vk_device; vk::UniqueCommandPool m_vk_unique_command_pool; bool m_is_native_committed = false; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp index 2b8e138c4..4a12ea091 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp @@ -194,6 +194,7 @@ void RenderCommandList::OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) { META_FUNCTION_TASK(); SetSecondaryRenderBufferInheritInfo(CreateRenderCommandBufferInheritanceInfo(static_cast(render_pass))); + InitializeSecondaryCommandBuffers(IsParallel() ? 0U : 1U); } void RenderCommandList::UpdatePrimitiveTopology(Primitive primitive) From 460fe6e2aa41f3686bff5f6d224296b99744623e Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Sat, 22 Jul 2023 17:03:11 +0300 Subject: [PATCH 09/64] Remove unused extensions: VK_KHR_SYNCHRONIZATION_2 and VK_GOOGLE_* --- .../Sources/Methane/Graphics/Vulkan/Device.cpp | 18 ------------------ .../Sources/Methane/Graphics/Vulkan/System.cpp | 6 ++---- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp index 11ac02004..3696d2225 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp @@ -46,12 +46,6 @@ Vulkan implementation of the device interface. namespace Methane::Graphics::Vulkan { -// Google extensions are used to reflect HLSL semantic names from shader input decorations, -// and it works fine, but is not listed by Windows NVidia drivers, who knows why? -//#ifdef __linux__ -//#define VK_GOOGLE_SPIRV_EXTENSIONS_ENABLED -//#endif - #define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset" static const std::vector g_common_device_extensions{ @@ -59,13 +53,6 @@ static const std::vector g_common_device_extensions{ #ifdef METHANE_GPU_INSTRUMENTATION_ENABLED VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, #endif -#ifndef __APPLE__ - VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, -#endif -#ifdef VK_GOOGLE_SPIRV_EXTENSIONS_ENABLED - VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME, - VK_GOOGLE_USER_TYPE_EXTENSION_NAME, -#endif }; template @@ -287,11 +274,6 @@ Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKH vk_device_dynamic_state_feature.setPNext(&vk_device_timeline_semaphores_feature); vk_device_timeline_semaphores_feature.setPNext(&vk_device_host_query_reset_feature); -#ifndef __APPLE__ - vk::PhysicalDeviceSynchronization2FeaturesKHR vk_device_synchronization_2_feature(true); - vk_device_host_query_reset_feature.setPNext(&vk_device_synchronization_2_feature); -#endif - m_vk_unique_device = vk_physical_device.createDeviceUnique(vk_device_info); VULKAN_HPP_DEFAULT_DISPATCHER.init(m_vk_unique_device.get()); } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp index fcd2640ff..1186d21f6 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp @@ -153,13 +153,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(VkDebugUtilsMessageSe strstr(callback_data_ptr->pMessage, "terminator_CreateInstance: Failed to CreateInstance in ICD"))) return VK_FALSE; -#ifndef VK_GOOGLE_SPIRV_EXTENSIONS_ENABLED // Filter out validation error appeared due to missing HLSL extension for SPIRV bytecode, which can not be used because of bug in NVidia Windows drivers: // vkCreateShaderModule(): The SPIR-V Extension (SPV_GOOGLE_hlsl_functionality1 | SPV_GOOGLE_user_type) was declared, but none of the requirements were met to use it. - if (callback_data_ptr->messageIdNumber == 1028204675 && // VUID-VkShaderModuleCreateInfo-pCode-04147 - strstr(callback_data_ptr->pMessage, "SPV_GOOGLE_")) + if (callback_data_ptr->messageIdNumber == -60244330 ||// VUID-VkShaderModuleCreateInfo-pCode-08742 + (callback_data_ptr->messageIdNumber == 1028204675 && strstr(callback_data_ptr->pMessage, "SPV_GOOGLE_")) ) // VUID-VkShaderModuleCreateInfo-pCode-04147 return VK_FALSE; -#endif // VK_GOOGLE_SPIRV_EXTENSIONS_ENABLED #endif // !NDEBUG From b91ba7e73bdd3e09cbf0476663a171177039fa22 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 22 Jul 2023 22:28:39 +0300 Subject: [PATCH 10/64] Workaround crash in validation layer on MacOS --- .../Include/Methane/Graphics/Vulkan/CommandListSet.h | 1 + .../Methane/Graphics/Vulkan/CommandListSet.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h index c1e8094cf..e2be37593 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h @@ -69,6 +69,7 @@ class CommandListSet final std::vector m_vk_wait_values; vk::UniqueSemaphore m_vk_unique_execution_completed_semaphore; vk::UniqueFence m_vk_unique_execution_completed_fence; + bool m_signalled_execution_completed_fence = false; TracyLockable(std::mutex, m_vk_unique_execution_completed_fence_mutex); }; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index 05971e213..a28a95df2 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -120,8 +120,15 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet } std::scoped_lock fence_guard(m_vk_unique_execution_completed_fence_mutex); - m_vk_device.resetFences(GetNativeExecutionCompletedFence()); - GetVulkanCommandQueue().GetNativeQueue().submit(submit_info, GetNativeExecutionCompletedFence()); + const vk::Fence& vk_fence = GetNativeExecutionCompletedFence(); + if (m_signalled_execution_completed_fence) + { + // Do not reset not-signalled fence to workaround crash in validation layer on MacOS + // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/4974 + m_vk_device.resetFences(vk_fence); + } + GetVulkanCommandQueue().GetNativeQueue().submit(submit_info, vk_fence); + m_signalled_execution_completed_fence = true; } void CommandListSet::WaitUntilCompleted() From 4a363a63497d9b7ba9c8a858ac79239cdb80a055 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 23 Jul 2023 22:57:26 +0300 Subject: [PATCH 11/64] Update Vulkan pipeline monolithic state on view state change or destruction --- .../Include/Methane/Graphics/Base/ViewState.h | 3 ++ .../Methane/Graphics/Base/ViewState.cpp | 8 ++++ .../Include/Methane/Graphics/RHI/IViewState.h | 13 +++++++ .../Include/Methane/Graphics/Null/ViewState.h | 7 +++- .../Methane/Graphics/Null/ViewState.cpp | 39 ++++++++++++++++++- .../Methane/Graphics/Vulkan/RenderState.h | 11 +++++- .../Methane/Graphics/Vulkan/RenderState.cpp | 36 +++++++++++++++-- .../Methane/Graphics/Vulkan/ViewState.cpp | 6 +++ 8 files changed, 116 insertions(+), 7 deletions(-) diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h index 8cf323048..81ccd8c28 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h @@ -26,6 +26,7 @@ Base implementation of the view state interface. #include "Object.h" #include +#include namespace Methane::Graphics::Base { @@ -34,10 +35,12 @@ class RenderCommandList; class ViewState : public Rhi::IViewState + , public Data::Emitter , public std::enable_shared_from_this { public: explicit ViewState(const Settings& settings); + ~ViewState() override; // IViewState overrides Ptr GetPtr() final { return shared_from_this(); } diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp index 0d44b87b0..2106ef6e3 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp @@ -21,6 +21,8 @@ Base implementation of the view state interface. ******************************************************************************/ +#include "Methane/Data/Emitter.hpp" +#include "Methane/Graphics/RHI/IViewState.h" #include #include @@ -47,6 +49,12 @@ ViewState::ViewState(const Settings& settings) Validate(settings.scissor_rects); } +ViewState::~ViewState() +{ + META_FUNCTION_TASK(); + Data::Emitter::Emit(&ICallback::OnViewStateDestroyed, *this); +} + bool ViewState::Reset(const Settings& settings) { META_FUNCTION_TASK(); diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h index f42e48a91..4057b3670 100644 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h @@ -24,6 +24,7 @@ Methane view state interface: viewports and clipping rects setup. #pragma once #include +#include namespace Methane::Graphics::Rhi { @@ -39,9 +40,21 @@ struct ViewSettings [[nodiscard]] explicit operator std::string() const; }; +struct IViewState; + +struct IViewStateCallback +{ + virtual void OnViewStateChanged(IViewState& view_state) = 0; + virtual void OnViewStateDestroyed(IViewState& view_state) = 0; + + virtual ~IViewStateCallback() = default; +}; + struct IViewState + : virtual Data::IEmitter { using Settings = ViewSettings; + using ICallback = IViewStateCallback; // Create IViewState instance [[nodiscard]] static Ptr Create(const Settings& state_settings); diff --git a/Modules/Graphics/RHI/Null/Include/Methane/Graphics/Null/ViewState.h b/Modules/Graphics/RHI/Null/Include/Methane/Graphics/Null/ViewState.h index 4a0cc36a4..1b907549b 100644 --- a/Modules/Graphics/RHI/Null/Include/Methane/Graphics/Null/ViewState.h +++ b/Modules/Graphics/RHI/Null/Include/Methane/Graphics/Null/ViewState.h @@ -34,8 +34,13 @@ class ViewState final public: using Base::ViewState::ViewState; + // IViewState overrides + bool Reset(const Settings& settings) override; + bool SetViewports(const Viewports& viewports) override; + bool SetScissorRects(const ScissorRects& scissor_rects) override; + // Base::ViewState interface - void Apply(Base::RenderCommandList&) override { /* Intentionally unimplemented */ } + void Apply(Base::RenderCommandList&) override; }; } // namespace Methane::Graphics::Null diff --git a/Modules/Graphics/RHI/Null/Sources/Methane/Graphics/Null/ViewState.cpp b/Modules/Graphics/RHI/Null/Sources/Methane/Graphics/Null/ViewState.cpp index ba7302e68..54f2f5e6e 100644 --- a/Modules/Graphics/RHI/Null/Sources/Methane/Graphics/Null/ViewState.cpp +++ b/Modules/Graphics/RHI/Null/Sources/Methane/Graphics/Null/ViewState.cpp @@ -26,7 +26,7 @@ Null implementation of the view state interface. namespace Methane::Graphics::Rhi { -Ptr Rhi::IViewState::Create(const Rhi::IViewState::Settings& state_settings) +Ptr IViewState::Create(const Rhi::IViewState::Settings& state_settings) { META_FUNCTION_TASK(); return std::make_shared(state_settings); @@ -34,3 +34,40 @@ Ptr Rhi::IViewState::Create(const Rhi::IViewState::Settings& state_s } // namespace Methane::Graphics::Rhi +namespace Methane::Graphics::Null +{ + +bool ViewState::Reset(const Settings& settings) +{ + if (!Base::ViewState::Reset(settings)) + return false; + + Data::Emitter::Emit(&ICallback::OnViewStateChanged, *this); + return true; +} + +bool ViewState::SetViewports(const Viewports& viewports) +{ + if (!Base::ViewState::SetViewports(viewports)) + return false; + + Data::Emitter::Emit(&ICallback::OnViewStateChanged, *this); + return true; +} + +bool ViewState::SetScissorRects(const ScissorRects& scissor_rects) +{ + if (!Base::ViewState::SetScissorRects(scissor_rects)) + return false; + + Data::Emitter::Emit(&ICallback::OnViewStateChanged, *this); + return true; +} + +void ViewState::Apply(Base::RenderCommandList&) +{ + /* Intentionally unimplemented */ +} + +} // namespace Methane::Graphics::Null + diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h index 0ca49e7b5..4789179a4 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h @@ -25,6 +25,7 @@ Vulkan implementation of the render state interface. #include #include +#include #include @@ -48,6 +49,8 @@ class ViewState; class RenderState final : public Base::RenderState + , private Data::Receiver + { public: static vk::PrimitiveTopology GetVulkanPrimitiveTopology(Rhi::RenderPrimitive primitive_type); @@ -65,13 +68,17 @@ class RenderState final bool IsNativePipelineDynamic() const noexcept { return !Base::RenderState::IsDeferred(); } const vk::Pipeline& GetNativePipelineDynamic() const; - const vk::Pipeline& GetNativePipelineMonolithic(const ViewState& viewState, Rhi::RenderPrimitive renderPrimitive); + const vk::Pipeline& GetNativePipelineMonolithic(ViewState& viewState, Rhi::RenderPrimitive renderPrimitive); const vk::Pipeline& GetNativePipelineMonolithic(const Base::RenderDrawingState& drawing_state); private: vk::UniquePipeline CreateNativePipeline(const ViewState* viewState = nullptr, Opt renderPrimitive = {}); - using PipelineId = std::tuple; + // IViewStateCallback overrides + void OnViewStateChanged(Rhi::IViewState& view_state) override; + void OnViewStateDestroyed(Rhi::IViewState& view_state) override; + + using PipelineId = std::tuple; using MonolithicPipelineById = std::map; const IContext& m_vk_context; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index eb62746ec..068920778 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -21,6 +21,7 @@ Vulkan implementation of the render state interface. ******************************************************************************/ +#include "Methane/Graphics/RHI/IViewState.h" #include #include #include @@ -251,14 +252,15 @@ const vk::Pipeline& RenderState::GetNativePipelineDynamic() const return m_vk_pipeline_dynamic.get(); } -const vk::Pipeline& RenderState::GetNativePipelineMonolithic(const ViewState& view_state, Rhi::RenderPrimitive render_primitive) +const vk::Pipeline& RenderState::GetNativePipelineMonolithic(ViewState& view_state, Rhi::RenderPrimitive render_primitive) { META_FUNCTION_TASK(); META_CHECK_ARG_FALSE_DESCR(IsNativePipelineDynamic(), "dynamic pipeline should be used"); - const PipelineId pipeline_id = std::tie(view_state.GetSettings(), render_primitive); + const PipelineId pipeline_id(static_cast(&view_state), render_primitive); const auto pipeline_monolithic_by_id_it = m_vk_pipeline_monolithic_by_id.find(pipeline_id); if (pipeline_monolithic_by_id_it == m_vk_pipeline_monolithic_by_id.end()) { + view_state.Connect(*this); return m_vk_pipeline_monolithic_by_id.try_emplace(pipeline_id, CreateNativePipeline(&view_state, render_primitive)).first->second.get(); } return pipeline_monolithic_by_id_it->second.get(); @@ -269,7 +271,7 @@ const vk::Pipeline& RenderState::GetNativePipelineMonolithic(const Base::RenderD META_FUNCTION_TASK(); META_CHECK_ARG_NOT_NULL_DESCR(drawing_state.view_state_ptr, "view state is not set in render command list drawing state"); META_CHECK_ARG_TRUE_DESCR(drawing_state.primitive_type_opt.has_value(), "primitive type is not set in render command list drawing state"); - return GetNativePipelineMonolithic(static_cast(*drawing_state.view_state_ptr), drawing_state.primitive_type_opt.value()); + return GetNativePipelineMonolithic(static_cast(*drawing_state.view_state_ptr), drawing_state.primitive_type_opt.value()); } vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state_ptr, Opt render_primitive_opt) @@ -416,4 +418,32 @@ vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state return std::move(pipe.value); } +void RenderState::OnViewStateChanged(Rhi::IViewState& view_state) +{ + META_FUNCTION_TASK(); + for(auto& [pipeline_id, vk_pipeline_monolithic] : m_vk_pipeline_monolithic_by_id) + if (std::get<0>(pipeline_id) == &view_state) + { + // TODO: add support of delayed destruction of the pipeline state used in executing GPU command buffer + vk_pipeline_monolithic = CreateNativePipeline(static_cast(&view_state), std::get<1>(pipeline_id)); + } +} + +void RenderState::OnViewStateDestroyed(Rhi::IViewState& view_state) +{ + META_FUNCTION_TASK(); + for(auto vk_pipeline_it = m_vk_pipeline_monolithic_by_id.begin(); + vk_pipeline_it != m_vk_pipeline_monolithic_by_id.end();) + { + if (std::get<0>(vk_pipeline_it->first) != &view_state) + { + vk_pipeline_it++; + continue; + } + + // TODO: add support of delayed destruction of the pipeline state used in executing GPU command buffer + m_vk_pipeline_monolithic_by_id.erase(vk_pipeline_it); + } +} + } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp index c4351f786..c21d54d1b 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp @@ -103,6 +103,8 @@ bool ViewState::Reset(const Settings& settings) m_vk_viewports = ViewportsToVulkan(settings.viewports); m_vk_scissor_rects = ScissorRectsToVulkan(settings.scissor_rects); m_vk_viewport_state_info = vk::PipelineViewportStateCreateInfo({}, m_vk_viewports, m_vk_scissor_rects); + + Data::Emitter::Emit(&ICallback::OnViewStateChanged, *this); return true; } @@ -114,6 +116,8 @@ bool ViewState::SetViewports(const Viewports& viewports) m_vk_viewports = ViewportsToVulkan(GetSettings().viewports); m_vk_viewport_state_info.setViewports(m_vk_viewports); + + Data::Emitter::Emit(&ICallback::OnViewStateChanged, *this); return true; } @@ -125,6 +129,8 @@ bool ViewState::SetScissorRects(const ScissorRects& scissor_rects) m_vk_scissor_rects = ScissorRectsToVulkan(GetSettings().scissor_rects); m_vk_viewport_state_info.setScissors(m_vk_scissor_rects); + + Data::Emitter::Emit(&ICallback::OnViewStateChanged, *this); return true; } From 224fe00b191e757676d1d95960bd9cfa7c3f26f5 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Mon, 24 Jul 2023 20:46:50 +0300 Subject: [PATCH 12/64] Add deferred release of Vulkan pipeline objects --- .../Methane/Graphics/Vulkan/RenderContext.h | 18 +++++++++++------- .../Methane/Graphics/Vulkan/RenderState.h | 3 ++- .../Methane/Graphics/Vulkan/RenderContext.cpp | 2 ++ .../Methane/Graphics/Vulkan/RenderState.cpp | 16 ++++++++-------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h index f56538720..121da4154 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h @@ -29,6 +29,7 @@ Vulkan implementation of the render context interface. #include #include +#include #include #ifdef __APPLE__ @@ -89,6 +90,8 @@ class RenderContext final // NOSONAR - this class requires destructor const vk::Semaphore& GetNativeFrameImageAvailableSemaphore(uint32_t frame_buffer_index) const; const vk::Semaphore& GetNativeFrameImageAvailableSemaphore() const; + void DeferredRelease(vk::UniquePipeline&& pipeline) const { m_vk_deferred_release_pipelines.emplace_back(std::move(pipeline)); } + protected: // Base::RenderContext overrides uint32_t GetNextFrameBufferIndex() override; @@ -107,13 +110,14 @@ class RenderContext final // NOSONAR - this class requires destructor // MacOS metal app view with swap-chain implementation to work via MoltenVK AppViewMetal* m_metal_view; #endif - const vk::UniqueSurfaceKHR m_vk_unique_surface; - vk::UniqueSwapchainKHR m_vk_unique_swapchain; - vk::Format m_vk_frame_format; - vk::Extent2D m_vk_frame_extent; - std::vector m_vk_frame_images; - std::vector m_vk_frame_semaphores_pool; - std::vector m_vk_frame_image_available_semaphores; + const vk::UniqueSurfaceKHR m_vk_unique_surface; + vk::UniqueSwapchainKHR m_vk_unique_swapchain; + vk::Format m_vk_frame_format; + vk::Extent2D m_vk_frame_extent; + std::vector m_vk_frame_images; + std::vector m_vk_frame_semaphores_pool; + std::vector m_vk_frame_image_available_semaphores; + mutable std::deque m_vk_deferred_release_pipelines; }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h index 4789179a4..234fb36c4 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h @@ -46,6 +46,7 @@ namespace Methane::Graphics::Vulkan struct IContext; class ViewState; +class RenderContext; class RenderState final : public Base::RenderState @@ -81,7 +82,7 @@ class RenderState final using PipelineId = std::tuple; using MonolithicPipelineById = std::map; - const IContext& m_vk_context; + const RenderContext& m_vk_render_context; vk::UniquePipeline m_vk_pipeline_dynamic; MonolithicPipelineById m_vk_pipeline_monolithic_by_id; }; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index c9b6fc7dd..00714e9c6 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -136,6 +136,8 @@ void RenderContext::WaitForGpu(WaitFor wait_for) } GetVulkanDefaultCommandQueue(cl_type).CompleteExecution(frame_buffer_index); + + m_vk_deferred_release_pipelines.clear(); } bool RenderContext::ReadyToRender() const diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index 068920778..6ca129218 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -21,7 +21,7 @@ Vulkan implementation of the render state interface. ******************************************************************************/ -#include "Methane/Graphics/RHI/IViewState.h" +#include #include #include #include @@ -194,7 +194,7 @@ vk::PrimitiveTopology RenderState::GetVulkanPrimitiveTopology(Rhi::RenderPrimiti RenderState::RenderState(const Base::RenderContext& context, const Settings& settings) : Base::RenderState(context, settings, !dynamic_cast(context).GetVulkanDevice().IsDynamicStateSupported()) - , m_vk_context(dynamic_cast(GetRenderContext())) + , m_vk_render_context(static_cast(GetRenderContext())) { META_FUNCTION_TASK(); Reset(settings); @@ -233,13 +233,13 @@ bool RenderState::SetName(std::string_view name) if (IsNativePipelineDynamic()) { - SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), m_vk_pipeline_dynamic.get(), name); + SetVulkanObjectName(m_vk_render_context.GetVulkanDevice().GetNativeDevice(), m_vk_pipeline_dynamic.get(), name); } else { for(const auto& [pipeline_id, vk_pipeline_monolithic] : m_vk_pipeline_monolithic_by_id) { - SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), vk_pipeline_monolithic.get(), name); + SetVulkanObjectName(m_vk_render_context.GetVulkanDevice().GetNativeDevice(), vk_pipeline_monolithic.get(), name); } } return true; @@ -411,10 +411,10 @@ vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state render_pattern.GetNativeRenderPass() ); - auto pipe = m_vk_context.GetVulkanDevice().GetNativeDevice().createGraphicsPipelineUnique(nullptr, vk_pipeline_create_info); + auto pipe = m_vk_render_context.GetVulkanDevice().GetNativeDevice().createGraphicsPipelineUnique(nullptr, vk_pipeline_create_info); META_CHECK_ARG_EQUAL_DESCR(pipe.result, vk::Result::eSuccess, "Vulkan pipeline creation has failed"); - SetVulkanObjectName(m_vk_context.GetVulkanDevice().GetNativeDevice(), pipe.value.get(), Base::Object::GetName()); + SetVulkanObjectName(m_vk_render_context.GetVulkanDevice().GetNativeDevice(), pipe.value.get(), Base::Object::GetName()); return std::move(pipe.value); } @@ -424,7 +424,7 @@ void RenderState::OnViewStateChanged(Rhi::IViewState& view_state) for(auto& [pipeline_id, vk_pipeline_monolithic] : m_vk_pipeline_monolithic_by_id) if (std::get<0>(pipeline_id) == &view_state) { - // TODO: add support of delayed destruction of the pipeline state used in executing GPU command buffer + m_vk_render_context.DeferredRelease(std::move(vk_pipeline_monolithic)); vk_pipeline_monolithic = CreateNativePipeline(static_cast(&view_state), std::get<1>(pipeline_id)); } } @@ -441,7 +441,7 @@ void RenderState::OnViewStateDestroyed(Rhi::IViewState& view_state) continue; } - // TODO: add support of delayed destruction of the pipeline state used in executing GPU command buffer + m_vk_render_context.DeferredRelease(std::move(vk_pipeline_it->second)); m_vk_pipeline_monolithic_by_id.erase(vk_pipeline_it); } } From c3804fc474bc9193b10b8e47e9f4bdf6e096bd7a Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Mon, 24 Jul 2023 22:12:45 +0300 Subject: [PATCH 13/64] Fix obsolete Vulkan pipeline destruction --- .../RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index 6ca129218..bde50e480 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -442,7 +442,7 @@ void RenderState::OnViewStateDestroyed(Rhi::IViewState& view_state) } m_vk_render_context.DeferredRelease(std::move(vk_pipeline_it->second)); - m_vk_pipeline_monolithic_by_id.erase(vk_pipeline_it); + vk_pipeline_it = m_vk_pipeline_monolithic_by_id.erase(vk_pipeline_it); } } From 73f612811d9965d0c06fe3c5aa20adb03f0eb65a Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Mon, 24 Jul 2023 22:29:59 +0300 Subject: [PATCH 14/64] Fix Vulkan thread-safety issues in ParallelRendering tutorial --- .../Vulkan/Include/Methane/Graphics/Vulkan/Program.h | 7 +++++-- .../Include/Methane/Graphics/Vulkan/RenderState.h | 9 ++++++--- .../Vulkan/Include/Methane/Graphics/Vulkan/Shader.h | 3 +++ .../Vulkan/Sources/Methane/Graphics/Vulkan/Program.cpp | 10 ++++++++-- .../Sources/Methane/Graphics/Vulkan/RenderState.cpp | 7 +++++++ .../Vulkan/Sources/Methane/Graphics/Vulkan/Shader.cpp | 2 ++ 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Program.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Program.h index 5321a8459..780f4aecd 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Program.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Program.h @@ -27,11 +27,13 @@ Vulkan implementation of the program interface. #include "ProgramBindings.h" #include +#include #include #include #include +#include namespace Methane::Graphics::Vulkan { @@ -68,8 +70,8 @@ class Program final std::vector GetNativeShaderStageCreateInfos() const; vk::PipelineVertexInputStateCreateInfo GetNativeVertexInputStateCreateInfo() const; const std::vector& GetNativeDescriptorSetLayouts() const; - const vk::DescriptorSetLayout& GetNativeDescriptorSetLayout(ArgumentAccessor::Type argument_access_type); - const DescriptorSetLayoutInfo& GetDescriptorSetLayoutInfo(ArgumentAccessor::Type argument_access_type); + const vk::DescriptorSetLayout& GetNativeDescriptorSetLayout(ArgumentAccessor::Type argument_access_type) const; + const DescriptorSetLayoutInfo& GetDescriptorSetLayoutInfo(ArgumentAccessor::Type argument_access_type) const; const vk::PipelineLayout& GetNativePipelineLayout(); const vk::DescriptorSet& GetConstantDescriptorSet(); const vk::DescriptorSet& GetFrameConstantDescriptorSet(Data::Index frame_index); @@ -90,6 +92,7 @@ class Program final vk::UniquePipelineLayout m_vk_unique_pipeline_layout; std::optional m_vk_constant_descriptor_set_opt; std::vector m_vk_frame_constant_descriptor_sets; + TracyLockable(std::mutex, m_mutex); }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h index 234fb36c4..920566f95 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h @@ -26,10 +26,12 @@ Vulkan implementation of the render state interface. #include #include #include +#include #include #include +#include namespace Methane::Graphics::Rhi { @@ -82,9 +84,10 @@ class RenderState final using PipelineId = std::tuple; using MonolithicPipelineById = std::map; - const RenderContext& m_vk_render_context; - vk::UniquePipeline m_vk_pipeline_dynamic; - MonolithicPipelineById m_vk_pipeline_monolithic_by_id; + const RenderContext& m_vk_render_context; + vk::UniquePipeline m_vk_pipeline_dynamic; + MonolithicPipelineById m_vk_pipeline_monolithic_by_id; + TracyLockable(std::mutex, m_mutex); }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Shader.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Shader.h index 5505674b1..8c44d6780 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Shader.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Shader.h @@ -26,10 +26,12 @@ Vulkan implementation of the shader interface. #include #include #include +#include #include #include +#include namespace spirv_cross // NOSONAR { @@ -77,6 +79,7 @@ class Shader final std::vector m_vertex_input_binding_descriptions; std::vector m_vertex_input_attribute_descriptions; bool m_vertex_input_initialized = false; + TracyLockable(std::mutex, m_mutex); }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Program.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Program.cpp index 0ea22806a..cd810221a 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Program.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Program.cpp @@ -101,7 +101,7 @@ const std::vector& Program::GetNativeDescriptorSetLayou return m_vk_descriptor_set_layouts; } -const vk::DescriptorSetLayout& Program::GetNativeDescriptorSetLayout(Rhi::ProgramArgumentAccessType argument_access_type) +const vk::DescriptorSetLayout& Program::GetNativeDescriptorSetLayout(Rhi::ProgramArgumentAccessType argument_access_type) const { META_FUNCTION_TASK(); static const vk::DescriptorSetLayout s_empty_layout; @@ -109,7 +109,7 @@ const vk::DescriptorSetLayout& Program::GetNativeDescriptorSetLayout(Rhi::Progra return layout_info.index_opt ? m_vk_unique_descriptor_set_layouts[*layout_info.index_opt].get() : s_empty_layout; } -const Program::DescriptorSetLayoutInfo& Program::GetDescriptorSetLayoutInfo(Rhi::ProgramArgumentAccessType argument_access_type) +const Program::DescriptorSetLayoutInfo& Program::GetDescriptorSetLayoutInfo(Rhi::ProgramArgumentAccessType argument_access_type) const { META_FUNCTION_TASK(); return m_descriptor_set_layout_info_by_access_type[*magic_enum::enum_index(argument_access_type)]; @@ -118,6 +118,8 @@ const Program::DescriptorSetLayoutInfo& Program::GetDescriptorSetLayoutInfo(Rhi: const vk::PipelineLayout& Program::GetNativePipelineLayout() { META_FUNCTION_TASK(); + std::lock_guard lock(m_mutex); + if (m_vk_unique_pipeline_layout) return m_vk_unique_pipeline_layout.get(); @@ -133,6 +135,8 @@ const vk::PipelineLayout& Program::GetNativePipelineLayout() const vk::DescriptorSet& Program::GetConstantDescriptorSet() { META_FUNCTION_TASK(); + std::lock_guard lock(m_mutex); + if (m_vk_constant_descriptor_set_opt.has_value()) return m_vk_constant_descriptor_set_opt.value(); @@ -148,6 +152,8 @@ const vk::DescriptorSet& Program::GetConstantDescriptorSet() const vk::DescriptorSet& Program::GetFrameConstantDescriptorSet(Data::Index frame_index) { META_FUNCTION_TASK(); + std::lock_guard lock(m_mutex); + if (!m_vk_frame_constant_descriptor_sets.empty()) { META_CHECK_ARG_LESS(frame_index, m_vk_frame_constant_descriptor_sets.size()); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index bde50e480..53a2351af 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -256,6 +256,8 @@ const vk::Pipeline& RenderState::GetNativePipelineMonolithic(ViewState& view_sta { META_FUNCTION_TASK(); META_CHECK_ARG_FALSE_DESCR(IsNativePipelineDynamic(), "dynamic pipeline should be used"); + std::lock_guard lock(m_mutex); + const PipelineId pipeline_id(static_cast(&view_state), render_primitive); const auto pipeline_monolithic_by_id_it = m_vk_pipeline_monolithic_by_id.find(pipeline_id); if (pipeline_monolithic_by_id_it == m_vk_pipeline_monolithic_by_id.end()) @@ -263,6 +265,7 @@ const vk::Pipeline& RenderState::GetNativePipelineMonolithic(ViewState& view_sta view_state.Connect(*this); return m_vk_pipeline_monolithic_by_id.try_emplace(pipeline_id, CreateNativePipeline(&view_state, render_primitive)).first->second.get(); } + return pipeline_monolithic_by_id_it->second.get(); } @@ -421,6 +424,8 @@ vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state void RenderState::OnViewStateChanged(Rhi::IViewState& view_state) { META_FUNCTION_TASK(); + std::lock_guard lock(m_mutex); + for(auto& [pipeline_id, vk_pipeline_monolithic] : m_vk_pipeline_monolithic_by_id) if (std::get<0>(pipeline_id) == &view_state) { @@ -432,6 +437,8 @@ void RenderState::OnViewStateChanged(Rhi::IViewState& view_state) void RenderState::OnViewStateDestroyed(Rhi::IViewState& view_state) { META_FUNCTION_TASK(); + std::lock_guard lock(m_mutex); + for(auto vk_pipeline_it = m_vk_pipeline_monolithic_by_id.begin(); vk_pipeline_it != m_vk_pipeline_monolithic_by_id.end();) { diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Shader.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Shader.cpp index ba8a20d7d..b53ac92d3 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Shader.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Shader.cpp @@ -286,6 +286,8 @@ vk::PipelineVertexInputStateCreateInfo Shader::GetNativeVertexInputStateCreateIn { META_FUNCTION_TASK(); META_CHECK_ARG_EQUAL(GetType(), Rhi::ShaderType::Vertex); + std::lock_guard lock(m_mutex); + if (!m_vertex_input_initialized) InitializeVertexInputDescriptions(program); From dd32c633a365b48fcc7db166cf041474b281f0eb Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Mon, 24 Jul 2023 22:45:24 +0300 Subject: [PATCH 15/64] Modify CMake warning about support of the Vulkan API on MacOS --- CMake/MethaneGlobalOptions.cmake | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CMake/MethaneGlobalOptions.cmake b/CMake/MethaneGlobalOptions.cmake index 32de149d1..963e8aede 100644 --- a/CMake/MethaneGlobalOptions.cmake +++ b/CMake/MethaneGlobalOptions.cmake @@ -86,16 +86,16 @@ elseif(APPLE) set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path") if (METHANE_GFX_API EQUAL METHANE_GFX_VULKAN) - # On Windows and Linux, only Vulkan-Headers are required to build Methane Kit, - # because it is dynamically loading Vulkan library in runtime. Vulkan SDK is not required for build. - message(WARNING "METHANE RHI: Vulkan API is not supported on MacOS, because MoltenVK does not support extension 'VK_EXT_extended_dynamic_state'") - # To enable Vulkan API on MacOS we link statically with MoltenVK framework (translation layer to Metal). - # in order to enable finding Vulkan SDK with MoltenVK framework, set environment variable - # - VULKAN_SDK to full installation path before running CMake generator ($USER_HOME$/VulkanSDK/1.2.182.0/macOS) + # * On Windows and Linux, only Vulkan-Headers are required to build Methane Kit, + # because it is dynamically loading Vulkan library in runtime. Vulkan SDK is not required for build. + message(WARNING "METHANE RHI: Vulkan API is not fully supported on MacOS due to weired crash on submit to Transfer command queue") + # * To enable Vulkan API on MacOS we link statically with MoltenVK framework (translation layer to Metal). + # in order to enable finding Vulkan SDK with MoltenVK framework, environment variable might need to be set: + # - VULKAN_SDK to full installation path before running CMake generator ($HOME/VulkanSDK/1.3.250.1/macOS) find_package(Vulkan REQUIRED) - # To run Vulkan application on MacOS, additional environment variables need to be set for application: - # - VK_ICD_FILENAMES=$USER_HOME$/VulkanSDK/1.2.182.0/macOS/share/vulkan/icd.d/MoltenVK_icd.json - # - VK_LAYER_PATH=$USER_HOME$/VulkanSDK/1.2.182.0/macOS/share/vulkan/explicit_layer.d + # * To run Vulkan application on MacOS, additional environment variables might need to be set for application: + # - VK_ICD_FILENAMES=$HOME/VulkanSDK/1.3.250.1/macOS/share/vulkan/icd.d/MoltenVK_icd.json + # - VK_LAYER_PATH=$HOME/VulkanSDK/1.3.250.1/macOS/share/vulkan/explicit_layer.d endif() else(UNIX) From 6859a71631b100edd20a05d3c300a11d32fbda91 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Mon, 24 Jul 2023 22:49:18 +0300 Subject: [PATCH 16/64] Update Vulkan headers to v1.3.251 --- Externals/VulkanHeaders.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Externals/VulkanHeaders.cmake b/Externals/VulkanHeaders.cmake index 1a02380fa..a3bb566b7 100644 --- a/Externals/VulkanHeaders.cmake +++ b/Externals/VulkanHeaders.cmake @@ -1,5 +1,5 @@ CPMAddPackage( NAME VulkanHeaders GITHUB_REPOSITORY MethanePowered/VulkanHeaders - VERSION 1.3.219 + VERSION 1.3.251 ) From 86500bb5c1df6a367ca169b0e01255fd27478551 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Mon, 24 Jul 2023 23:20:46 +0300 Subject: [PATCH 17/64] Mute Vulkan validation warning for vkCmdPipelineBarrier(): .dstStageMask must not be 0 unless synchronization2 is enabled (appears on Linux only) --- .../RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp index 1186d21f6..81e919791 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp @@ -143,9 +143,10 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(VkDebugUtilsMessageSe // Assert on calling vkBeginCommandBuffer() on active VkCommandBuffer before it has completed. You must check command buffer fence before this call. //assert(callback_data_ptr->messageIdNumber == -2080204129); // VUID-vkBeginCommandBuffer-commandBuffer-00049 - if (callback_data_ptr->messageIdNumber == 648835635 || // UNASSIGNED-khronos-Validation-debug-build-warning-message - callback_data_ptr->messageIdNumber == 767975156 || // UNASSIGNED-BestPractices-vkCreateInstance-specialise-extension - callback_data_ptr->messageIdNumber == -400166253) // UNASSIGNED-CoreValidation-DrawState-QueueForwardProgress + if (callback_data_ptr->messageIdNumber == 648835635 || // UNASSIGNED-khronos-Validation-debug-build-warning-message + callback_data_ptr->messageIdNumber == 767975156 || // UNASSIGNED-BestPractices-vkCreateInstance-specialise-extension + callback_data_ptr->messageIdNumber == -400166253 || // UNASSIGNED-CoreValidation-DrawState-QueueForwardProgress + callback_data_ptr->messageIdNumber == 1630022081) // VUID-vkCmdPipelineBarrier-dstStageMask-03937 (vkCmdPipelineBarrier(): .dstStageMask must not be 0 unless synchronization2 is enabled) return VK_FALSE; if (callback_data_ptr->messageIdNumber == 0 && ( From cdc1123e900fc17906df3e17418926a751496a8c Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Tue, 25 Jul 2023 21:37:31 +0300 Subject: [PATCH 18/64] Fix Vulkan ParallelRenderCommandList command buffers refresh on RenderPass update --- .../Base/ParallelRenderCommandList.cpp | 7 ++-- .../Methane/Graphics/Vulkan/CommandList.hpp | 41 ++++++++++++++----- .../Vulkan/ParallelRenderCommandList.h | 7 ++++ .../Graphics/Vulkan/RenderCommandList.h | 2 +- .../Vulkan/ParallelRenderCommandList.cpp | 28 ++++++++++++- .../Graphics/Vulkan/RenderCommandList.cpp | 12 +++--- 6 files changed, 75 insertions(+), 22 deletions(-) diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp index faeb4ff29..fffd5e5bc 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp @@ -150,11 +150,12 @@ void ParallelRenderCommandList::SetParallelCommandListsCount(uint32_t count) for(uint32_t cmd_list_index = initial_count; cmd_list_index < count; ++cmd_list_index) { m_parallel_command_lists.emplace_back(std::static_pointer_cast(CreateCommandList(false))); - m_parallel_command_lists.back()->SetValidationEnabled(m_is_validation_enabled); - m_parallel_command_lists_refs.emplace_back(*m_parallel_command_lists.back()); + RenderCommandList& render_command_list = *m_parallel_command_lists.back(); + render_command_list.SetValidationEnabled(m_is_validation_enabled); + m_parallel_command_lists_refs.emplace_back(render_command_list); if (!name.empty()) { - m_parallel_command_lists.back()->SetName(GetThreadCommandListName(name, cmd_list_index)); + render_command_list.SetName(GetThreadCommandListName(name, cmd_list_index)); } } } diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp index c0d58104b..5382b747c 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp @@ -64,13 +64,14 @@ class CommandList : CommandListBaseT(std::forward(construct_args)...) , m_vk_device(GetVulkanCommandQueue().GetVulkanContext().GetVulkanDevice().GetNativeDevice()) // NOSONAR , m_vk_unique_command_pool(CreateVulkanCommandPool(GetVulkanCommandQueue().GetFamilyIndex())) + , m_vk_primary_command_buffer_level(vk::CommandBufferLevel::ePrimary) { META_FUNCTION_TASK(); std::fill(m_vk_command_buffer_encoding_flags.begin(), m_vk_command_buffer_encoding_flags.end(), false); std::fill(m_vk_command_buffer_primary_flags.begin(), m_vk_command_buffer_primary_flags.end(), false); InitializePrimaryCommandBuffer(); - SetSecondaryRenderBufferInheritInfo(secondary_render_buffer_inherit_info); + SetCommandBufferInheritInfo(secondary_render_buffer_inherit_info, CommandBufferType::SecondaryRenderPass); InitializeSecondaryCommandBuffers(1U); CommandListBaseT::InitializeTimestampQueries(); @@ -83,6 +84,7 @@ class CommandList : CommandListBaseT(parallel_render_command_list) , m_vk_device(GetVulkanCommandQueue().GetVulkanContext().GetVulkanDevice().GetNativeDevice()) // NOSONAR , m_vk_unique_command_pool(CreateVulkanCommandPool(GetVulkanCommandQueue().GetFamilyIndex())) + , m_vk_primary_command_buffer_level(vk::CommandBufferLevel::ePrimary) , m_debug_group_command_buffer_type(is_beginning_cmd_list ? CommandBufferType::Primary : default_command_buffer_type) { META_FUNCTION_TASK(); @@ -102,7 +104,7 @@ class CommandList else { // Thread render and ending command lists of the parallel rendering do not use primary command buffers - SetSecondaryRenderBufferInheritInfo(secondary_render_buffer_inherit_info); + SetCommandBufferInheritInfo(secondary_render_buffer_inherit_info, CommandBufferType::SecondaryRenderPass); InitializeSecondaryCommandBuffers(0U); } @@ -115,13 +117,14 @@ class CommandList : CommandListBaseT(std::forward(construct_args)...) , m_vk_device(GetVulkanCommandQueue().GetVulkanContext().GetVulkanDevice().GetNativeDevice()) // NOSONAR , m_vk_unique_command_pool(CreateVulkanCommandPool(GetVulkanCommandQueue().GetFamilyIndex())) + , m_vk_primary_command_buffer_level(vk_buffer_level) , m_vk_command_buffer_begin_infos({ vk_begin_info }) { META_FUNCTION_TASK(); std::fill(m_vk_command_buffer_encoding_flags.begin(), m_vk_command_buffer_encoding_flags.end(), false); std::fill(m_vk_command_buffer_primary_flags.begin(), m_vk_command_buffer_primary_flags.end(), false); - InitializePrimaryCommandBuffer(vk_buffer_level); + InitializePrimaryCommandBuffer(); if (vk_buffer_level == vk::CommandBufferLevel::ePrimary) { @@ -256,7 +259,21 @@ class CommandList magic_enum::enum_name(cmd_buffer_type)); return m_vk_unique_command_buffers[cmd_buffer_index].get(); } - + + template + void UpdateCommandBufferInheritInfo(const vk::CommandBufferInheritanceInfo& vk_inherit_info, bool is_parallel) + { + META_FUNCTION_TASK(); + SetCommandBufferInheritInfo(vk_inherit_info, command_buffer_type); + if constexpr (command_buffer_type == CommandBufferType::Primary) + { + InitializePrimaryCommandBuffer(); + } + else + { + InitializeSecondaryCommandBuffers(is_parallel ? 0U : 1U); + } + } protected: bool IsNativeCommitted() const { return m_is_native_committed; } @@ -280,11 +297,12 @@ class CommandList Base::CommandList::GetProgramBindingsPtr(), apply_behavior); } - void SetSecondaryRenderBufferInheritInfo(const vk::CommandBufferInheritanceInfo& secondary_render_buffer_inherit_info) noexcept + void SetCommandBufferInheritInfo(const vk::CommandBufferInheritanceInfo& secondary_render_buffer_inherit_info, + CommandBufferType command_buffer_type) noexcept { META_FUNCTION_TASK(); m_vk_secondary_render_buffer_inherit_info_opt = secondary_render_buffer_inherit_info; - const size_t secondary_render_pass_index = magic_enum::enum_index(CommandBufferType::SecondaryRenderPass).value(); + const size_t secondary_render_pass_index = magic_enum::enum_index(command_buffer_type).value(); const bool is_secondary_command_buffer = !m_vk_command_buffer_primary_flags[secondary_render_pass_index]; m_vk_command_buffer_begin_infos[secondary_render_pass_index] = vk::CommandBufferBeginInfo( is_secondary_command_buffer && secondary_render_buffer_inherit_info.renderPass @@ -302,12 +320,12 @@ class CommandList return m_vk_device.createCommandPoolUnique(vk_command_pool_info); } - void InitializePrimaryCommandBuffer(const vk::CommandBufferLevel& vk_buffer_level = vk::CommandBufferLevel::ePrimary) + void InitializePrimaryCommandBuffer() { META_FUNCTION_TASK(); m_vk_command_buffer_primary_flags[0] = true; m_vk_unique_command_buffers[0] = std::move(m_vk_device.allocateCommandBuffersUnique( - vk::CommandBufferAllocateInfo(m_vk_unique_command_pool.get(), vk_buffer_level, 1U) + vk::CommandBufferAllocateInfo(m_vk_unique_command_pool.get(), m_vk_primary_command_buffer_level, 1U) ).back()); m_vk_unique_command_buffers[0].get().begin(m_vk_command_buffer_begin_infos[0]); @@ -348,9 +366,10 @@ class CommandList } private: - vk::Device m_vk_device; - vk::UniqueCommandPool m_vk_unique_command_pool; - bool m_is_native_committed = false; + vk::Device m_vk_device; + vk::UniqueCommandPool m_vk_unique_command_pool; + bool m_is_native_committed = false; + const vk::CommandBufferLevel m_vk_primary_command_buffer_level; // Unique command buffers and corresponding begin flags are indexed by the value of CommandBufferType enum std::array m_vk_unique_command_buffers; diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h index 9981dadfb..194e0c880 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h @@ -28,6 +28,7 @@ Vulkan implementation of the parallel render command list interface. #include #include +#include namespace Methane::Graphics::Vulkan { @@ -38,6 +39,7 @@ class RenderPass; class ParallelRenderCommandList final : public Base::ParallelRenderCommandList + , private Data::Receiver { public: ParallelRenderCommandList(CommandQueue& command_queue, RenderPass& render_pass); @@ -70,6 +72,11 @@ class ParallelRenderCommandList final private: using SyncCommandList = Vulkan::CommandList; + // IRenderPassCallback + void OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) override; + + void UpdateParallelCommandBuffers(); + RenderCommandList m_beginning_command_list; vk::CommandBufferInheritanceInfo m_vk_ending_inheritance_info; SyncCommandList m_ending_command_list; diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h index 148087090..06948746c 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderCommandList.h @@ -63,10 +63,10 @@ class RenderCommandList final // NOSONAR - inheritance hierarchy is greater than bool IsDynamicStateSupported() const noexcept { return m_is_dynamic_state_supported; } -private: // IRenderPassCallback void OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) override; +private: void UpdatePrimitiveTopology(Primitive primitive); RenderPass& GetVulkanPass(); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp index effd34d72..eb17be4d1 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp @@ -41,7 +41,10 @@ ParallelRenderCommandList::ParallelRenderCommandList(CommandQueue& command_queue , m_ending_command_list(vk::CommandBufferLevel::eSecondary, // Ending command list creates Primary command buffer with Secondary level vk::CommandBufferBeginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit, &m_vk_ending_inheritance_info), static_cast(command_queue), Rhi::CommandListType::Render) -{ } +{ + META_FUNCTION_TASK(); + static_cast&>(render_pass).Connect(*this); +} bool ParallelRenderCommandList::SetName(std::string_view name) { @@ -107,7 +110,12 @@ void ParallelRenderCommandList::SetParallelCommandListsCount(uint32_t count) { META_FUNCTION_TASK(); Base::ParallelRenderCommandList::SetParallelCommandListsCount(count); + UpdateParallelCommandBuffers(); +} +void ParallelRenderCommandList::UpdateParallelCommandBuffers() +{ + META_FUNCTION_TASK(); m_vk_parallel_sync_cmd_buffers.clear(); m_vk_parallel_pass_cmd_buffers.clear(); @@ -184,4 +192,22 @@ Ptr ParallelRenderCommandList::CreateCommandList(bool i return std::make_shared(*this, is_beginning_list); } +void ParallelRenderCommandList::OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) +{ + META_FUNCTION_TASK(); + RenderPass& vulkan_render_pass = GetVulkanPass(); + m_vk_ending_inheritance_info = vk::CommandBufferInheritanceInfo( + vulkan_render_pass.GetVulkanPattern().GetNativeRenderPass(), + 0U, + vulkan_render_pass.GetNativeFrameBuffer()); + m_ending_command_list.UpdateCommandBufferInheritInfo(m_vk_ending_inheritance_info, false); + + for(const Ref& parallel_cmd_list_ref : GetParallelCommandLists()) + { + static_cast(parallel_cmd_list_ref.get()).OnRenderPassUpdated(render_pass); + } + + UpdateParallelCommandBuffers(); +} + } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp index 4a12ea091..b277e6855 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp @@ -60,7 +60,7 @@ static vk::IndexType GetVulkanIndexTypeByStride(Data::Size index_stride_bytes) } } -static vk::CommandBufferInheritanceInfo CreateRenderCommandBufferInheritanceInfo(const RenderPass& render_pass) noexcept +static vk::CommandBufferInheritanceInfo CreateCommandBufferInheritInfo(const RenderPass& render_pass) noexcept { META_FUNCTION_TASK(); return vk::CommandBufferInheritanceInfo( @@ -76,7 +76,7 @@ RenderCommandList::RenderCommandList(CommandQueue& command_queue) { } RenderCommandList::RenderCommandList(CommandQueue& command_queue, RenderPass& render_pass) - : CommandList(CreateRenderCommandBufferInheritanceInfo(render_pass), command_queue, render_pass) + : CommandList(CreateCommandBufferInheritInfo(render_pass), command_queue, render_pass) , m_is_dynamic_state_supported(GetVulkanCommandQueue().GetVulkanDevice().IsDynamicStateSupported()) { META_FUNCTION_TASK(); @@ -84,11 +84,10 @@ RenderCommandList::RenderCommandList(CommandQueue& command_queue, RenderPass& re } RenderCommandList::RenderCommandList(ParallelRenderCommandList& parallel_render_command_list, bool is_beginning_cmd_list) - : CommandList(CreateRenderCommandBufferInheritanceInfo(parallel_render_command_list.GetVulkanPass()), parallel_render_command_list, is_beginning_cmd_list) + : CommandList(CreateCommandBufferInheritInfo(parallel_render_command_list.GetVulkanPass()), parallel_render_command_list, is_beginning_cmd_list) , m_is_dynamic_state_supported(GetVulkanCommandQueue().GetVulkanDevice().IsDynamicStateSupported()) { META_FUNCTION_TASK(); - static_cast&>(parallel_render_command_list.GetVulkanPass()).Connect(*this); } void RenderCommandList::Reset(IDebugGroup* debug_group_ptr) @@ -193,8 +192,9 @@ void RenderCommandList::Commit() void RenderCommandList::OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) { META_FUNCTION_TASK(); - SetSecondaryRenderBufferInheritInfo(CreateRenderCommandBufferInheritanceInfo(static_cast(render_pass))); - InitializeSecondaryCommandBuffers(IsParallel() ? 0U : 1U); + UpdateCommandBufferInheritInfo( + CreateCommandBufferInheritInfo(static_cast(render_pass)), + IsParallel()); } void RenderCommandList::UpdatePrimitiveTopology(Primitive primitive) From c66804427ccb74882b6e6d66c8dfe19bd6cd339c Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Tue, 25 Jul 2023 21:51:21 +0300 Subject: [PATCH 19/64] Fix SonarCloud code analysis issues --- .../Base/Include/Methane/Graphics/Base/ViewState.h | 6 ++++++ .../Base/Sources/Methane/Graphics/Base/ViewState.cpp | 12 +++++++++++- .../Include/Methane/Graphics/RHI/IViewState.h | 4 +--- .../Include/Methane/Graphics/Vulkan/RenderState.h | 2 +- .../Sources/Methane/Graphics/Vulkan/Device.cpp | 2 ++ .../Sources/Methane/Graphics/Vulkan/RenderState.cpp | 2 +- .../Sources/Methane/Graphics/Vulkan/ViewState.cpp | 2 +- 7 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h index 81ccd8c28..1251d592e 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h @@ -42,6 +42,12 @@ class ViewState explicit ViewState(const Settings& settings); ~ViewState() override; + ViewState(const ViewState&) = delete; + ViewState(ViewState&&) noexcept = delete; + + ViewState& operator=(const ViewState&) = delete; + ViewState& operator=(ViewState&&) noexcept = delete; + // IViewState overrides Ptr GetPtr() final { return shared_from_this(); } const Settings& GetSettings() const noexcept final { return m_settings; } diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp index 2106ef6e3..340f03ceb 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ViewState.cpp @@ -28,6 +28,8 @@ Base implementation of the view state interface. #include #include +#include + namespace Methane::Graphics::Base { @@ -52,7 +54,15 @@ ViewState::ViewState(const Settings& settings) ViewState::~ViewState() { META_FUNCTION_TASK(); - Data::Emitter::Emit(&ICallback::OnViewStateDestroyed, *this); + try + { + Data::Emitter::Emit(&ICallback::OnViewStateDestroyed, *this); + } + catch([[maybe_unused]] const std::exception& e) + { + META_LOG("WARNING: Unexpected error during view-state destruction: {}", e.what()); + assert(false); + } } bool ViewState::Reset(const Settings& settings) diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h index 4057b3670..5862b5d69 100644 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IViewState.h @@ -51,7 +51,7 @@ struct IViewStateCallback }; struct IViewState - : virtual Data::IEmitter + : virtual Data::IEmitter // NOSONAR { using Settings = ViewSettings; using ICallback = IViewStateCallback; @@ -65,8 +65,6 @@ struct IViewState virtual bool Reset(const Settings& settings) = 0; virtual bool SetViewports(const Viewports& viewports) = 0; virtual bool SetScissorRects(const ScissorRects& scissor_rects) = 0; - - virtual ~IViewState() = default; }; } // namespace Methane::Graphics::Rhi diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h index 920566f95..9806e1319 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderState.h @@ -75,7 +75,7 @@ class RenderState final const vk::Pipeline& GetNativePipelineMonolithic(const Base::RenderDrawingState& drawing_state); private: - vk::UniquePipeline CreateNativePipeline(const ViewState* viewState = nullptr, Opt renderPrimitive = {}); + vk::UniquePipeline CreateNativePipeline(const ViewState* viewState = nullptr, Opt renderPrimitive = {}) const; // IViewStateCallback overrides void OnViewStateChanged(Rhi::IViewState& view_state) override; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp index 3696d2225..d06b223e5 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp @@ -46,7 +46,9 @@ Vulkan implementation of the device interface. namespace Methane::Graphics::Vulkan { +#ifndef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME #define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset" +#endif static const std::vector g_common_device_extensions{ VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp index 53a2351af..be6a69062 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderState.cpp @@ -277,7 +277,7 @@ const vk::Pipeline& RenderState::GetNativePipelineMonolithic(const Base::RenderD return GetNativePipelineMonolithic(static_cast(*drawing_state.view_state_ptr), drawing_state.primitive_type_opt.value()); } -vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state_ptr, Opt render_primitive_opt) +vk::UniquePipeline RenderState::CreateNativePipeline(const ViewState* view_state_ptr, Opt render_primitive_opt) const { META_FUNCTION_TASK(); const Settings& settings = GetSettings(); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp index c21d54d1b..8101cd161 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ViewState.cpp @@ -137,7 +137,7 @@ bool ViewState::SetScissorRects(const ScissorRects& scissor_rects) void ViewState::Apply(Base::RenderCommandList& command_list) { META_FUNCTION_TASK(); - auto& vulkan_command_list = static_cast(command_list); + const auto& vulkan_command_list = static_cast(command_list); if (!vulkan_command_list.IsDynamicStateSupported()) return; From 8c8c778845061f160adef00a313f1ac437d7fbb8 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Tue, 25 Jul 2023 22:35:09 +0300 Subject: [PATCH 20/64] Fix Vulkan ParallelRenderCommandList debug groups encoding --- .../Vulkan/ParallelRenderCommandList.cpp | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp index eb17be4d1..2b7ca255a 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp @@ -61,34 +61,13 @@ void ParallelRenderCommandList::Reset(IDebugGroup* debug_group_ptr) { META_FUNCTION_TASK(); m_beginning_command_list.Reset(debug_group_ptr); - - if (debug_group_ptr) - { - // Instead of closing debug group in beginning CL commit, we force to close it in ending CL - m_beginning_command_list.ClearOpenDebugGroups(); - - m_ending_command_list.ResetOnce(); - m_ending_command_list.PushOpenDebugGroup(*debug_group_ptr); - } - Base::ParallelRenderCommandList::Reset(debug_group_ptr); } void ParallelRenderCommandList::ResetWithState(Rhi::IRenderState& render_state, IDebugGroup* debug_group_ptr) { META_FUNCTION_TASK(); - m_beginning_command_list.Reset(debug_group_ptr); - - if (debug_group_ptr) - { - // Instead of closing debug group in beginning CL commit, we force to close it in ending CL - m_beginning_command_list.ClearOpenDebugGroups(); - - m_ending_command_list.ResetOnce(); - m_ending_command_list.PushOpenDebugGroup(*debug_group_ptr); - } - Base::ParallelRenderCommandList::ResetWithState(render_state, debug_group_ptr); } From adea64785400e2dce10b7bd7c8dc15581c890449 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Tue, 25 Jul 2023 23:08:48 +0300 Subject: [PATCH 21/64] Fix Vulkan ParallelRenderCommandList execution wait for Frame Image available semaphore --- .../Graphics/Base/ParallelRenderCommandList.h | 2 +- .../Base/ParallelRenderCommandList.cpp | 2 +- .../Graphics/Base/RenderCommandList.cpp | 2 +- .../DirectX/ParallelRenderCommandList.cpp | 2 +- .../Metal/ParallelRenderCommandList.mm | 2 +- .../Vulkan/ParallelRenderCommandList.h | 2 +- .../Graphics/Vulkan/CommandListSet.cpp | 42 +++++++++++++++---- .../Vulkan/ParallelRenderCommandList.cpp | 8 ++-- .../Graphics/Vulkan/RenderCommandList.cpp | 2 +- 9 files changed, 46 insertions(+), 18 deletions(-) diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ParallelRenderCommandList.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ParallelRenderCommandList.h index 95b670102..160f149ba 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ParallelRenderCommandList.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ParallelRenderCommandList.h @@ -73,7 +73,7 @@ class ParallelRenderCommandList // IObject interface bool SetName(std::string_view name) override; - RenderPass& GetPass(); + RenderPass& GetRenderPass() const; protected: static std::string GetParallelCommandListDebugName(std::string_view base_name, std::string_view suffix); diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp index fffd5e5bc..c35a5a4a6 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp @@ -200,7 +200,7 @@ bool ParallelRenderCommandList::SetName(std::string_view name) return true; } -RenderPass& ParallelRenderCommandList::GetPass() +RenderPass& ParallelRenderCommandList::GetRenderPass() const { META_FUNCTION_TASK(); META_CHECK_ARG_NOT_NULL(m_render_pass_ptr); diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp index 765517d5a..dc56ac28d 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderCommandList.cpp @@ -51,7 +51,7 @@ RenderCommandList::RenderCommandList(CommandQueue& command_queue, RenderPass& pa RenderCommandList::RenderCommandList(ParallelRenderCommandList& parallel_render_command_list) : CommandList(static_cast(parallel_render_command_list.GetCommandQueue()), Type::Render) , m_is_parallel(true) - , m_render_pass_ptr(parallel_render_command_list.GetPass().GetPtr()) + , m_render_pass_ptr(parallel_render_command_list.GetRenderPass().GetPtr()) { } Rhi::IRenderPass& RenderCommandList::GetRenderPass() const diff --git a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/ParallelRenderCommandList.cpp index d3691a865..10c81ace2 100644 --- a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/ParallelRenderCommandList.cpp @@ -153,7 +153,7 @@ CommandQueue& ParallelRenderCommandList::GetDirectCommandQueue() RenderPass& ParallelRenderCommandList::GetDirectPass() { META_FUNCTION_TASK(); - return static_cast(GetPass()); + return static_cast(GetRenderPass()); } Ptr ParallelRenderCommandList::CreateCommandList(bool) diff --git a/Modules/Graphics/RHI/Metal/Sources/Methane/Graphics/Metal/ParallelRenderCommandList.mm b/Modules/Graphics/RHI/Metal/Sources/Methane/Graphics/Metal/ParallelRenderCommandList.mm index 3363ff338..72fb8a32e 100644 --- a/Modules/Graphics/RHI/Metal/Sources/Methane/Graphics/Metal/ParallelRenderCommandList.mm +++ b/Modules/Graphics/RHI/Metal/Sources/Methane/Graphics/Metal/ParallelRenderCommandList.mm @@ -77,7 +77,7 @@ RenderPass& ParallelRenderCommandList::GetMetalRenderPass() { META_FUNCTION_TASK(); - return static_cast(GetPass()); + return static_cast(GetRenderPass()); } } // namespace Methane::Graphics::Metal diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h index 194e0c880..1e3689fc2 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/ParallelRenderCommandList.h @@ -63,7 +63,7 @@ class ParallelRenderCommandList final const Vulkan::ICommandList& GetVulkanPrimaryCommandList() const noexcept { return m_beginning_command_list; } CommandQueue& GetVulkanCommandQueue() noexcept; - RenderPass& GetVulkanPass() noexcept; + RenderPass& GetVulkanRenderPass() const noexcept; protected: // ParallelRenderCommandListBase interface diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index a28a95df2..881d9b09b 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -50,20 +50,44 @@ Ptr Rhi::ICommandListSet::Create(const Refs& comm namespace Methane::Graphics::Vulkan { +static Rhi::IRenderPass* GetRenderPassFromCommandList(const Rhi::ICommandList& command_list) +{ + META_FUNCTION_TASK(); + const Rhi::CommandListType cmd_list_type = command_list.GetType(); + + switch(cmd_list_type) + { + case Rhi::CommandListType::Render: + { + const auto& render_cmd_list = dynamic_cast(command_list); + if (render_cmd_list.HasPass()) + return &render_cmd_list.GetRenderPass(); + } break; + + case Rhi::CommandListType::ParallelRender: + { + const auto& parallel_render_cmd_list = dynamic_cast(command_list); + return ¶llel_render_cmd_list.GetRenderPass(); + } break; + + default: + break; + } + + return nullptr; +} + static vk::PipelineStageFlags GetFrameBufferRenderingWaitStages(const Refs& command_list_refs) { META_FUNCTION_TASK(); vk::PipelineStageFlags wait_stages {}; for(const Ref& command_list_ref : command_list_refs) { - if (command_list_ref.get().GetType() != Rhi::CommandListType::Render) - continue; - - const auto& render_command_list = dynamic_cast(command_list_ref.get()); - if (!render_command_list.HasPass()) + const Rhi::IRenderPass* render_pass_ptr = GetRenderPassFromCommandList(command_list_ref.get()); + if (!render_pass_ptr) continue; - for(const Rhi::TextureView& attach_location : render_command_list.GetRenderPass().GetSettings().attachments) + for(const Rhi::TextureView& attach_location : render_pass_ptr->GetSettings().attachments) { const Rhi::TextureType attach_texture_type = attach_location.GetTexture().GetSettings().type; if (attach_texture_type == Rhi::TextureType::FrameBuffer) @@ -164,7 +188,11 @@ const std::vector& CommandListSet::GetWaitSemaphores() return vk_wait_semaphores; m_vk_wait_semaphores = vk_wait_semaphores; - m_vk_wait_semaphores.push_back(dynamic_cast(command_queue.GetVulkanContext()).GetNativeFrameImageAvailableSemaphore()); + const Opt& frame_index_opt = GetFrameIndex(); + const RenderContext& render_context = dynamic_cast(command_queue.GetVulkanContext()); + m_vk_wait_semaphores.push_back( + frame_index_opt ? render_context.GetNativeFrameImageAvailableSemaphore(*frame_index_opt) + : render_context.GetNativeFrameImageAvailableSemaphore()); return m_vk_wait_semaphores; } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp index 2b7ca255a..13db33d00 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp @@ -119,7 +119,7 @@ void ParallelRenderCommandList::Commit() const vk::CommandBuffer& vk_beginning_primary_cmd_buffer = m_beginning_command_list.GetNativeCommandBuffer(CommandBufferType::Primary); vk_beginning_primary_cmd_buffer.executeCommands(m_vk_parallel_sync_cmd_buffers); - RenderPass& render_pass = GetVulkanPass(); + RenderPass& render_pass = GetVulkanRenderPass(); render_pass.Begin(m_beginning_command_list); vk_beginning_primary_cmd_buffer.executeCommands(m_vk_parallel_pass_cmd_buffers); @@ -160,10 +160,10 @@ CommandQueue& ParallelRenderCommandList::GetVulkanCommandQueue() noexcept return static_cast(GetCommandQueue()); } -RenderPass& ParallelRenderCommandList::GetVulkanPass() noexcept +RenderPass& ParallelRenderCommandList::GetVulkanRenderPass() const noexcept { META_FUNCTION_TASK(); - return static_cast(GetPass()); + return static_cast(GetRenderPass()); } Ptr ParallelRenderCommandList::CreateCommandList(bool is_beginning_list) @@ -174,7 +174,7 @@ Ptr ParallelRenderCommandList::CreateCommandList(bool i void ParallelRenderCommandList::OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) { META_FUNCTION_TASK(); - RenderPass& vulkan_render_pass = GetVulkanPass(); + RenderPass& vulkan_render_pass = GetVulkanRenderPass(); m_vk_ending_inheritance_info = vk::CommandBufferInheritanceInfo( vulkan_render_pass.GetVulkanPattern().GetNativeRenderPass(), 0U, diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp index b277e6855..866f81fd3 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderCommandList.cpp @@ -84,7 +84,7 @@ RenderCommandList::RenderCommandList(CommandQueue& command_queue, RenderPass& re } RenderCommandList::RenderCommandList(ParallelRenderCommandList& parallel_render_command_list, bool is_beginning_cmd_list) - : CommandList(CreateCommandBufferInheritInfo(parallel_render_command_list.GetVulkanPass()), parallel_render_command_list, is_beginning_cmd_list) + : CommandList(CreateCommandBufferInheritInfo(parallel_render_command_list.GetVulkanRenderPass()), parallel_render_command_list, is_beginning_cmd_list) , m_is_dynamic_state_supported(GetVulkanCommandQueue().GetVulkanDevice().IsDynamicStateSupported()) { META_FUNCTION_TASK(); From 2618d17e352b41e8cbc0a1dcec4fe59a0f2d25cb Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Tue, 25 Jul 2023 23:55:00 +0300 Subject: [PATCH 22/64] Fix SonarCloud code analysis issue for ViewState --- .../Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h index 1251d592e..6e1284c90 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/ViewState.h @@ -33,7 +33,7 @@ namespace Methane::Graphics::Base class RenderCommandList; -class ViewState +class ViewState // NOSONAR - class requires destructor : public Rhi::IViewState , public Data::Emitter , public std::enable_shared_from_this From 87e515ce766dee3863721c113e4352d568c62201 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Tue, 25 Jul 2023 23:59:35 +0300 Subject: [PATCH 23/64] Allow CI Build workflow to run in forks by removing cron schedule; prevent CI Sonar Scan workflow to run in forks by adding cron schedule --- .github/workflows/ci-build.yml | 4 ++-- .github/workflows/ci-codeql-scan.yml | 2 +- .github/workflows/ci-sonar-scan.yml | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 19275eaa8..4335aea0c 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -25,8 +25,8 @@ on: - 'CMake/**' - 'CMakeLists.txt' - 'CMakePresets.json' - schedule: - - cron: '20 23 * * 3' + +# Do not schedule workflow with "cron", so that it could run in GitHub forks (scheduled workflows are disabled in forks) env: product_ver_major: 0 diff --git a/.github/workflows/ci-codeql-scan.yml b/.github/workflows/ci-codeql-scan.yml index f61065136..a0e22c883 100644 --- a/.github/workflows/ci-codeql-scan.yml +++ b/.github/workflows/ci-codeql-scan.yml @@ -26,7 +26,7 @@ on: - 'CMakeLists.txt' - 'CMakePresets.json' schedule: - - cron: '20 23 * * 3' + - cron: '20 23 * * 3' # Scheduled workflow will not run in GitHub forks jobs: analyze: diff --git a/.github/workflows/ci-sonar-scan.yml b/.github/workflows/ci-sonar-scan.yml index 9f9bbd3f6..309c0ae7b 100644 --- a/.github/workflows/ci-sonar-scan.yml +++ b/.github/workflows/ci-sonar-scan.yml @@ -32,6 +32,8 @@ on: - 'CMake/**' - 'CMakeLists.txt' - 'CMakePresets.json' + schedule: + - cron: '20 23 * * 3' # Scheduled workflow will not run in GitHub forks env: product_ver_major: 0 From 551b0a83c4b26bd3af8e3d540b5400a28cb3b562 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Wed, 26 Jul 2023 00:44:24 +0300 Subject: [PATCH 24/64] Fix SonarCloud code analysis issues --- .../Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp | 4 +--- .../Sources/Methane/Graphics/Vulkan/CommandListSet.cpp | 5 +++-- .../Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp index 5382b747c..70c23049a 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandList.hpp @@ -64,7 +64,6 @@ class CommandList : CommandListBaseT(std::forward(construct_args)...) , m_vk_device(GetVulkanCommandQueue().GetVulkanContext().GetVulkanDevice().GetNativeDevice()) // NOSONAR , m_vk_unique_command_pool(CreateVulkanCommandPool(GetVulkanCommandQueue().GetFamilyIndex())) - , m_vk_primary_command_buffer_level(vk::CommandBufferLevel::ePrimary) { META_FUNCTION_TASK(); std::fill(m_vk_command_buffer_encoding_flags.begin(), m_vk_command_buffer_encoding_flags.end(), false); @@ -84,7 +83,6 @@ class CommandList : CommandListBaseT(parallel_render_command_list) , m_vk_device(GetVulkanCommandQueue().GetVulkanContext().GetVulkanDevice().GetNativeDevice()) // NOSONAR , m_vk_unique_command_pool(CreateVulkanCommandPool(GetVulkanCommandQueue().GetFamilyIndex())) - , m_vk_primary_command_buffer_level(vk::CommandBufferLevel::ePrimary) , m_debug_group_command_buffer_type(is_beginning_cmd_list ? CommandBufferType::Primary : default_command_buffer_type) { META_FUNCTION_TASK(); @@ -369,7 +367,7 @@ class CommandList vk::Device m_vk_device; vk::UniqueCommandPool m_vk_unique_command_pool; bool m_is_native_committed = false; - const vk::CommandBufferLevel m_vk_primary_command_buffer_level; + const vk::CommandBufferLevel m_vk_primary_command_buffer_level = vk::CommandBufferLevel::ePrimary; // Unique command buffers and corresponding begin flags are indexed by the value of CommandBufferType enum std::array m_vk_unique_command_buffers; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index 881d9b09b..16ac3eed6 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -53,9 +53,10 @@ namespace Methane::Graphics::Vulkan static Rhi::IRenderPass* GetRenderPassFromCommandList(const Rhi::ICommandList& command_list) { META_FUNCTION_TASK(); - const Rhi::CommandListType cmd_list_type = command_list.GetType(); - switch(cmd_list_type) + + switch(const Rhi::CommandListType cmd_list_type = command_list.GetType(); + cmd_list_type) { case Rhi::CommandListType::Render: { diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp index 13db33d00..9d15899d1 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ParallelRenderCommandList.cpp @@ -174,7 +174,7 @@ Ptr ParallelRenderCommandList::CreateCommandList(bool i void ParallelRenderCommandList::OnRenderPassUpdated(const Rhi::IRenderPass& render_pass) { META_FUNCTION_TASK(); - RenderPass& vulkan_render_pass = GetVulkanRenderPass(); + const RenderPass& vulkan_render_pass = GetVulkanRenderPass(); m_vk_ending_inheritance_info = vk::CommandBufferInheritanceInfo( vulkan_render_pass.GetVulkanPattern().GetNativeRenderPass(), 0U, From 20778767ee01b3a88ae0ddc6cd72ffb3fc7bd334 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Wed, 26 Jul 2023 00:45:14 +0300 Subject: [PATCH 25/64] Fix Vulkan::Headers CMake target duplication when VULKAN_SDK path is defined --- Externals/VulkanHeaders.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Externals/VulkanHeaders.cmake b/Externals/VulkanHeaders.cmake index a3bb566b7..143072a5a 100644 --- a/Externals/VulkanHeaders.cmake +++ b/Externals/VulkanHeaders.cmake @@ -1,3 +1,8 @@ +if(TARGET Vulkan::Headers) + # Vulkan::Headers target can be added by find_package(Vulkan) when VULKAN_SDK environment variable defines valid path + return() +endif() + CPMAddPackage( NAME VulkanHeaders GITHUB_REPOSITORY MethanePowered/VulkanHeaders From 37c264cceb50ea66f82112871fd1ec4164c9fcf1 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Wed, 26 Jul 2023 22:38:10 +0300 Subject: [PATCH 26/64] Fix Vulkan validation error: image owner transition barrier with undefined layout --- .../Sources/Methane/Graphics/Vulkan/ResourceBarriers.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ResourceBarriers.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ResourceBarriers.cpp index 0e5b90358..82ffdd996 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ResourceBarriers.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/ResourceBarriers.cpp @@ -304,11 +304,12 @@ void ResourceBarriers::AddImageMemoryOwnerChangeBarrier(const Texture& texture, if (family_index_before == family_index_after) return; + const vk::ImageLayout image_layout = IResource::GetNativeImageLayoutByResourceState(texture.GetState()); m_vk_default_barrier.vk_image_memory_barriers.emplace_back( vk::AccessFlagBits::eMemoryWrite, vk::AccessFlagBits::eMemoryRead, - vk::ImageLayout::eUndefined, - vk::ImageLayout::eUndefined, + image_layout, + image_layout, family_index_before, family_index_after, texture.GetNativeImage(), From 21fa1c6955cbac131aeaee28b5ff06d3081a62d9 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Wed, 26 Jul 2023 22:59:28 +0300 Subject: [PATCH 27/64] Fix SonarCloud code analysis issue --- Build/Windows/Build.bat | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Build/Windows/Build.bat b/Build/Windows/Build.bat index a08c7cfbe..5aa769d41 100644 --- a/Build/Windows/Build.bat +++ b/Build/Windows/Build.bat @@ -1,5 +1,5 @@ @REM Run 'Build.bat' with optional arguments: -@REM --vs2022 - build with Visual Studio 2022 instead of Visual Studio 2019 by default +@REM --vs2019 - build with Visual Studio 2019 instead of Visual Studio 2019 by default @REM --win32 - 32-bit build instead of 64-bit by default @REM --debug - Debug build instead of Release build by default @REM --vulkan - use Vulkan graphics API instead of DirectX 12 by default @@ -20,8 +20,8 @@ SET START_DIR=%cd% REM Parse command line options :options_loop IF NOT "%1"=="" ( - IF "%1"=="--vs2022" ( - SET USE_VS2022=1 + IF "%1"=="--vs2019" ( + SET USE_VS2019=1 ) IF "%1"=="--win32" ( SET WIN32_BUILD=1 @@ -65,10 +65,10 @@ IF DEFINED DEBUG_BUILD ( SET BUILD_TYPE=Release ) -IF DEFINED USE_VS2022 ( - SET CMAKE_GENERATOR=Visual Studio 17 2022 -) ELSE ( +IF DEFINED USE_VS2019 ( SET CMAKE_GENERATOR=Visual Studio 16 2019 +) ELSE ( + SET CMAKE_GENERATOR=Visual Studio 17 2022 ) SET CONFIG_DIR=%OUTPUT_DIR%\VisualStudio\%ARCH_TYPE%-MSVC-%GFX_API%-%BUILD_TYPE%-SLN @@ -80,15 +80,20 @@ SET CMAKE_FLAGS= ^ -DMETHANE_VERSION_MINOR=%BUILD_VERSION_MINOR% ^ -DMETHANE_VERSION_PATCH=%BUILD_VERSION_PATCH% ^ -DMETHANE_GFX_VULKAN_ENABLED:BOOL=%VULKAN_API_ENABLED% ^ - -DMETHANE_SHADERS_CODEVIEW_ENABLED:BOOL=ON ^ + -DMETHANE_APPS_BUILD_ENABLED:BOOL=ON ^ + -DMETHANE_TESTS_BUILD_ENABLED:BOOL=ON ^ + -DMETHANE_UNITY_BUILD_ENABLED:BOOL=ON ^ -DMETHANE_RHI_PIMPL_INLINE_ENABLED:BOOL=ON ^ + -DMETHANE_CHECKS_ENABLED:BOOL=ON ^ + -DMETHANE_SHADERS_CODEVIEW_ENABLED:BOOL=ON ^ -DMETHANE_PRECOMPILED_HEADERS_ENABLED:BOOL=ON ^ -DMETHANE_RUN_TESTS_DURING_BUILD:BOOL=OFF ^ + -DMETHANE_CODE_COVERAGE_ENABLED:BOOL=OFF ^ -DMETHANE_COMMAND_DEBUG_GROUPS_ENABLED:BOOL=ON ^ -DMETHANE_LOGGING_ENABLED:BOOL=OFF ^ -DMETHANE_OPEN_IMAGE_IO_ENABLED:BOOL=OFF ^ -DMETHANE_SCOPE_TIMERS_ENABLED:BOOL=OFF ^ - -DMETHANE_ITT_INSTRUMENTATION_ENABLED:BOOL=ON ^ + -DMETHANE_ITT_INSTRUMENTATION_ENABLED:BOOL=OFF ^ -DMETHANE_ITT_METADATA_ENABLED:BOOL=OFF ^ -DMETHANE_GPU_INSTRUMENTATION_ENABLED:BOOL=OFF ^ -DMETHANE_TRACY_PROFILING_ENABLED:BOOL=OFF ^ From 78f9f7eb7b7a60e0d06af5e60153eecb25317da8 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Wed, 26 Jul 2023 23:55:22 +0300 Subject: [PATCH 28/64] Fix SonarCloud code analysis issue --- .../Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index 16ac3eed6..0e6500e66 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -190,7 +190,7 @@ const std::vector& CommandListSet::GetWaitSemaphores() m_vk_wait_semaphores = vk_wait_semaphores; const Opt& frame_index_opt = GetFrameIndex(); - const RenderContext& render_context = dynamic_cast(command_queue.GetVulkanContext()); + const auto& render_context = dynamic_cast(command_queue.GetVulkanContext()); m_vk_wait_semaphores.push_back( frame_index_opt ? render_context.GetNativeFrameImageAvailableSemaphore(*frame_index_opt) : render_context.GetNativeFrameImageAvailableSemaphore()); From b1b09460b2b35f6b62791b98d1f93d6ad9d753a4 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 29 Jul 2023 20:41:38 +0300 Subject: [PATCH 29/64] Add Vulkan RHI support of ErrorSurfaceLostKHR on acquireNextImageKHR --- .../Methane/Graphics/Vulkan/RenderContext.h | 5 ++- .../Methane/Graphics/Vulkan/RenderContext.cpp | 41 +++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h index 121da4154..8e5475579 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h @@ -105,12 +105,13 @@ class RenderContext final // NOSONAR - this class requires destructor void ResetNativeSwapchain(); void ResetNativeObjectNames() const; - const vk::Device m_vk_device; + const Methane::Platform::AppEnvironment m_app_env; + const vk::Device m_vk_device; #ifdef __APPLE__ // MacOS metal app view with swap-chain implementation to work via MoltenVK AppViewMetal* m_metal_view; #endif - const vk::UniqueSurfaceKHR m_vk_unique_surface; + vk::UniqueSurfaceKHR m_vk_unique_surface; vk::UniqueSwapchainKHR m_vk_unique_swapchain; vk::Format m_vk_frame_format; vk::Extent2D m_vk_frame_extent; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index 00714e9c6..2d8acea99 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -37,7 +37,6 @@ Vulkan implementation of the render context interface. #include #include #include - #include #include @@ -52,6 +51,7 @@ namespace Methane::Graphics::Vulkan RenderContext::RenderContext(const Methane::Platform::AppEnvironment& app_env, Device& device, tf::Executor& parallel_executor, const Rhi::RenderContextSettings& settings) : Context(device, parallel_executor, settings) + , m_app_env(app_env) , m_vk_device(device.GetNativeDevice()) , m_vk_unique_surface(Platform::CreateVulkanSurfaceForWindow(static_cast(Rhi::ISystem::Get()).GetNativeInstance(), app_env)) { } @@ -237,14 +237,31 @@ uint32_t RenderContext::GetNextFrameBufferIndex() { META_FUNCTION_TASK(); uint32_t next_image_index = 0; - const vk::Semaphore& vk_image_available_semaphore = m_vk_frame_semaphores_pool[Base::RenderContext::GetFrameBufferIndex()].get(); - if (const vk::Result image_acquire_result = m_vk_device.acquireNextImageKHR(GetNativeSwapchain(), std::numeric_limits::max(), vk_image_available_semaphore, {}, &next_image_index); - image_acquire_result != vk::Result::eSuccess && - image_acquire_result != vk::Result::eSuboptimalKHR) - throw InvalidArgumentException("RenderContext::GetNextFrameBufferIndex", "image_acquire_result", image_acquire_result, "failed to acquire next image"); - - m_vk_frame_image_available_semaphores[next_image_index % m_vk_frame_image_available_semaphores.size()] = vk_image_available_semaphore; - return next_image_index % Base::RenderContext::GetSettings().frame_buffers_count; + const uint32_t frame_semaphore_index = Base::RenderContext::GetFrameIndex() % m_vk_frame_semaphores_pool.size(); + const vk::Semaphore& vk_image_available_semaphore = m_vk_frame_semaphores_pool[frame_semaphore_index].get(); + + switch (const vk::Result image_acquire_result = m_vk_device.acquireNextImageKHR(GetNativeSwapchain(), std::numeric_limits::max(), + vk_image_available_semaphore, {}, &next_image_index); + image_acquire_result) + { + case vk::Result::eSuccess: + case vk::Result::eSuboptimalKHR: + break; + + case vk::Result::eErrorSurfaceLostKHR: + m_vk_unique_surface.release(); + m_vk_unique_surface = Platform::CreateVulkanSurfaceForWindow(static_cast(Rhi::ISystem::Get()).GetNativeInstance(), m_app_env); + ResetNativeSwapchain(); + break; + + default: + throw InvalidArgumentException("RenderContext::GetNextFrameBufferIndex", "image_acquire_result", + image_acquire_result, "failed to acquire next image"); + } + + const uint32_t next_frame_index = next_image_index % Base::RenderContext::GetSettings().frame_buffers_count; + m_vk_frame_image_available_semaphores[next_frame_index] = vk_image_available_semaphore; + return next_frame_index; } vk::SurfaceFormatKHR RenderContext::ChooseSwapSurfaceFormat(const std::vector& available_formats) const @@ -323,9 +340,9 @@ void RenderContext::InitializeNativeSwapchain() } const Device::SwapChainSupport swap_chain_support = GetVulkanDevice().GetSwapChainSupportForSurface(GetNativeSurface()); - const vk::SurfaceFormatKHR swap_surface_format = ChooseSwapSurfaceFormat(swap_chain_support.formats); - const vk::PresentModeKHR swap_present_mode = ChooseSwapPresentMode(swap_chain_support.present_modes); - const vk::Extent2D swap_extent = ChooseSwapExtent(swap_chain_support.capabilities); + const vk::SurfaceFormatKHR swap_surface_format = ChooseSwapSurfaceFormat(swap_chain_support.formats); + const vk::PresentModeKHR swap_present_mode = ChooseSwapPresentMode(swap_chain_support.present_modes); + const vk::Extent2D swap_extent = ChooseSwapExtent(swap_chain_support.capabilities); uint32_t image_count = std::max(swap_chain_support.capabilities.minImageCount, GetSettings().frame_buffers_count); if (swap_chain_support.capabilities.maxImageCount && image_count > swap_chain_support.capabilities.maxImageCount) From c08ffe0e8d3af1e8393695b572782ff89e844958 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 29 Jul 2023 23:31:12 +0300 Subject: [PATCH 30/64] Add SetObjectName template function for safe string formatted naming of RHI objects --- Apps/01-HelloTriangle/HelloTriangleApp.cpp | 2 +- Apps/01-HelloTriangle/README.md | 2 +- Apps/02-HelloCube/HelloCubeApp.cpp | 8 ++-- Apps/03-TexturedCube/TexturedCubeApp.cpp | 6 +-- Apps/04-ShadowCube/ShadowCubeApp.cpp | 28 +++++++------- Apps/05-Typography/TypographyApp.cpp | 2 +- Apps/06-CubeMapArray/CubeMapArrayApp.cpp | 10 ++--- .../ParallelRenderingApp.cpp | 10 ++--- .../Methane/Tutorials/TextureLabeler.cpp | 9 +++-- .../App/Include/Methane/Graphics/App.hpp | 2 +- .../App/Include/Methane/Graphics/AppBase.h | 2 - .../App/Sources/Methane/Graphics/AppBase.cpp | 6 --- .../Include/Methane/Graphics/MeshBuffers.hpp | 3 +- .../Methane/Graphics/MeshBuffersBase.cpp | 5 ++- .../Sources/Methane/Graphics/ScreenQuad.cpp | 9 +++-- .../Methane/Graphics/Base/CommandKit.cpp | 13 ++++--- .../Sources/Methane/Graphics/Base/Context.cpp | 10 ++--- Modules/Graphics/RHI/Interface/CMakeLists.txt | 1 + .../Methane/Graphics/RHI/ObjectName.hpp | 38 +++++++++++++++++++ .../Include/Methane/Graphics/Vulkan/Utils.hpp | 3 +- .../Methane/UserInterface/FontImpl.hpp | 3 +- .../Sources/Methane/UserInterface/Text.cpp | 11 +++--- 22 files changed, 111 insertions(+), 72 deletions(-) create mode 100644 Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp diff --git a/Apps/01-HelloTriangle/HelloTriangleApp.cpp b/Apps/01-HelloTriangle/HelloTriangleApp.cpp index 3c7d76602..789acb6c5 100644 --- a/Apps/01-HelloTriangle/HelloTriangleApp.cpp +++ b/Apps/01-HelloTriangle/HelloTriangleApp.cpp @@ -87,7 +87,7 @@ class HelloTriangleApp final // NOSONAR - destructor required for (HelloTriangleFrame& frame : GetFrames()) { frame.render_cmd_list = cmd_queue.CreateRenderCommandList(frame.screen_pass); - frame.render_cmd_list.SetName(IndexedName("Render Triangle", frame.index)); + rhi::SetObjectName(frame.render_cmd_list, "Render Triangle {}", frame.index); frame.execute_cmd_list_set = Rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/01-HelloTriangle/README.md b/Apps/01-HelloTriangle/README.md index 84383f0b4..0d58ea30b 100644 --- a/Apps/01-HelloTriangle/README.md +++ b/Apps/01-HelloTriangle/README.md @@ -138,7 +138,7 @@ public: for (HelloTriangleFrame& frame : GetFrames()) { frame.render_cmd_list = cmd_queue.CreateRenderCommandList(frame.screen_pass); - frame.render_cmd_list.SetName(IndexedName("Render Triangle", frame.index)); + rhi::SetObjectName(frame.render_cmd_list, "Render Triangle {}", frame.index)); frame.execute_cmd_list_set = Rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/02-HelloCube/HelloCubeApp.cpp b/Apps/02-HelloCube/HelloCubeApp.cpp index 08bedff54..064b458dd 100644 --- a/Apps/02-HelloCube/HelloCubeApp.cpp +++ b/Apps/02-HelloCube/HelloCubeApp.cpp @@ -204,23 +204,23 @@ class HelloCubeApp final // NOSONAR - destructor required #ifdef UNIFORMS_BUFFER_ENABLED // Create uniforms buffer with volatile parameters for frame rendering frame.uniforms_buffer = GetRenderContext().CreateBuffer(Rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, false, true)); - frame.uniforms_buffer.SetName(IndexedName("Uniforms Buffer", frame.index)); + rhi::SetObjectName(frame.uniforms_buffer, "Uniforms Buffer {}", frame.index); // Configure program resource bindings frame.program_bindings = m_render_state.GetProgram().CreateBindings({ { { Rhi::ShaderType::Vertex, "g_uniforms" }, { { frame.uniforms_buffer.GetInterface() } } } }, frame.index); - frame.program_bindings.SetName(IndexedName("Cube Bindings {}", frame.index)); + rhi::SetObjectName(frame.program_bindings, "Cube Bindings {} {}", frame.index); #else // Create vertex buffers for each frame Rhi::Buffer vertex_buffer = GetRenderContext().CreateBuffer(Rhi::BufferSettings::ForVertexBuffer(m_cube_mesh.GetVertexDataSize(), m_cube_mesh.GetVertexSize(), true)); - vertex_buffer.SetName(IndexedName("Cube Vertex Buffer", frame.index)); + rhi::SetObjectName(vertex_buffer, "Cube Vertex Buffer {}", frame.index); frame.vertex_buffer_set = Rhi::BufferSet(Rhi::BufferType::Vertex, { vertex_buffer }); #endif // Create command list for rendering frame.render_cmd_list = m_render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - frame.render_cmd_list.SetName(IndexedName("Cube Rendering", frame.index)); + rhi::SetObjectName(frame.render_cmd_list, "Cube Rendering {}", frame.index); frame.execute_cmd_list_set = Rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/03-TexturedCube/TexturedCubeApp.cpp b/Apps/03-TexturedCube/TexturedCubeApp.cpp index 8447124bf..5d4760313 100644 --- a/Apps/03-TexturedCube/TexturedCubeApp.cpp +++ b/Apps/03-TexturedCube/TexturedCubeApp.cpp @@ -157,7 +157,7 @@ void TexturedCubeApp::Init() { // Create uniforms buffer with volatile parameters for frame rendering frame.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, false, true)); - frame.uniforms_buffer.SetName(IndexedName("Uniforms Buffer", frame.index)); + rhi::SetObjectName(frame.uniforms_buffer, "Uniforms Buffer {}", frame.index); // Configure program resource bindings frame.program_bindings = m_render_state.GetProgram().CreateBindings({ @@ -166,11 +166,11 @@ void TexturedCubeApp::Init() { { rhi::ShaderType::Pixel, "g_texture" }, { { m_cube_texture.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - frame.program_bindings.SetName(IndexedName("Cube Bindings", frame.index)); + rhi::SetObjectName(frame.program_bindings, "Cube Bindings {}", frame.index); // Create command list for rendering frame.render_cmd_list = render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - frame.render_cmd_list.SetName(IndexedName("Cube Rendering", frame.index)); + rhi::SetObjectName(frame.render_cmd_list, "Cube Rendering {}", frame.index); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/04-ShadowCube/ShadowCubeApp.cpp b/Apps/04-ShadowCube/ShadowCubeApp.cpp index 9b8d33424..016b31ae1 100644 --- a/Apps/04-ShadowCube/ShadowCubeApp.cpp +++ b/Apps/04-ShadowCube/ShadowCubeApp.cpp @@ -161,7 +161,7 @@ void ShadowCubeApp::Init() ), GetScreenRenderPattern() }; - final_state_settings.program.SetName("Textured, Shadows & Lighting"); + SetObjectName(final_state_settings.program, "Textured, Shadows & Lighting"); final_state_settings.depth.enabled = true; m_final_pass.render_state = render_context.CreateRenderState( final_state_settings); @@ -205,7 +205,7 @@ void ShadowCubeApp::Init() ), m_shadow_pass_pattern }; - shadow_state_settings.program.SetName("Vertex Only: Textured, Lighting"); + SetObjectName(shadow_state_settings.program, "Vertex Only: Textured, Lighting"); shadow_state_settings.depth.enabled = true; m_shadow_pass.render_state = render_context.CreateRenderState( shadow_state_settings); @@ -227,33 +227,33 @@ void ShadowCubeApp::Init() { // Create uniforms buffer with volatile parameters for the whole scene rendering frame.scene_uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(scene_uniforms_data_size, false, true)); - frame.scene_uniforms_buffer.SetName(IndexedName("Scene Uniforms Buffer", frame.index)); + rhi::SetObjectName(frame.scene_uniforms_buffer, "Scene Uniforms Buffer {}", frame.index); // ========= Shadow Pass Resources ========= // Create uniforms buffer for Cube rendering in Shadow pass frame.shadow_pass.cube.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - frame.shadow_pass.cube.uniforms_buffer.SetName(IndexedName("Cube Uniforms Buffer for Shadow Pass", frame.index)); + rhi::SetObjectName(frame.shadow_pass.cube.uniforms_buffer, "Cube Uniforms Buffer for Shadow Pass {}", frame.index); // Create uniforms buffer for Floor rendering in Shadow pass frame.shadow_pass.floor.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - frame.shadow_pass.floor.uniforms_buffer.SetName(IndexedName("Floor Uniforms Buffer for Shadow Pass", frame.index)); + rhi::SetObjectName(frame.shadow_pass.floor.uniforms_buffer, "Floor Uniforms Buffer for Shadow Pass {}", frame.index); // Shadow-pass resource bindings for cube rendering frame.shadow_pass.cube.program_bindings = shadow_state_settings.program.CreateBindings({ { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.shadow_pass.cube.uniforms_buffer.GetInterface() } } }, }, frame.index); - frame.shadow_pass.cube.program_bindings.SetName(IndexedName("Cube Shadow-Pass Bindings {}", frame.index)); + rhi::SetObjectName(frame.shadow_pass.cube.program_bindings, "Cube Shadow-Pass Bindings {} {}", frame.index); // Shadow-pass resource bindings for floor rendering frame.shadow_pass.floor.program_bindings = shadow_state_settings.program.CreateBindings({ { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.shadow_pass.floor.uniforms_buffer.GetInterface() } } }, }, frame.index); - frame.shadow_pass.floor.program_bindings.SetName(IndexedName("Floor Shadow-Pass Bindings {}", frame.index)); + rhi::SetObjectName(frame.shadow_pass.floor.program_bindings, "Floor Shadow-Pass Bindings {} {}", frame.index); // Create depth texture for shadow map rendering frame.shadow_pass.rt_texture = render_context.CreateTexture(shadow_texture_settings); - frame.shadow_pass.rt_texture.SetName(IndexedName("Shadow Map", frame.index)); + rhi::SetObjectName(frame.shadow_pass.rt_texture, "Shadow Map {}", frame.index); // Create shadow pass configuration with depth attachment frame.shadow_pass.render_pass = m_shadow_pass_pattern.CreateRenderPass({ @@ -263,17 +263,17 @@ void ShadowCubeApp::Init() // Create render pass and command list for shadow pass rendering frame.shadow_pass.cmd_list = render_cmd_queue.CreateRenderCommandList(frame.shadow_pass.render_pass); - frame.shadow_pass.cmd_list.SetName(IndexedName("Shadow-Map Rendering", frame.index)); + rhi::SetObjectName(frame.shadow_pass.cmd_list, "Shadow-Map Rendering {}", frame.index); // ========= Final Pass Resources ========= // Create uniforms buffer for Cube rendering in Final pass frame.final_pass.cube.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - frame.final_pass.cube.uniforms_buffer.SetName(IndexedName("Cube Uniforms Buffer for Final Pass", frame.index)); + rhi::SetObjectName(frame.final_pass.cube.uniforms_buffer, "Cube Uniforms Buffer for Final Pass {}", frame.index); // Create uniforms buffer for Floor rendering in Final pass frame.final_pass.floor.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - frame.final_pass.floor.uniforms_buffer.SetName(IndexedName("Floor Uniforms Buffer for Final Pass", frame.index)); + rhi::SetObjectName(frame.final_pass.floor.uniforms_buffer, "Floor Uniforms Buffer for Final Pass {}", frame.index); // Final-pass resource bindings for cube rendering frame.final_pass.cube.program_bindings = final_state_settings.program.CreateBindings({ @@ -285,14 +285,14 @@ void ShadowCubeApp::Init() { { rhi::ShaderType::Pixel, "g_texture" }, { { m_cube_buffers_ptr->GetTexture().GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_texture_sampler"}, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - frame.final_pass.cube.program_bindings.SetName(IndexedName("Cube Final-Pass Bindings {}", frame.index)); + rhi::SetObjectName(frame.final_pass.cube.program_bindings, "Cube Final-Pass Bindings {} {}", frame.index); // Final-pass resource bindings for floor rendering - patched a copy of cube bindings frame.final_pass.floor.program_bindings = rhi::ProgramBindings(frame.final_pass.cube.program_bindings, { { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.final_pass.floor.uniforms_buffer.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_texture" }, { { m_floor_buffers_ptr->GetTexture().GetInterface() } } }, }, frame.index); - frame.final_pass.floor.program_bindings.SetName(IndexedName("Floor Final-Pass Bindings {}", frame.index)); + rhi::SetObjectName(frame.final_pass.floor.program_bindings, "Floor Final-Pass Bindings {} {}", frame.index); // Bind final pass RT texture and pass to the frame buffer texture and final pass. frame.final_pass.rt_texture = frame.screen_texture; @@ -300,7 +300,7 @@ void ShadowCubeApp::Init() // Create render pass and command list for final pass rendering frame.final_pass.cmd_list = render_cmd_queue.CreateRenderCommandList(frame.final_pass.render_pass); - frame.final_pass.cmd_list.SetName(IndexedName("Final Scene Rendering", frame.index)); + rhi::SetObjectName(frame.final_pass.cmd_list, "Final Scene Rendering {}", frame.index); // Rendering command lists sequence frame.execute_cmd_list_set = rhi::CommandListSet({ diff --git a/Apps/05-Typography/TypographyApp.cpp b/Apps/05-Typography/TypographyApp.cpp index 7a88c942c..239752c12 100644 --- a/Apps/05-Typography/TypographyApp.cpp +++ b/Apps/05-Typography/TypographyApp.cpp @@ -216,7 +216,7 @@ void TypographyApp::Init() for(TypographyFrame& frame : GetFrames()) { frame.render_cmd_list = GetRenderContext().GetRenderCommandKit().GetQueue().CreateRenderCommandList(frame.screen_pass); - frame.render_cmd_list.SetName(IndexedName("Text Rendering", frame.index)); + rhi::SetObjectName(frame.render_cmd_list, "Text Rendering {}", frame.index); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/06-CubeMapArray/CubeMapArrayApp.cpp b/Apps/06-CubeMapArray/CubeMapArrayApp.cpp index f5f814eb8..65459bd85 100644 --- a/Apps/06-CubeMapArray/CubeMapArrayApp.cpp +++ b/Apps/06-CubeMapArray/CubeMapArrayApp.cpp @@ -171,7 +171,7 @@ void CubeMapArrayApp::Init() { // Create uniforms buffer with volatile parameters for frame rendering frame.cube.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, false, true)); - frame.cube.uniforms_buffer.SetName(IndexedName("Uniforms Buffer", frame.index)); + rhi::SetObjectName(frame.cube.uniforms_buffer, "Uniforms Buffer {}", frame.index); // Configure program resource bindings frame.cube.program_bindings = m_render_state.GetProgram().CreateBindings({ @@ -179,19 +179,19 @@ void CubeMapArrayApp::Init() { { rhi::ShaderType::Pixel, "g_texture_array" }, { { m_cube_buffers_ptr->GetTexture().GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - frame.cube.program_bindings.SetName(IndexedName("Cube Bindings", frame.index)); + rhi::SetObjectName(frame.cube.program_bindings, "Cube Bindings {}", frame.index); // Create uniforms buffer for Sky-Box rendering frame.sky_box.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(gfx::SkyBox::GetUniformsSize(), false, true)); - frame.sky_box.uniforms_buffer.SetName(IndexedName("Sky-box Uniforms Buffer", frame.index)); + rhi::SetObjectName(frame.sky_box.uniforms_buffer, "Sky-box Uniforms Buffer {}", frame.index); // Resource bindings for Sky-Box rendering frame.sky_box.program_bindings = m_sky_box.CreateProgramBindings(frame.sky_box.uniforms_buffer, frame.index); - frame.sky_box.program_bindings.SetName(IndexedName("Space Sky-Box Bindings {}", frame.index)); + rhi::SetObjectName(frame.sky_box.program_bindings, "Space Sky-Box Bindings {} {}", frame.index); // Create command list for rendering frame.render_cmd_list = render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - frame.render_cmd_list.SetName(IndexedName("Cube Rendering", frame.index)); + rhi::SetObjectName(frame.render_cmd_list, "Cube Rendering {}", frame.index); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp index 8285b9b23..3a1aebde8 100644 --- a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp +++ b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp @@ -193,7 +193,7 @@ void ParallelRenderingApp::Init() { // Create buffer for uniforms array related to all cube instances frame.cubes_array.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, true, true)); - frame.cubes_array.uniforms_buffer.SetName(IndexedName("Uniforms Buffer", frame.index)); + rhi::SetObjectName(frame.cubes_array.uniforms_buffer, "Uniforms Buffer {}", frame.index); // Configure program resource bindings frame.cubes_array.program_bindings_per_instance.resize(cubes_count); @@ -202,7 +202,7 @@ void ParallelRenderingApp::Init() { { rhi::ShaderType::Pixel, "g_texture_array" }, { { m_texture_array.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - frame.cubes_array.program_bindings_per_instance[0].SetName(fmt::format("Cube 0 Bindings {}", frame.index)); + SetObjectName(frame.cubes_array.program_bindings_per_instance[0], "Cube 0 Bindings {}", frame.index); program_bindings_task_flow.for_each_index(1U, cubes_count, 1U, [this, &frame, uniform_data_size](const uint32_t cube_index) @@ -214,7 +214,7 @@ void ParallelRenderingApp::Init() { { frame.cubes_array.uniforms_buffer.GetInterface(), m_cube_array_buffers_ptr->GetUniformsBufferOffset(cube_index), uniform_data_size } } } }, frame.index); - cube_program_bindings.SetName(fmt::format("Cube {} Bindings {}", cube_index, frame.index)); + SetObjectName(cube_program_bindings, "Cube {} Bindings {}", cube_index, frame.index); }); if (m_settings.parallel_rendering_enabled) @@ -223,14 +223,14 @@ void ParallelRenderingApp::Init() frame.parallel_render_cmd_list = render_cmd_queue.CreateParallelRenderCommandList(frame.screen_pass); frame.parallel_render_cmd_list.SetParallelCommandListsCount(m_settings.GetActiveRenderThreadCount()); frame.parallel_render_cmd_list.SetValidationEnabled(false); - frame.parallel_render_cmd_list.SetName(IndexedName("Parallel Cubes Rendering", frame.index)); + rhi::SetObjectName(frame.parallel_render_cmd_list, "Parallel Cubes Rendering {}", frame.index); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.parallel_render_cmd_list.GetInterface() }, frame.index); } else { // Create serial command list for rendering to the screen pass frame.serial_render_cmd_list = render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - frame.serial_render_cmd_list.SetName(IndexedName("Serial Cubes Rendering", frame.index)); + rhi::SetObjectName(frame.serial_render_cmd_list, "Serial Cubes Rendering {}", frame.index); frame.serial_render_cmd_list.SetValidationEnabled(false); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.serial_render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp b/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp index 0da9fa145..60de0956f 100644 --- a/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp +++ b/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp @@ -26,6 +26,7 @@ Renders text labels to the faces of cube-map texture array #include #include #include +#include #include #include #include @@ -101,7 +102,7 @@ TextureLabeler::TextureLabeler(gui::Context& gui_context, const gui::FontContext }); const std::string_view rt_texture_name = m_rt_texture.GetName(); - m_texture_face_render_pattern.SetName(fmt::format("Texture '{}' Face Render Pattern", rt_texture_name)); + SetObjectName(m_texture_face_render_pattern, "Texture '{}' Face Render Pattern", rt_texture_name); gui::Text::SettingsUtf32 slice_text_settings { @@ -136,10 +137,10 @@ TextureLabeler::TextureLabeler(gui::Context& gui_context, const gui::FontContext { rhi::TextureView(rt_texture.GetInterface(), rhi::SubResource::Index(depth_index, array_index), {}, rhi::TextureDimensionType::Tex2D) }, rt_texture_settings.dimensions.AsRectSize() }); - slice.render_pass.SetName(fmt::format("Texture '{}' Slice {}:{} Render Pass", rt_texture_name, array_index, depth_index)); + SetObjectName(slice.render_pass, "Texture '{}' Slice {}:{} Render Pass", rt_texture_name, array_index, depth_index); slice.render_cmd_list = m_gui_context.GetRenderCommandQueue().CreateRenderCommandList(slice.render_pass); - slice.render_cmd_list.SetName(fmt::format("Render Texture '{}' Slice {}:{} Label", rt_texture_name, array_index, depth_index)); + SetObjectName(slice.render_cmd_list, "Render Texture '{}' Slice {}:{} Label", rt_texture_name, array_index, depth_index); slice_render_cmd_list_refs.emplace_back(slice.render_cmd_list.GetInterface()); slice_text_settings.name = fmt::format("Texture '{}' Slice {}:{} Label Text", rt_texture_name, array_index, depth_index); @@ -173,7 +174,7 @@ TextureLabeler::TextureLabeler(gui::Context& gui_context, const gui::FontContext }); m_ending_render_pass = m_ending_render_pattern.CreateRenderPass({ { }, rt_texture_settings.dimensions.AsRectSize() }); m_ending_render_cmd_list = m_gui_context.GetRenderCommandQueue().CreateRenderCommandList(m_ending_render_pass); - m_ending_render_cmd_list.SetName(fmt::format("Render Texture State Transition", rt_texture_name)); + SetObjectName(m_ending_render_cmd_list, "Render Texture State Transition", rt_texture_name); m_ending_resource_barriers = rhi::ResourceBarriers({ { m_rt_texture.GetInterface(), rhi::ResourceState::RenderTarget, rt_texture_final_state } }); diff --git a/Modules/Graphics/App/Include/Methane/Graphics/App.hpp b/Modules/Graphics/App/Include/Methane/Graphics/App.hpp index 1fff59143..25d28fc06 100644 --- a/Modules/Graphics/App/Include/Methane/Graphics/App.hpp +++ b/Modules/Graphics/App/Include/Methane/Graphics/App.hpp @@ -98,7 +98,7 @@ class App // Create color texture for frame buffer frame.screen_texture = render_context.CreateTexture(Rhi::TextureSettings::ForFrameBuffer(render_context.GetSettings(), frame.index)); - frame.screen_texture.SetName(IndexedName("Frame Buffer", frame.index)); + rhi::SetObjectName(frame.screen_texture, "Frame Buffer {}", frame.index); // Configure render pass: color, depth, stencil attachments and shader access frame.screen_pass = CreateScreenRenderPass(frame.screen_texture); diff --git a/Modules/Graphics/App/Include/Methane/Graphics/AppBase.h b/Modules/Graphics/App/Include/Methane/Graphics/AppBase.h index 7b1a63f1a..5334de912 100644 --- a/Modules/Graphics/App/Include/Methane/Graphics/AppBase.h +++ b/Modules/Graphics/App/Include/Methane/Graphics/AppBase.h @@ -112,8 +112,6 @@ class AppBase // NOSONAR ImageLoader& GetImageLoader() noexcept { return m_image_loader; } Data::AnimationsPool& GetAnimations() noexcept { return m_animations; } - static std::string IndexedName(const std::string& base_name, uint32_t index); - private: Graphics::IApp::Settings m_settings; Rhi::RenderContextSettings m_initial_context_settings; diff --git a/Modules/Graphics/App/Sources/Methane/Graphics/AppBase.cpp b/Modules/Graphics/App/Sources/Methane/Graphics/AppBase.cpp index 274763cb6..5abc105e6 100644 --- a/Modules/Graphics/App/Sources/Methane/Graphics/AppBase.cpp +++ b/Modules/Graphics/App/Sources/Methane/Graphics/AppBase.cpp @@ -409,10 +409,4 @@ void AppBase::OnContextInitialized(Rhi::IContext&) SetBaseAnimationsEnabled(m_restore_animations_enabled); } -std::string AppBase::IndexedName(const std::string& base_name, uint32_t index) -{ - META_FUNCTION_TASK(); - return fmt::format("{} {}", base_name, index); -} - } // namespace Methane::Graphics diff --git a/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp b/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp index f3f1c40cd..c4d2062d2 100644 --- a/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp +++ b/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp @@ -26,6 +26,7 @@ Mesh buffers with texture extension structure. #include "MeshBuffersBase.h" #include +#include #include #include #include @@ -195,7 +196,7 @@ class TexturedMeshBuffers SetSubsetTexture(texture, 0U); if (texture.IsInitialized()) { - texture.SetName(fmt::format("{} Texture", MeshBuffers::GetMeshName())); + SetObjectName(texture, "{} Texture", MeshBuffers::GetMeshName()); } } diff --git a/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp b/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp index a5a6cd145..64790f583 100644 --- a/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp +++ b/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp @@ -25,6 +25,7 @@ Mesh buffers base implementation class. #include #include #include +#include #include #include @@ -52,7 +53,7 @@ MeshBuffersBase::MeshBuffersBase(const Rhi::CommandQueue& render_cmd_queue, cons Rhi::BufferSettings::ForVertexBuffer( mesh_data.GetVertexDataSize(), mesh_data.GetVertexSize())); - vertex_buffer.SetName(fmt::format("{} Vertex Buffer", mesh_name)); + SetObjectName(vertex_buffer, "{} Vertex Buffer", mesh_name); vertex_buffer.SetData(render_cmd_queue, { mesh_data.GetVertexData(), mesh_data.GetVertexDataSize() @@ -63,7 +64,7 @@ MeshBuffersBase::MeshBuffersBase(const Rhi::CommandQueue& render_cmd_queue, cons Rhi::BufferSettings::ForIndexBuffer( mesh_data.GetIndexDataSize(), GetIndexFormat(mesh_data.GetIndex(0)))); - m_index_buffer.SetName(fmt::format("{} Index Buffer", mesh_name)); + SetObjectName(m_index_buffer, "{} Index Buffer", mesh_name); m_index_buffer.SetData(render_cmd_queue, { reinterpret_cast(mesh_data.GetIndices().data()), // NOSONAR mesh_data.GetIndexDataSize() diff --git a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp index e286ff8ca..bf8422b0f 100644 --- a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp +++ b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp @@ -34,6 +34,7 @@ Screen Quad rendering primitive. #include #include #include +#include #include #include #include @@ -154,7 +155,7 @@ class ScreenQuad::Impl }), render_pattern }; - state_settings.program.SetName(fmt::format("{} Shading", quad_name)); + SetObjectName(state_settings.program, "{} Shading", quad_name); state_settings.depth.enabled = false; state_settings.depth.write_enabled = false; state_settings.rasterizer.is_front_counter_clockwise = true; @@ -193,7 +194,7 @@ class ScreenQuad::Impl render_context.GetObjectRegistry().AddGraphicsObject(m_texture_sampler.GetInterface()); } - m_texture.SetName(fmt::format("{} Screen-Quad Texture", m_settings.name)); + SetObjectName(m_texture, "{} Screen-Quad Texture", m_settings.name); } static const std::string s_vertex_buffer_name = "Screen-Quad Vertex Buffer"; @@ -241,7 +242,7 @@ class ScreenQuad::Impl m_const_buffer = render_context.CreateBuffer( Rhi::BufferSettings::ForConstantBuffer(static_cast(sizeof(hlslpp::ScreenQuadConstants)))); - m_const_buffer.SetName(fmt::format("{} Screen-Quad Constants Buffer", m_settings.name)); + SetObjectName(m_const_buffer, "{} Screen-Quad Constants Buffer", m_settings.name); Rhi::ProgramBindings::ResourceViewsByArgument program_binding_resource_views = { { { Rhi::ShaderType::Pixel, "g_constants" }, { { m_const_buffer.GetInterface() } } } @@ -254,7 +255,7 @@ class ScreenQuad::Impl } m_const_program_bindings = m_render_state.GetProgram().CreateBindings(program_binding_resource_views); - m_const_program_bindings.SetName(fmt::format("{} Screen-Quad Constant Bindings", m_settings.name)); + SetObjectName(m_const_program_bindings, "{} Screen-Quad Constant Bindings", m_settings.name); UpdateConstantsBuffer(); } diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp index b57655ee2..c72c361ed 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp @@ -32,6 +32,7 @@ Methane command kit implementation. #include #include #include +#include #include #include @@ -87,20 +88,20 @@ bool CommandKit::SetName(std::string_view name) return false; if (m_cmd_queue_ptr) - m_cmd_queue_ptr->SetName(fmt::format("{} Command Queue", GetName())); + SetObjectName(*m_cmd_queue_ptr, "{} Command Queue", GetName()); for(size_t cmd_list_index = 0; cmd_list_index < m_cmd_list_ptrs.size(); ++cmd_list_index) { const Ptr& cmd_list_ptr = m_cmd_list_ptrs[cmd_list_index]; if (cmd_list_ptr) - cmd_list_ptr->SetName(fmt::format("{} Command List {}", GetName(), cmd_list_index)); + SetObjectName(*cmd_list_ptr, "{} Command List {}", GetName(), cmd_list_index); } for(size_t fence_index = 0; fence_index < m_fence_ptrs.size(); ++fence_index) { const Ptr& fence_ptr = m_fence_ptrs[fence_index]; if (fence_ptr) - fence_ptr->SetName(fmt::format("{} Fence {}", GetName(), fence_index)); + SetObjectName(*fence_ptr, "{} Fence {}", GetName(), fence_index); } return true; @@ -113,7 +114,7 @@ Rhi::ICommandQueue& CommandKit::GetQueue() const return *m_cmd_queue_ptr; m_cmd_queue_ptr = Rhi::ICommandQueue::Create(m_context, m_cmd_list_type); - m_cmd_queue_ptr->SetName(fmt::format("{} Command Queue", GetName())); + SetObjectName(*m_cmd_queue_ptr, "{} Command Queue", GetName()); return *m_cmd_queue_ptr; } @@ -151,7 +152,7 @@ Rhi::ICommandList& CommandKit::GetList(Rhi::CommandListId cmd_list_id = 0U) cons default: META_UNEXPECTED_ARG(m_cmd_list_type); } - cmd_list_ptr->SetName(fmt::format("{} Helper List {}", GetName(), GetCommandListNameById(cmd_list_id))); + SetObjectName(*cmd_list_ptr, "{} Helper List {}", GetName(), GetCommandListNameById(cmd_list_id)); return *cmd_list_ptr; } @@ -214,7 +215,7 @@ Rhi::IFence& CommandKit::GetFence(Rhi::CommandListId fence_id) const return *fence_ptr; fence_ptr = Rhi::IFence::Create(GetQueue()); - fence_ptr->SetName(fmt::format("{} Fence {}", GetName(), fence_id)); + SetObjectName(*fence_ptr, "{} Fence {}", GetName(), fence_id); return *fence_ptr; } diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp index 76d911db8..39d8cf338 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp @@ -26,8 +26,8 @@ Base implementation of the context interface. #include #include #include - #include +#include #include #include @@ -164,7 +164,7 @@ void Context::Initialize(Device& device, bool is_callback_emitted) if (const std::string_view context_name = GetName(); !context_name.empty()) { - m_device_ptr->SetName(fmt::format("{} Device", context_name)); + SetObjectName(*m_device_ptr, "{} Device", context_name); } if (is_callback_emitted) @@ -181,7 +181,7 @@ Rhi::ICommandKit& Context::GetDefaultCommandKit(Rhi::CommandListType type) const return *cmd_kit_ptr; cmd_kit_ptr = Rhi::ICommandKit::Create(*this, type); - cmd_kit_ptr->SetName(fmt::format("{} {}", GetName(), g_default_command_kit_names[magic_enum::enum_index(type).value()])); + SetObjectName(*cmd_kit_ptr, "{} {}", GetName(), g_default_command_kit_names[magic_enum::enum_index(type).value()]); m_default_command_kit_ptr_by_queue[std::addressof(cmd_kit_ptr->GetQueue())] = cmd_kit_ptr; return *cmd_kit_ptr; @@ -232,11 +232,11 @@ bool Context::SetName(std::string_view name) if (!Object::SetName(name)) return false; - GetBaseDevice().SetName(fmt::format("{} Device", name)); + SetObjectName(GetBaseDevice(), "{} Device", name); for(const Ptr& cmd_kit_ptr : m_default_command_kit_ptrs) { if (cmd_kit_ptr) - cmd_kit_ptr->SetName(fmt::format("{} {}", name, g_default_command_kit_names[magic_enum::enum_index(cmd_kit_ptr->GetListType()).value()])); + SetObjectName(*cmd_kit_ptr, "{} {}", name, g_default_command_kit_names[magic_enum::enum_index(cmd_kit_ptr->GetListType()).value()]); } return true; } diff --git a/Modules/Graphics/RHI/Interface/CMakeLists.txt b/Modules/Graphics/RHI/Interface/CMakeLists.txt index ad56fc0da..22f174341 100644 --- a/Modules/Graphics/RHI/Interface/CMakeLists.txt +++ b/Modules/Graphics/RHI/Interface/CMakeLists.txt @@ -38,6 +38,7 @@ list(APPEND HEADERS ${INCLUDE_DIR}/IParallelRenderCommandList.h ${INCLUDE_DIR}/IQueryPool.h ${INCLUDE_DIR}/IDescriptorManager.h + ${INCLUDE_DIR}/ObjectName.hpp ${INCLUDE_DIR}/TypeFormatters.hpp ) diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp new file mode 100644 index 000000000..069623c93 --- /dev/null +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp @@ -0,0 +1,38 @@ +/****************************************************************************** + +Copyright 2019-2020 Evgeny Gorodetskiy + +Licensed under the Apache License, Version 2.0 (the "License"), +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +******************************************************************************* + +FILE: Methane/Graphics/RHI/ObjectName.hpp +Methane graphics RHI object naming utility function + +******************************************************************************/ + +#pragma once + +#include + +namespace Methane::Graphics::Rhi +{ + +template +bool SetObjectName(ObjectType& object, FormatType&& format, ArgTypes&& ... args) +{ + const std::string formatted_name = fmt::format(std::forward(format), std::forward(args)...); + return object.SetName(formatted_name); +} + +} // namespace Methane::Graphics::Rhi diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp index 269b60f55..1c99a1938 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp @@ -24,7 +24,7 @@ Methane graphics utils for Vulkan API. #pragma once #include - +#include #include #include @@ -36,6 +36,7 @@ template void SetVulkanObjectName(const vk::Device& vk_device, const VulkanObjectType& vk_object, const char* name) { META_FUNCTION_TASK(); + Methane::Platform::PrintToDebugOutput(name); vk_device.setDebugUtilsObjectNameEXT( vk::DebugUtilsObjectNameInfoEXT( VulkanObjectType::objectType, diff --git a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp index 8976b6a2d..51b8c788b 100644 --- a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp +++ b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp @@ -31,6 +31,7 @@ Font implementation. #include #include #include +#include #include #include #include @@ -497,7 +498,7 @@ class Font::Impl // NOSONAR - class destructor is required, class has more than rhi::TextureSettings::ForImage( gfx::Dimensions(m_atlas_pack_ptr->GetSize()), std::nullopt, gfx::PixelFormat::R8Unorm, false)); - atlas_texture.SetName(fmt::format("{} Font Atlas", m_settings.description.name)); + SetObjectName(atlas_texture, "{} Font Atlas", m_settings.description.name); if (deferred_data_init) { render_context.RequestDeferredAction(rhi::IContext::DeferredAction::CompleteInitialization); diff --git a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp index 3301d929f..bb8413b01 100644 --- a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp +++ b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp @@ -40,6 +40,7 @@ Methane text rendering primitive. #include #include #include +#include #include #include #include @@ -190,7 +191,7 @@ class TextFrameResources const Data::Size vertex_buffer_size = vertices_data_size * reservation_multiplier; rhi::Buffer vertex_buffer; vertex_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForVertexBuffer(vertex_buffer_size, text_mesh.GetVertexSize())); - vertex_buffer.SetName(fmt::format("{} Text Vertex Buffer {}", text_name, m_frame_index)); + SetObjectName(vertex_buffer, "{} Text Vertex Buffer {}", text_name, m_frame_index); m_vertex_buffer_set = rhi::BufferSet(rhi::BufferType::Vertex, { vertex_buffer }); } m_vertex_buffer_set[0].SetData(render_context.GetRenderCommandKit().GetQueue(), { @@ -208,7 +209,7 @@ class TextFrameResources { const Data::Size index_buffer_size = vertices_data_size * reservation_multiplier; m_index_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForIndexBuffer(index_buffer_size, gfx::PixelFormat::R16Uint)); - m_index_buffer.SetName(fmt::format("{} Text Index Buffer {}", text_name, m_frame_index)); + SetObjectName(m_index_buffer, "{} Text Index Buffer {}", text_name, m_frame_index); } m_index_buffer.SetData(render_context.GetRenderCommandKit().GetQueue(), { @@ -241,7 +242,7 @@ class TextFrameResources if (!m_uniforms_buffer.IsInitialized()) { m_uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size)); - m_uniforms_buffer.SetName(fmt::format("{} Text Uniforms Buffer {}", text_name, m_frame_index)); + SetObjectName(m_uniforms_buffer, "{} Text Uniforms Buffer {}", text_name, m_frame_index); if (m_program_bindings.IsInitialized()) { @@ -271,7 +272,7 @@ class TextFrameResources { { rhi::ShaderType::Pixel, "g_texture" }, { { m_atlas_texture.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { atlas_sampler.GetInterface() } } }, }); - m_program_bindings.SetName(fmt::format("{} Text Bindings {}", text_name, m_frame_index)); + SetObjectName(m_program_bindings, "{} Text Bindings {}", text_name, m_frame_index); } }; @@ -655,7 +656,7 @@ class Text::Impl // NOSONAR - class destructor is required if (!m_const_buffer.IsInitialized()) { m_const_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(static_cast(sizeof(hlslpp::TextConstants)))); - m_const_buffer.SetName(fmt::format("{} Text Constants Buffer", m_settings.name)); + SetObjectName(m_const_buffer, "{} Text Constants Buffer", m_settings.name); } const rhi::Texture& atlas_texture = m_font.GetAtlasTexture(render_context); From 89f264d9b6a72dd1e0584de203ee54bd7d2b561d Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 30 Jul 2023 16:58:02 +0300 Subject: [PATCH 31/64] Fix crashes on Vulkan debug object name change --- Apps/02-HelloCube/HelloCubeApp.cpp | 2 +- Apps/04-ShadowCube/ShadowCubeApp.cpp | 8 ++++---- Apps/06-CubeMapArray/CubeMapArrayApp.cpp | 2 +- .../RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp | 4 +++- .../Sources/Methane/Graphics/Vulkan/RenderContext.cpp | 8 +++++--- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Apps/02-HelloCube/HelloCubeApp.cpp b/Apps/02-HelloCube/HelloCubeApp.cpp index 064b458dd..34f7f66f5 100644 --- a/Apps/02-HelloCube/HelloCubeApp.cpp +++ b/Apps/02-HelloCube/HelloCubeApp.cpp @@ -210,7 +210,7 @@ class HelloCubeApp final // NOSONAR - destructor required frame.program_bindings = m_render_state.GetProgram().CreateBindings({ { { Rhi::ShaderType::Vertex, "g_uniforms" }, { { frame.uniforms_buffer.GetInterface() } } } }, frame.index); - rhi::SetObjectName(frame.program_bindings, "Cube Bindings {} {}", frame.index); + rhi::SetObjectName(frame.program_bindings, "Cube Bindings {}", frame.index); #else // Create vertex buffers for each frame Rhi::Buffer vertex_buffer = GetRenderContext().CreateBuffer(Rhi::BufferSettings::ForVertexBuffer(m_cube_mesh.GetVertexDataSize(), m_cube_mesh.GetVertexSize(), true)); diff --git a/Apps/04-ShadowCube/ShadowCubeApp.cpp b/Apps/04-ShadowCube/ShadowCubeApp.cpp index 016b31ae1..1614559a0 100644 --- a/Apps/04-ShadowCube/ShadowCubeApp.cpp +++ b/Apps/04-ShadowCube/ShadowCubeApp.cpp @@ -243,13 +243,13 @@ void ShadowCubeApp::Init() frame.shadow_pass.cube.program_bindings = shadow_state_settings.program.CreateBindings({ { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.shadow_pass.cube.uniforms_buffer.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.shadow_pass.cube.program_bindings, "Cube Shadow-Pass Bindings {} {}", frame.index); + rhi::SetObjectName(frame.shadow_pass.cube.program_bindings, "Cube Shadow-Pass Bindings {}", frame.index); // Shadow-pass resource bindings for floor rendering frame.shadow_pass.floor.program_bindings = shadow_state_settings.program.CreateBindings({ { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.shadow_pass.floor.uniforms_buffer.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.shadow_pass.floor.program_bindings, "Floor Shadow-Pass Bindings {} {}", frame.index); + rhi::SetObjectName(frame.shadow_pass.floor.program_bindings, "Floor Shadow-Pass Bindings {}", frame.index); // Create depth texture for shadow map rendering frame.shadow_pass.rt_texture = render_context.CreateTexture(shadow_texture_settings); @@ -285,14 +285,14 @@ void ShadowCubeApp::Init() { { rhi::ShaderType::Pixel, "g_texture" }, { { m_cube_buffers_ptr->GetTexture().GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_texture_sampler"}, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.final_pass.cube.program_bindings, "Cube Final-Pass Bindings {} {}", frame.index); + rhi::SetObjectName(frame.final_pass.cube.program_bindings, "Cube Final-Pass Bindings {}", frame.index); // Final-pass resource bindings for floor rendering - patched a copy of cube bindings frame.final_pass.floor.program_bindings = rhi::ProgramBindings(frame.final_pass.cube.program_bindings, { { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.final_pass.floor.uniforms_buffer.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_texture" }, { { m_floor_buffers_ptr->GetTexture().GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.final_pass.floor.program_bindings, "Floor Final-Pass Bindings {} {}", frame.index); + rhi::SetObjectName(frame.final_pass.floor.program_bindings, "Floor Final-Pass Bindings {}", frame.index); // Bind final pass RT texture and pass to the frame buffer texture and final pass. frame.final_pass.rt_texture = frame.screen_texture; diff --git a/Apps/06-CubeMapArray/CubeMapArrayApp.cpp b/Apps/06-CubeMapArray/CubeMapArrayApp.cpp index 65459bd85..f1b59b172 100644 --- a/Apps/06-CubeMapArray/CubeMapArrayApp.cpp +++ b/Apps/06-CubeMapArray/CubeMapArrayApp.cpp @@ -187,7 +187,7 @@ void CubeMapArrayApp::Init() // Resource bindings for Sky-Box rendering frame.sky_box.program_bindings = m_sky_box.CreateProgramBindings(frame.sky_box.uniforms_buffer, frame.index); - rhi::SetObjectName(frame.sky_box.program_bindings, "Space Sky-Box Bindings {} {}", frame.index); + rhi::SetObjectName(frame.sky_box.program_bindings, "Space Sky-Box Bindings {}", frame.index); // Create command list for rendering frame.render_cmd_list = render_cmd_queue.CreateRenderCommandList(frame.screen_pass); diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp index 1c99a1938..a6165ee75 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp @@ -36,7 +36,9 @@ template void SetVulkanObjectName(const vk::Device& vk_device, const VulkanObjectType& vk_object, const char* name) { META_FUNCTION_TASK(); - Methane::Platform::PrintToDebugOutput(name); + if (!vk_object) + return; + vk_device.setDebugUtilsObjectNameEXT( vk::DebugUtilsObjectNameInfoEXT( VulkanObjectType::objectType, diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index 2d8acea99..8ac693fb5 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -419,7 +419,9 @@ void RenderContext::ResetNativeObjectNames() const if (context_name.empty()) return; - SetVulkanObjectName(m_vk_device, m_vk_unique_surface.get(), context_name.data()); + // NOTE: Do not set name of the m_vk_unique_surface because it was not created with m_vk_device, + // and attempt to set name of the unrelated object may cause crash on some platforms (SIGSEGV on Linux). + SetVulkanObjectName(m_vk_device, m_vk_unique_swapchain.get(), context_name); uint32_t frame_index = 0u; for (const vk::UniqueSemaphore& vk_unique_frame_semaphore : m_vk_frame_semaphores_pool) @@ -427,8 +429,8 @@ void RenderContext::ResetNativeObjectNames() const if (!vk_unique_frame_semaphore) continue; - const std::string frame_semaphore_name = fmt::format("{} Frame {} Image Available", GetName(), frame_index); - SetVulkanObjectName(m_vk_device, vk_unique_frame_semaphore.get(), frame_semaphore_name.c_str()); + SetVulkanObjectName(m_vk_device, vk_unique_frame_semaphore.get(), + fmt::format("{} Frame {} Image Available", context_name, frame_index)); frame_index++; } } From 40de546487cc027906cb4f60a20081406e3958e1 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 30 Jul 2023 17:18:52 +0300 Subject: [PATCH 32/64] Revert adding of SetObjectName function for name formatting --- Apps/01-HelloTriangle/HelloTriangleApp.cpp | 2 +- Apps/01-HelloTriangle/README.md | 2 +- Apps/02-HelloCube/HelloCubeApp.cpp | 8 ++-- Apps/03-TexturedCube/TexturedCubeApp.cpp | 6 +-- Apps/04-ShadowCube/ShadowCubeApp.cpp | 28 +++++++------- Apps/05-Typography/TypographyApp.cpp | 2 +- Apps/06-CubeMapArray/CubeMapArrayApp.cpp | 10 ++--- .../ParallelRenderingApp.cpp | 10 ++--- .../Methane/Tutorials/TextureLabeler.cpp | 9 ++--- .../App/Include/Methane/Graphics/App.hpp | 2 +- .../Include/Methane/Graphics/MeshBuffers.hpp | 3 +- .../Methane/Graphics/MeshBuffersBase.cpp | 5 +-- .../Sources/Methane/Graphics/ScreenQuad.cpp | 9 ++--- .../Methane/Graphics/Base/CommandKit.cpp | 13 +++---- .../Sources/Methane/Graphics/Base/Context.cpp | 9 ++--- Modules/Graphics/RHI/Interface/CMakeLists.txt | 1 - .../Methane/Graphics/RHI/ObjectName.hpp | 38 ------------------- .../Include/Methane/Graphics/Vulkan/Utils.hpp | 2 +- .../Methane/Graphics/Vulkan/Device.cpp | 2 +- .../Methane/UserInterface/FontImpl.hpp | 3 +- .../Sources/Methane/UserInterface/Text.cpp | 11 +++--- 21 files changed, 64 insertions(+), 111 deletions(-) delete mode 100644 Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp diff --git a/Apps/01-HelloTriangle/HelloTriangleApp.cpp b/Apps/01-HelloTriangle/HelloTriangleApp.cpp index 789acb6c5..a7d09ffbe 100644 --- a/Apps/01-HelloTriangle/HelloTriangleApp.cpp +++ b/Apps/01-HelloTriangle/HelloTriangleApp.cpp @@ -87,7 +87,7 @@ class HelloTriangleApp final // NOSONAR - destructor required for (HelloTriangleFrame& frame : GetFrames()) { frame.render_cmd_list = cmd_queue.CreateRenderCommandList(frame.screen_pass); - rhi::SetObjectName(frame.render_cmd_list, "Render Triangle {}", frame.index); + frame.render_cmd_list.SetName(fmt::format("Render Triangle {}", frame.index)); frame.execute_cmd_list_set = Rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/01-HelloTriangle/README.md b/Apps/01-HelloTriangle/README.md index 0d58ea30b..aa7fe915e 100644 --- a/Apps/01-HelloTriangle/README.md +++ b/Apps/01-HelloTriangle/README.md @@ -138,7 +138,7 @@ public: for (HelloTriangleFrame& frame : GetFrames()) { frame.render_cmd_list = cmd_queue.CreateRenderCommandList(frame.screen_pass); - rhi::SetObjectName(frame.render_cmd_list, "Render Triangle {}", frame.index)); + frame.render_cmd_list.SetName(fmt::format("Render Triangle {}", frame.index)); frame.execute_cmd_list_set = Rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/02-HelloCube/HelloCubeApp.cpp b/Apps/02-HelloCube/HelloCubeApp.cpp index 34f7f66f5..32803e1ea 100644 --- a/Apps/02-HelloCube/HelloCubeApp.cpp +++ b/Apps/02-HelloCube/HelloCubeApp.cpp @@ -204,23 +204,23 @@ class HelloCubeApp final // NOSONAR - destructor required #ifdef UNIFORMS_BUFFER_ENABLED // Create uniforms buffer with volatile parameters for frame rendering frame.uniforms_buffer = GetRenderContext().CreateBuffer(Rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, false, true)); - rhi::SetObjectName(frame.uniforms_buffer, "Uniforms Buffer {}", frame.index); + frame.uniforms_buffer.SetName(fmt::format("Uniforms Buffer {}", frame.index)); // Configure program resource bindings frame.program_bindings = m_render_state.GetProgram().CreateBindings({ { { Rhi::ShaderType::Vertex, "g_uniforms" }, { { frame.uniforms_buffer.GetInterface() } } } }, frame.index); - rhi::SetObjectName(frame.program_bindings, "Cube Bindings {}", frame.index); + frame.program_bindings.SetName(fmt::format("Cube Bindings {}", frame.index)); #else // Create vertex buffers for each frame Rhi::Buffer vertex_buffer = GetRenderContext().CreateBuffer(Rhi::BufferSettings::ForVertexBuffer(m_cube_mesh.GetVertexDataSize(), m_cube_mesh.GetVertexSize(), true)); - rhi::SetObjectName(vertex_buffer, "Cube Vertex Buffer {}", frame.index); + vertex_buffer.SetName(fmt::format("Cube Vertex Buffer {}", frame.index)); frame.vertex_buffer_set = Rhi::BufferSet(Rhi::BufferType::Vertex, { vertex_buffer }); #endif // Create command list for rendering frame.render_cmd_list = m_render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - rhi::SetObjectName(frame.render_cmd_list, "Cube Rendering {}", frame.index); + frame.render_cmd_list.SetName(fmt::format("Cube Rendering {}", frame.index)); frame.execute_cmd_list_set = Rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/03-TexturedCube/TexturedCubeApp.cpp b/Apps/03-TexturedCube/TexturedCubeApp.cpp index 5d4760313..560f05129 100644 --- a/Apps/03-TexturedCube/TexturedCubeApp.cpp +++ b/Apps/03-TexturedCube/TexturedCubeApp.cpp @@ -157,7 +157,7 @@ void TexturedCubeApp::Init() { // Create uniforms buffer with volatile parameters for frame rendering frame.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, false, true)); - rhi::SetObjectName(frame.uniforms_buffer, "Uniforms Buffer {}", frame.index); + frame.uniforms_buffer.SetName(fmt::format("Uniforms Buffer {}", frame.index)); // Configure program resource bindings frame.program_bindings = m_render_state.GetProgram().CreateBindings({ @@ -166,11 +166,11 @@ void TexturedCubeApp::Init() { { rhi::ShaderType::Pixel, "g_texture" }, { { m_cube_texture.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.program_bindings, "Cube Bindings {}", frame.index); + frame.program_bindings.SetName(fmt::format("Cube Bindings {}", frame.index)); // Create command list for rendering frame.render_cmd_list = render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - rhi::SetObjectName(frame.render_cmd_list, "Cube Rendering {}", frame.index); + frame.render_cmd_list.SetName(fmt::format("Cube Rendering {}", frame.index)); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/04-ShadowCube/ShadowCubeApp.cpp b/Apps/04-ShadowCube/ShadowCubeApp.cpp index 1614559a0..6cb6865cb 100644 --- a/Apps/04-ShadowCube/ShadowCubeApp.cpp +++ b/Apps/04-ShadowCube/ShadowCubeApp.cpp @@ -161,7 +161,7 @@ void ShadowCubeApp::Init() ), GetScreenRenderPattern() }; - SetObjectName(final_state_settings.program, "Textured, Shadows & Lighting"); + final_state_settings.program.SetName("Textured, Shadows & Lighting"); final_state_settings.depth.enabled = true; m_final_pass.render_state = render_context.CreateRenderState( final_state_settings); @@ -205,7 +205,7 @@ void ShadowCubeApp::Init() ), m_shadow_pass_pattern }; - SetObjectName(shadow_state_settings.program, "Vertex Only: Textured, Lighting"); + shadow_state_settings.program.SetName("Vertex Only: Textured, Lighting"); shadow_state_settings.depth.enabled = true; m_shadow_pass.render_state = render_context.CreateRenderState( shadow_state_settings); @@ -227,33 +227,33 @@ void ShadowCubeApp::Init() { // Create uniforms buffer with volatile parameters for the whole scene rendering frame.scene_uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(scene_uniforms_data_size, false, true)); - rhi::SetObjectName(frame.scene_uniforms_buffer, "Scene Uniforms Buffer {}", frame.index); + frame.scene_uniforms_buffer.SetName(fmt::format("Scene Uniforms Buffer {}", frame.index)); // ========= Shadow Pass Resources ========= // Create uniforms buffer for Cube rendering in Shadow pass frame.shadow_pass.cube.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - rhi::SetObjectName(frame.shadow_pass.cube.uniforms_buffer, "Cube Uniforms Buffer for Shadow Pass {}", frame.index); + frame.shadow_pass.cube.uniforms_buffer.SetName(fmt::format("Cube Uniforms Buffer for Shadow Pass {}", frame.index)); // Create uniforms buffer for Floor rendering in Shadow pass frame.shadow_pass.floor.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - rhi::SetObjectName(frame.shadow_pass.floor.uniforms_buffer, "Floor Uniforms Buffer for Shadow Pass {}", frame.index); + frame.shadow_pass.floor.uniforms_buffer.SetName(fmt::format("Floor Uniforms Buffer for Shadow Pass {}", frame.index)); // Shadow-pass resource bindings for cube rendering frame.shadow_pass.cube.program_bindings = shadow_state_settings.program.CreateBindings({ { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.shadow_pass.cube.uniforms_buffer.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.shadow_pass.cube.program_bindings, "Cube Shadow-Pass Bindings {}", frame.index); + frame.shadow_pass.cube.program_bindings.SetName(fmt::format("Cube Shadow-Pass Bindings {}", frame.index)); // Shadow-pass resource bindings for floor rendering frame.shadow_pass.floor.program_bindings = shadow_state_settings.program.CreateBindings({ { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.shadow_pass.floor.uniforms_buffer.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.shadow_pass.floor.program_bindings, "Floor Shadow-Pass Bindings {}", frame.index); + frame.shadow_pass.floor.program_bindings.SetName(fmt::format("Floor Shadow-Pass Bindings {}", frame.index)); // Create depth texture for shadow map rendering frame.shadow_pass.rt_texture = render_context.CreateTexture(shadow_texture_settings); - rhi::SetObjectName(frame.shadow_pass.rt_texture, "Shadow Map {}", frame.index); + frame.shadow_pass.rt_texture.SetName(fmt::format("Shadow Map {}", frame.index)); // Create shadow pass configuration with depth attachment frame.shadow_pass.render_pass = m_shadow_pass_pattern.CreateRenderPass({ @@ -263,17 +263,17 @@ void ShadowCubeApp::Init() // Create render pass and command list for shadow pass rendering frame.shadow_pass.cmd_list = render_cmd_queue.CreateRenderCommandList(frame.shadow_pass.render_pass); - rhi::SetObjectName(frame.shadow_pass.cmd_list, "Shadow-Map Rendering {}", frame.index); + frame.shadow_pass.cmd_list.SetName(fmt::format("Shadow-Map Rendering {}", frame.index)); // ========= Final Pass Resources ========= // Create uniforms buffer for Cube rendering in Final pass frame.final_pass.cube.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - rhi::SetObjectName(frame.final_pass.cube.uniforms_buffer, "Cube Uniforms Buffer for Final Pass {}", frame.index); + frame.final_pass.cube.uniforms_buffer.SetName(fmt::format("Cube Uniforms Buffer for Final Pass {}", frame.index)); // Create uniforms buffer for Floor rendering in Final pass frame.final_pass.floor.uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(mesh_uniforms_data_size, false, true)); - rhi::SetObjectName(frame.final_pass.floor.uniforms_buffer, "Floor Uniforms Buffer for Final Pass {}", frame.index); + frame.final_pass.floor.uniforms_buffer.SetName(fmt::format("Floor Uniforms Buffer for Final Pass {}", frame.index)); // Final-pass resource bindings for cube rendering frame.final_pass.cube.program_bindings = final_state_settings.program.CreateBindings({ @@ -285,14 +285,14 @@ void ShadowCubeApp::Init() { { rhi::ShaderType::Pixel, "g_texture" }, { { m_cube_buffers_ptr->GetTexture().GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_texture_sampler"}, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.final_pass.cube.program_bindings, "Cube Final-Pass Bindings {}", frame.index); + frame.final_pass.cube.program_bindings.SetName(fmt::format("Cube Final-Pass Bindings {}", frame.index)); // Final-pass resource bindings for floor rendering - patched a copy of cube bindings frame.final_pass.floor.program_bindings = rhi::ProgramBindings(frame.final_pass.cube.program_bindings, { { { rhi::ShaderType::Vertex, "g_mesh_uniforms" }, { { frame.final_pass.floor.uniforms_buffer.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_texture" }, { { m_floor_buffers_ptr->GetTexture().GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.final_pass.floor.program_bindings, "Floor Final-Pass Bindings {}", frame.index); + frame.final_pass.floor.program_bindings.SetName(fmt::format("Floor Final-Pass Bindings {}", frame.index)); // Bind final pass RT texture and pass to the frame buffer texture and final pass. frame.final_pass.rt_texture = frame.screen_texture; @@ -300,7 +300,7 @@ void ShadowCubeApp::Init() // Create render pass and command list for final pass rendering frame.final_pass.cmd_list = render_cmd_queue.CreateRenderCommandList(frame.final_pass.render_pass); - rhi::SetObjectName(frame.final_pass.cmd_list, "Final Scene Rendering {}", frame.index); + frame.final_pass.cmd_list.SetName(fmt::format("Final Scene Rendering {}", frame.index)); // Rendering command lists sequence frame.execute_cmd_list_set = rhi::CommandListSet({ diff --git a/Apps/05-Typography/TypographyApp.cpp b/Apps/05-Typography/TypographyApp.cpp index 239752c12..2be50bd1c 100644 --- a/Apps/05-Typography/TypographyApp.cpp +++ b/Apps/05-Typography/TypographyApp.cpp @@ -216,7 +216,7 @@ void TypographyApp::Init() for(TypographyFrame& frame : GetFrames()) { frame.render_cmd_list = GetRenderContext().GetRenderCommandKit().GetQueue().CreateRenderCommandList(frame.screen_pass); - rhi::SetObjectName(frame.render_cmd_list, "Text Rendering {}", frame.index); + frame.render_cmd_list.SetName(fmt::format("Text Rendering {}", frame.index)); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/06-CubeMapArray/CubeMapArrayApp.cpp b/Apps/06-CubeMapArray/CubeMapArrayApp.cpp index f1b59b172..209a41144 100644 --- a/Apps/06-CubeMapArray/CubeMapArrayApp.cpp +++ b/Apps/06-CubeMapArray/CubeMapArrayApp.cpp @@ -171,7 +171,7 @@ void CubeMapArrayApp::Init() { // Create uniforms buffer with volatile parameters for frame rendering frame.cube.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, false, true)); - rhi::SetObjectName(frame.cube.uniforms_buffer, "Uniforms Buffer {}", frame.index); + frame.cube.uniforms_buffer.SetName(fmt::format("Uniforms Buffer {}", frame.index)); // Configure program resource bindings frame.cube.program_bindings = m_render_state.GetProgram().CreateBindings({ @@ -179,19 +179,19 @@ void CubeMapArrayApp::Init() { { rhi::ShaderType::Pixel, "g_texture_array" }, { { m_cube_buffers_ptr->GetTexture().GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - rhi::SetObjectName(frame.cube.program_bindings, "Cube Bindings {}", frame.index); + frame.cube.program_bindings.SetName(fmt::format("Cube Bindings {}", frame.index)); // Create uniforms buffer for Sky-Box rendering frame.sky_box.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(gfx::SkyBox::GetUniformsSize(), false, true)); - rhi::SetObjectName(frame.sky_box.uniforms_buffer, "Sky-box Uniforms Buffer {}", frame.index); + frame.sky_box.uniforms_buffer.SetName(fmt::format("Sky-box Uniforms Buffer {}", frame.index)); // Resource bindings for Sky-Box rendering frame.sky_box.program_bindings = m_sky_box.CreateProgramBindings(frame.sky_box.uniforms_buffer, frame.index); - rhi::SetObjectName(frame.sky_box.program_bindings, "Space Sky-Box Bindings {}", frame.index); + frame.sky_box.program_bindings.SetName(fmt::format("Space Sky-Box Bindings {}", frame.index)); // Create command list for rendering frame.render_cmd_list = render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - rhi::SetObjectName(frame.render_cmd_list, "Cube Rendering {}", frame.index); + frame.render_cmd_list.SetName(fmt::format("Cube Rendering {}", frame.index)); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp index 3a1aebde8..f347201f6 100644 --- a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp +++ b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp @@ -193,7 +193,7 @@ void ParallelRenderingApp::Init() { // Create buffer for uniforms array related to all cube instances frame.cubes_array.uniforms_buffer = GetRenderContext().CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size, true, true)); - rhi::SetObjectName(frame.cubes_array.uniforms_buffer, "Uniforms Buffer {}", frame.index); + frame.cubes_array.uniforms_buffer.SetName(fmt::format("Uniforms Buffer {}", frame.index)); // Configure program resource bindings frame.cubes_array.program_bindings_per_instance.resize(cubes_count); @@ -202,7 +202,7 @@ void ParallelRenderingApp::Init() { { rhi::ShaderType::Pixel, "g_texture_array" }, { { m_texture_array.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { m_texture_sampler.GetInterface() } } }, }, frame.index); - SetObjectName(frame.cubes_array.program_bindings_per_instance[0], "Cube 0 Bindings {}", frame.index); + frame.cubes_array.program_bindings_per_instance[0].SetName(fmt::format("Cube 0 Bindings {}", frame.index)); program_bindings_task_flow.for_each_index(1U, cubes_count, 1U, [this, &frame, uniform_data_size](const uint32_t cube_index) @@ -214,7 +214,7 @@ void ParallelRenderingApp::Init() { { frame.cubes_array.uniforms_buffer.GetInterface(), m_cube_array_buffers_ptr->GetUniformsBufferOffset(cube_index), uniform_data_size } } } }, frame.index); - SetObjectName(cube_program_bindings, "Cube {} Bindings {}", cube_index, frame.index); + cube_program_bindings.SetName(fmt::format("Cube {} Bindings {}", cube_index, frame.index)); }); if (m_settings.parallel_rendering_enabled) @@ -223,14 +223,14 @@ void ParallelRenderingApp::Init() frame.parallel_render_cmd_list = render_cmd_queue.CreateParallelRenderCommandList(frame.screen_pass); frame.parallel_render_cmd_list.SetParallelCommandListsCount(m_settings.GetActiveRenderThreadCount()); frame.parallel_render_cmd_list.SetValidationEnabled(false); - rhi::SetObjectName(frame.parallel_render_cmd_list, "Parallel Cubes Rendering {}", frame.index); + frame.parallel_render_cmd_list.SetName(fmt::format("Parallel Cubes Rendering {}", frame.index)); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.parallel_render_cmd_list.GetInterface() }, frame.index); } else { // Create serial command list for rendering to the screen pass frame.serial_render_cmd_list = render_cmd_queue.CreateRenderCommandList(frame.screen_pass); - rhi::SetObjectName(frame.serial_render_cmd_list, "Serial Cubes Rendering {}", frame.index); + frame.serial_render_cmd_list.SetName(fmt::format("Serial Cubes Rendering {}", frame.index)); frame.serial_render_cmd_list.SetValidationEnabled(false); frame.execute_cmd_list_set = rhi::CommandListSet({ frame.serial_render_cmd_list.GetInterface() }, frame.index); } diff --git a/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp b/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp index 60de0956f..0da9fa145 100644 --- a/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp +++ b/Apps/Common/Sources/Methane/Tutorials/TextureLabeler.cpp @@ -26,7 +26,6 @@ Renders text labels to the faces of cube-map texture array #include #include #include -#include #include #include #include @@ -102,7 +101,7 @@ TextureLabeler::TextureLabeler(gui::Context& gui_context, const gui::FontContext }); const std::string_view rt_texture_name = m_rt_texture.GetName(); - SetObjectName(m_texture_face_render_pattern, "Texture '{}' Face Render Pattern", rt_texture_name); + m_texture_face_render_pattern.SetName(fmt::format("Texture '{}' Face Render Pattern", rt_texture_name)); gui::Text::SettingsUtf32 slice_text_settings { @@ -137,10 +136,10 @@ TextureLabeler::TextureLabeler(gui::Context& gui_context, const gui::FontContext { rhi::TextureView(rt_texture.GetInterface(), rhi::SubResource::Index(depth_index, array_index), {}, rhi::TextureDimensionType::Tex2D) }, rt_texture_settings.dimensions.AsRectSize() }); - SetObjectName(slice.render_pass, "Texture '{}' Slice {}:{} Render Pass", rt_texture_name, array_index, depth_index); + slice.render_pass.SetName(fmt::format("Texture '{}' Slice {}:{} Render Pass", rt_texture_name, array_index, depth_index)); slice.render_cmd_list = m_gui_context.GetRenderCommandQueue().CreateRenderCommandList(slice.render_pass); - SetObjectName(slice.render_cmd_list, "Render Texture '{}' Slice {}:{} Label", rt_texture_name, array_index, depth_index); + slice.render_cmd_list.SetName(fmt::format("Render Texture '{}' Slice {}:{} Label", rt_texture_name, array_index, depth_index)); slice_render_cmd_list_refs.emplace_back(slice.render_cmd_list.GetInterface()); slice_text_settings.name = fmt::format("Texture '{}' Slice {}:{} Label Text", rt_texture_name, array_index, depth_index); @@ -174,7 +173,7 @@ TextureLabeler::TextureLabeler(gui::Context& gui_context, const gui::FontContext }); m_ending_render_pass = m_ending_render_pattern.CreateRenderPass({ { }, rt_texture_settings.dimensions.AsRectSize() }); m_ending_render_cmd_list = m_gui_context.GetRenderCommandQueue().CreateRenderCommandList(m_ending_render_pass); - SetObjectName(m_ending_render_cmd_list, "Render Texture State Transition", rt_texture_name); + m_ending_render_cmd_list.SetName(fmt::format("Render Texture State Transition", rt_texture_name)); m_ending_resource_barriers = rhi::ResourceBarriers({ { m_rt_texture.GetInterface(), rhi::ResourceState::RenderTarget, rt_texture_final_state } }); diff --git a/Modules/Graphics/App/Include/Methane/Graphics/App.hpp b/Modules/Graphics/App/Include/Methane/Graphics/App.hpp index 25d28fc06..2334b344f 100644 --- a/Modules/Graphics/App/Include/Methane/Graphics/App.hpp +++ b/Modules/Graphics/App/Include/Methane/Graphics/App.hpp @@ -98,7 +98,7 @@ class App // Create color texture for frame buffer frame.screen_texture = render_context.CreateTexture(Rhi::TextureSettings::ForFrameBuffer(render_context.GetSettings(), frame.index)); - rhi::SetObjectName(frame.screen_texture, "Frame Buffer {}", frame.index); + frame.screen_texture.SetName(fmt::format("Frame Buffer {}", frame.index)); // Configure render pass: color, depth, stencil attachments and shader access frame.screen_pass = CreateScreenRenderPass(frame.screen_texture); diff --git a/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp b/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp index c4d2062d2..f3f1c40cd 100644 --- a/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp +++ b/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp @@ -26,7 +26,6 @@ Mesh buffers with texture extension structure. #include "MeshBuffersBase.h" #include -#include #include #include #include @@ -196,7 +195,7 @@ class TexturedMeshBuffers SetSubsetTexture(texture, 0U); if (texture.IsInitialized()) { - SetObjectName(texture, "{} Texture", MeshBuffers::GetMeshName()); + texture.SetName(fmt::format("{} Texture", MeshBuffers::GetMeshName())); } } diff --git a/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp b/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp index 64790f583..a5a6cd145 100644 --- a/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp +++ b/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp @@ -25,7 +25,6 @@ Mesh buffers base implementation class. #include #include #include -#include #include #include @@ -53,7 +52,7 @@ MeshBuffersBase::MeshBuffersBase(const Rhi::CommandQueue& render_cmd_queue, cons Rhi::BufferSettings::ForVertexBuffer( mesh_data.GetVertexDataSize(), mesh_data.GetVertexSize())); - SetObjectName(vertex_buffer, "{} Vertex Buffer", mesh_name); + vertex_buffer.SetName(fmt::format("{} Vertex Buffer", mesh_name)); vertex_buffer.SetData(render_cmd_queue, { mesh_data.GetVertexData(), mesh_data.GetVertexDataSize() @@ -64,7 +63,7 @@ MeshBuffersBase::MeshBuffersBase(const Rhi::CommandQueue& render_cmd_queue, cons Rhi::BufferSettings::ForIndexBuffer( mesh_data.GetIndexDataSize(), GetIndexFormat(mesh_data.GetIndex(0)))); - SetObjectName(m_index_buffer, "{} Index Buffer", mesh_name); + m_index_buffer.SetName(fmt::format("{} Index Buffer", mesh_name)); m_index_buffer.SetData(render_cmd_queue, { reinterpret_cast(mesh_data.GetIndices().data()), // NOSONAR mesh_data.GetIndexDataSize() diff --git a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp index bf8422b0f..e286ff8ca 100644 --- a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp +++ b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ScreenQuad.cpp @@ -34,7 +34,6 @@ Screen Quad rendering primitive. #include #include #include -#include #include #include #include @@ -155,7 +154,7 @@ class ScreenQuad::Impl }), render_pattern }; - SetObjectName(state_settings.program, "{} Shading", quad_name); + state_settings.program.SetName(fmt::format("{} Shading", quad_name)); state_settings.depth.enabled = false; state_settings.depth.write_enabled = false; state_settings.rasterizer.is_front_counter_clockwise = true; @@ -194,7 +193,7 @@ class ScreenQuad::Impl render_context.GetObjectRegistry().AddGraphicsObject(m_texture_sampler.GetInterface()); } - SetObjectName(m_texture, "{} Screen-Quad Texture", m_settings.name); + m_texture.SetName(fmt::format("{} Screen-Quad Texture", m_settings.name)); } static const std::string s_vertex_buffer_name = "Screen-Quad Vertex Buffer"; @@ -242,7 +241,7 @@ class ScreenQuad::Impl m_const_buffer = render_context.CreateBuffer( Rhi::BufferSettings::ForConstantBuffer(static_cast(sizeof(hlslpp::ScreenQuadConstants)))); - SetObjectName(m_const_buffer, "{} Screen-Quad Constants Buffer", m_settings.name); + m_const_buffer.SetName(fmt::format("{} Screen-Quad Constants Buffer", m_settings.name)); Rhi::ProgramBindings::ResourceViewsByArgument program_binding_resource_views = { { { Rhi::ShaderType::Pixel, "g_constants" }, { { m_const_buffer.GetInterface() } } } @@ -255,7 +254,7 @@ class ScreenQuad::Impl } m_const_program_bindings = m_render_state.GetProgram().CreateBindings(program_binding_resource_views); - SetObjectName(m_const_program_bindings, "{} Screen-Quad Constant Bindings", m_settings.name); + m_const_program_bindings.SetName(fmt::format("{} Screen-Quad Constant Bindings", m_settings.name)); UpdateConstantsBuffer(); } diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp index c72c361ed..b57655ee2 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandKit.cpp @@ -32,7 +32,6 @@ Methane command kit implementation. #include #include #include -#include #include #include @@ -88,20 +87,20 @@ bool CommandKit::SetName(std::string_view name) return false; if (m_cmd_queue_ptr) - SetObjectName(*m_cmd_queue_ptr, "{} Command Queue", GetName()); + m_cmd_queue_ptr->SetName(fmt::format("{} Command Queue", GetName())); for(size_t cmd_list_index = 0; cmd_list_index < m_cmd_list_ptrs.size(); ++cmd_list_index) { const Ptr& cmd_list_ptr = m_cmd_list_ptrs[cmd_list_index]; if (cmd_list_ptr) - SetObjectName(*cmd_list_ptr, "{} Command List {}", GetName(), cmd_list_index); + cmd_list_ptr->SetName(fmt::format("{} Command List {}", GetName(), cmd_list_index)); } for(size_t fence_index = 0; fence_index < m_fence_ptrs.size(); ++fence_index) { const Ptr& fence_ptr = m_fence_ptrs[fence_index]; if (fence_ptr) - SetObjectName(*fence_ptr, "{} Fence {}", GetName(), fence_index); + fence_ptr->SetName(fmt::format("{} Fence {}", GetName(), fence_index)); } return true; @@ -114,7 +113,7 @@ Rhi::ICommandQueue& CommandKit::GetQueue() const return *m_cmd_queue_ptr; m_cmd_queue_ptr = Rhi::ICommandQueue::Create(m_context, m_cmd_list_type); - SetObjectName(*m_cmd_queue_ptr, "{} Command Queue", GetName()); + m_cmd_queue_ptr->SetName(fmt::format("{} Command Queue", GetName())); return *m_cmd_queue_ptr; } @@ -152,7 +151,7 @@ Rhi::ICommandList& CommandKit::GetList(Rhi::CommandListId cmd_list_id = 0U) cons default: META_UNEXPECTED_ARG(m_cmd_list_type); } - SetObjectName(*cmd_list_ptr, "{} Helper List {}", GetName(), GetCommandListNameById(cmd_list_id)); + cmd_list_ptr->SetName(fmt::format("{} Helper List {}", GetName(), GetCommandListNameById(cmd_list_id))); return *cmd_list_ptr; } @@ -215,7 +214,7 @@ Rhi::IFence& CommandKit::GetFence(Rhi::CommandListId fence_id) const return *fence_ptr; fence_ptr = Rhi::IFence::Create(GetQueue()); - SetObjectName(*fence_ptr, "{} Fence {}", GetName(), fence_id); + fence_ptr->SetName(fmt::format("{} Fence {}", GetName(), fence_id)); return *fence_ptr; } diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp index 39d8cf338..28fb90601 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/Context.cpp @@ -27,7 +27,6 @@ Base implementation of the context interface. #include #include #include -#include #include #include @@ -164,7 +163,7 @@ void Context::Initialize(Device& device, bool is_callback_emitted) if (const std::string_view context_name = GetName(); !context_name.empty()) { - SetObjectName(*m_device_ptr, "{} Device", context_name); + m_device_ptr->SetName(fmt::format("{} Device", context_name)); } if (is_callback_emitted) @@ -181,7 +180,7 @@ Rhi::ICommandKit& Context::GetDefaultCommandKit(Rhi::CommandListType type) const return *cmd_kit_ptr; cmd_kit_ptr = Rhi::ICommandKit::Create(*this, type); - SetObjectName(*cmd_kit_ptr, "{} {}", GetName(), g_default_command_kit_names[magic_enum::enum_index(type).value()]); + cmd_kit_ptr->SetName(fmt::format("{} {}", GetName(), g_default_command_kit_names[magic_enum::enum_index(type).value()])); m_default_command_kit_ptr_by_queue[std::addressof(cmd_kit_ptr->GetQueue())] = cmd_kit_ptr; return *cmd_kit_ptr; @@ -232,11 +231,11 @@ bool Context::SetName(std::string_view name) if (!Object::SetName(name)) return false; - SetObjectName(GetBaseDevice(), "{} Device", name); + GetBaseDevice().SetName(fmt::format("{} Device", name)); for(const Ptr& cmd_kit_ptr : m_default_command_kit_ptrs) { if (cmd_kit_ptr) - SetObjectName(*cmd_kit_ptr, "{} {}", name, g_default_command_kit_names[magic_enum::enum_index(cmd_kit_ptr->GetListType()).value()]); + cmd_kit_ptr->SetName(fmt::format("{} {}", name, g_default_command_kit_names[magic_enum::enum_index(cmd_kit_ptr->GetListType()).value()])); } return true; } diff --git a/Modules/Graphics/RHI/Interface/CMakeLists.txt b/Modules/Graphics/RHI/Interface/CMakeLists.txt index 22f174341..ad56fc0da 100644 --- a/Modules/Graphics/RHI/Interface/CMakeLists.txt +++ b/Modules/Graphics/RHI/Interface/CMakeLists.txt @@ -38,7 +38,6 @@ list(APPEND HEADERS ${INCLUDE_DIR}/IParallelRenderCommandList.h ${INCLUDE_DIR}/IQueryPool.h ${INCLUDE_DIR}/IDescriptorManager.h - ${INCLUDE_DIR}/ObjectName.hpp ${INCLUDE_DIR}/TypeFormatters.hpp ) diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp deleted file mode 100644 index 069623c93..000000000 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/ObjectName.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/****************************************************************************** - -Copyright 2019-2020 Evgeny Gorodetskiy - -Licensed under the Apache License, Version 2.0 (the "License"), -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -******************************************************************************* - -FILE: Methane/Graphics/RHI/ObjectName.hpp -Methane graphics RHI object naming utility function - -******************************************************************************/ - -#pragma once - -#include - -namespace Methane::Graphics::Rhi -{ - -template -bool SetObjectName(ObjectType& object, FormatType&& format, ArgTypes&& ... args) -{ - const std::string formatted_name = fmt::format(std::forward(format), std::forward(args)...); - return object.SetName(formatted_name); -} - -} // namespace Methane::Graphics::Rhi diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp index a6165ee75..a254e0b54 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/Utils.hpp @@ -24,7 +24,7 @@ Methane graphics utils for Vulkan API. #pragma once #include -#include + #include #include diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp index d06b223e5..f151ed116 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp @@ -208,7 +208,7 @@ Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKH , m_vk_physical_device(vk_physical_device) , m_supported_extension_names_storage(GetDeviceSupportedExtensionNames(vk_physical_device)) , m_supported_extension_names_set(m_supported_extension_names_storage.begin(), m_supported_extension_names_storage.end()) - , m_is_dynamic_state_supported(IsExtensionSupported(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) + , m_is_dynamic_state_supported(false) //IsExtensionSupported(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) , m_vk_queue_family_properties(vk_physical_device.getQueueFamilyProperties()) { META_FUNCTION_TASK(); diff --git a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp index 51b8c788b..8976b6a2d 100644 --- a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp +++ b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/FontImpl.hpp @@ -31,7 +31,6 @@ Font implementation. #include #include #include -#include #include #include #include @@ -498,7 +497,7 @@ class Font::Impl // NOSONAR - class destructor is required, class has more than rhi::TextureSettings::ForImage( gfx::Dimensions(m_atlas_pack_ptr->GetSize()), std::nullopt, gfx::PixelFormat::R8Unorm, false)); - SetObjectName(atlas_texture, "{} Font Atlas", m_settings.description.name); + atlas_texture.SetName(fmt::format("{} Font Atlas", m_settings.description.name)); if (deferred_data_init) { render_context.RequestDeferredAction(rhi::IContext::DeferredAction::CompleteInitialization); diff --git a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp index bb8413b01..3301d929f 100644 --- a/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp +++ b/Modules/UserInterface/Typography/Sources/Methane/UserInterface/Text.cpp @@ -40,7 +40,6 @@ Methane text rendering primitive. #include #include #include -#include #include #include #include @@ -191,7 +190,7 @@ class TextFrameResources const Data::Size vertex_buffer_size = vertices_data_size * reservation_multiplier; rhi::Buffer vertex_buffer; vertex_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForVertexBuffer(vertex_buffer_size, text_mesh.GetVertexSize())); - SetObjectName(vertex_buffer, "{} Text Vertex Buffer {}", text_name, m_frame_index); + vertex_buffer.SetName(fmt::format("{} Text Vertex Buffer {}", text_name, m_frame_index)); m_vertex_buffer_set = rhi::BufferSet(rhi::BufferType::Vertex, { vertex_buffer }); } m_vertex_buffer_set[0].SetData(render_context.GetRenderCommandKit().GetQueue(), { @@ -209,7 +208,7 @@ class TextFrameResources { const Data::Size index_buffer_size = vertices_data_size * reservation_multiplier; m_index_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForIndexBuffer(index_buffer_size, gfx::PixelFormat::R16Uint)); - SetObjectName(m_index_buffer, "{} Text Index Buffer {}", text_name, m_frame_index); + m_index_buffer.SetName(fmt::format("{} Text Index Buffer {}", text_name, m_frame_index)); } m_index_buffer.SetData(render_context.GetRenderCommandKit().GetQueue(), { @@ -242,7 +241,7 @@ class TextFrameResources if (!m_uniforms_buffer.IsInitialized()) { m_uniforms_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(uniforms_data_size)); - SetObjectName(m_uniforms_buffer, "{} Text Uniforms Buffer {}", text_name, m_frame_index); + m_uniforms_buffer.SetName(fmt::format("{} Text Uniforms Buffer {}", text_name, m_frame_index)); if (m_program_bindings.IsInitialized()) { @@ -272,7 +271,7 @@ class TextFrameResources { { rhi::ShaderType::Pixel, "g_texture" }, { { m_atlas_texture.GetInterface() } } }, { { rhi::ShaderType::Pixel, "g_sampler" }, { { atlas_sampler.GetInterface() } } }, }); - SetObjectName(m_program_bindings, "{} Text Bindings {}", text_name, m_frame_index); + m_program_bindings.SetName(fmt::format("{} Text Bindings {}", text_name, m_frame_index)); } }; @@ -656,7 +655,7 @@ class Text::Impl // NOSONAR - class destructor is required if (!m_const_buffer.IsInitialized()) { m_const_buffer = render_context.CreateBuffer(rhi::BufferSettings::ForConstantBuffer(static_cast(sizeof(hlslpp::TextConstants)))); - SetObjectName(m_const_buffer, "{} Text Constants Buffer", m_settings.name); + m_const_buffer.SetName(fmt::format("{} Text Constants Buffer", m_settings.name)); } const rhi::Texture& atlas_texture = m_font.GetAtlasTexture(render_context); From 4c247f2ea1bc616c60bb2e26f260eca808e07de1 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 30 Jul 2023 17:38:09 +0300 Subject: [PATCH 33/64] Add CMake option to enable memory address sanitizer in build --- Build/README.md | 1 + CMake/MethaneGlobalOptions.cmake | 8 +++++++- CMakeLists.txt | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Build/README.md b/Build/README.md index e7a9f2a69..513f45d2e 100644 --- a/Build/README.md +++ b/Build/README.md @@ -212,6 +212,7 @@ cmake -G [Generator] ... -D[BUILD_OPTION_NAME]:BOOL=[ON|OFF] | METHANE_GPU_INSTRUMENTATION_ENABLED | OFF | OFF | ON | Enable GPU instrumentation to collect command list execution timings | | METHANE_TRACY_PROFILING_ENABLED | OFF | OFF | ON | Enable realtime profiling with Tracy | | METHANE_TRACY_PROFILING_ON_DEMAND | OFF | OFF | ON | Enable Tracy data collection on demand, after client connection | +| METHANE_MEMORY_SANITIZER_ENABLED | OFF | OFF | OFF | Enable memory address sanitizer in compiler and linker | | METHANE_APPLE_CODE_SIGNING_ENABLED | OFF | OFF | OFF | Enable code signing on Apple platforms (requires APPLE_DEVELOPMENT_TEAM) | ### CMake Presets diff --git a/CMake/MethaneGlobalOptions.cmake b/CMake/MethaneGlobalOptions.cmake index 963e8aede..74cf20fc8 100644 --- a/CMake/MethaneGlobalOptions.cmake +++ b/CMake/MethaneGlobalOptions.cmake @@ -21,6 +21,12 @@ Methane global solution/workspace options, which must be set from root CMakeList *****************************************************************************]] +if (METHANE_MEMORY_SANITIZER_ENABLED) + # Add compiler and linker options globally for all modules + add_compile_options(-fsanitize=address) + add_link_options(-fsanitize=address) +endif() + if(WIN32) if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") @@ -49,7 +55,7 @@ elseif(APPLE) endif() # Set OS deployment target minimum version - if(DEPLOYMENT_TARGET) + if (DEPLOYMENT_TARGET) set(CMAKE_OSX_DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}") else() set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0") diff --git a/CMakeLists.txt b/CMakeLists.txt index 275a8e54b..e45e33d06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ option(METHANE_ITT_METADATA_ENABLED "Enable ITT metadata for tasks and e option(METHANE_GPU_INSTRUMENTATION_ENABLED "Enable GPU instrumentation to collect command list execution timings" OFF) option(METHANE_TRACY_PROFILING_ENABLED "Enable realtime profiling with Tracy" OFF) option(METHANE_TRACY_PROFILING_ON_DEMAND "Enable Tracy data collection on demand, after client connection" OFF) +option(METHANE_MEMORY_SANITIZER_ENABLED "Enable memory address sanitizer in compiler and linker" OFF) # Platform dependent options if(APPLE) From 05adf70c31032b91636c2c38bfb28339849be63f Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 30 Jul 2023 17:38:43 +0300 Subject: [PATCH 34/64] Fix multi-threaded access to CommandListSet shared pointers --- .../Base/Sources/Methane/Graphics/Base/CommandQueueTracking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueueTracking.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueueTracking.cpp index c99fcd14b..f7f8eb986 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueueTracking.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueueTracking.cpp @@ -144,7 +144,7 @@ void CommandQueueTracking::WaitForExecution() noexcept while (!m_executing_command_lists.empty()) { - const Ptr& command_list_set_ptr = GetNextExecutingCommandListSet(); + Ptr command_list_set_ptr = GetNextExecutingCommandListSet(); if (!command_list_set_ptr) break; From 35b204e60bd01d4c1d154ea0073dd7bbba83e363 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 30 Jul 2023 18:12:48 +0300 Subject: [PATCH 35/64] Fix Vulkan buffer size alignment --- .../RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h | 2 -- .../Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp | 9 +++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h index bd5d2e871..3de1ecaff 100644 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h @@ -54,8 +54,6 @@ struct BufferSettings PixelFormat data_format; BufferStorageMode storage_mode = BufferStorageMode::Managed; - static constexpr Data::Size s_data_alignment = 256U; - [[nodiscard]] static Data::Size GetAlignedSize(Data::Size size) noexcept; [[nodiscard]] static BufferSettings ForVertexBuffer(Data::Size size, Data::Size stride, bool is_volatile = false); [[nodiscard]] static BufferSettings ForIndexBuffer(Data::Size size, PixelFormat format, bool is_volatile = false); diff --git a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp index ed9fb6809..67bf4dfad 100644 --- a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp +++ b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp @@ -107,9 +107,14 @@ bool BufferSettings::operator!=(const BufferSettings& other) const Data::Size BufferSettings::GetAlignedSize(Data::Size size) noexcept { +#ifdef METHANE_GFX_DIRECTX // Aligned size must be a multiple 256 bytes - static constexpr uint32_t s_data_placement_minus_one = s_data_alignment - 1; - return (size + s_data_placement_minus_one) & ~s_data_placement_minus_one; + constexpr Data::Size data_alignment = 256U; + constexpr uint32_t data_placement_minus_one = data_alignment - 1; + return (size + data_placement_minus_one) & ~data_placement_minus_one; +#else + return size; +#endif } } // namespace Methane::Graphics::Rhi From d6f5836724ce98f5603a5a7be6cbe205531eee77 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 30 Jul 2023 18:32:22 +0300 Subject: [PATCH 36/64] Fix Vulkan build for MacOS and Vulkan dynamic state support --- .../RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp | 2 +- .../RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp index f151ed116..d06b223e5 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/Device.cpp @@ -208,7 +208,7 @@ Device::Device(const vk::PhysicalDevice& vk_physical_device, const vk::SurfaceKH , m_vk_physical_device(vk_physical_device) , m_supported_extension_names_storage(GetDeviceSupportedExtensionNames(vk_physical_device)) , m_supported_extension_names_set(m_supported_extension_names_storage.begin(), m_supported_extension_names_storage.end()) - , m_is_dynamic_state_supported(false) //IsExtensionSupported(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) + , m_is_dynamic_state_supported(IsExtensionSupported(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) , m_vk_queue_family_properties(vk_physical_device.getQueueFamilyProperties()) { META_FUNCTION_TASK(); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm index 10bd38222..9e3cdf9f9 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm @@ -32,6 +32,7 @@ RenderContext::RenderContext(const Methane::Platform::AppEnvironment& app_env, Device& device, tf::Executor& parallel_executor, const Rhi::RenderContextSettings& settings) : Context(device, parallel_executor, settings) + , m_app_env(app_env) , m_vk_device(device.GetNativeDevice()) , m_metal_view(Metal::CreateRenderContextAppView(app_env, settings)) , m_vk_unique_surface(Platform::CreateVulkanSurfaceForWindow(static_cast(Rhi::ISystem::Get()).GetNativeInstance(), app_env)) From 11e8f0f6a94bb9486fbb8dabab9bf41e8feaeb46 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Sun, 30 Jul 2023 19:31:52 +0300 Subject: [PATCH 37/64] Disable some CI Build steps and workflows in Forked repositories on GitHub --- .github/workflows/ci-build.yml | 8 +++++--- .github/workflows/ci-codeql-scan.yml | 1 + .github/workflows/ci-sonar-scan.yml | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 4335aea0c..ca505f3ed 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -34,6 +34,7 @@ env: product_ver_patch: 2 product_ver_build: ${{ github.run_number }} tracy_release_version: "0.9.1" + is_origin_repository: ${{ github.repository == 'MethanePowered/MethaneKit' }} # TSC Invariant check is disabled to allow running Catch test executables only for tests list query by CTest TRACY_NO_INVARIANT_CHECK: 1 @@ -187,6 +188,7 @@ jobs: uses: actions/checkout@v3 - name: Install Testspace + if: ${{ env.is_origin_repository }} uses: testspace-com/setup-testspace@v1 with: domain: ${{ github.repository_owner }} @@ -255,7 +257,7 @@ jobs: path: ${{ env.INSTALL_DIR }}/Tests/*_result.xml - name: Upload Test Results and Build Log to Testspace server - if: ${{ matrix.run_tests && (success() || failure()) }} + if: ${{ is_origin_repository && matrix.run_tests && (success() || failure()) }} run: testspace "[ ${{ matrix.name }} ]${{ env.INSTALL_DIR }}/Tests/*_result.xml" "[ ${{ matrix.name }} ]${{ env.BUILD_LOG_FILE }}" - name: Add README and BUILD files @@ -300,7 +302,7 @@ jobs: - name: Update Badge Parameters id: badge-params - if: ${{ github.event_name == 'push' && always() }} + if: ${{ is_origin_repository && github.event_name == 'push' && always() }} shell: bash run: | case "${{ job.status }}" in @@ -323,7 +325,7 @@ jobs: esac - name: Update Badge JSON - if: ${{ github.event_name == 'push' && always() }} + if: ${{ is_origin_repository && github.event_name == 'push' && always() }} uses: schneegans/dynamic-badges-action@v1.6.0 # https://github.com/marketplace/actions/dynamic-badges with: auth: ${{ secrets.GIST_TOKEN }} diff --git a/.github/workflows/ci-codeql-scan.yml b/.github/workflows/ci-codeql-scan.yml index a0e22c883..ab693c584 100644 --- a/.github/workflows/ci-codeql-scan.yml +++ b/.github/workflows/ci-codeql-scan.yml @@ -31,6 +31,7 @@ on: jobs: analyze: name: ${{ matrix.name }} + if: ${{ github.repository == 'MethanePowered/MethaneKit' }} strategy: fail-fast: false diff --git a/.github/workflows/ci-sonar-scan.yml b/.github/workflows/ci-sonar-scan.yml index 309c0ae7b..0e4d2bed9 100644 --- a/.github/workflows/ci-sonar-scan.yml +++ b/.github/workflows/ci-sonar-scan.yml @@ -47,6 +47,7 @@ env: jobs: sonar_scan: name: ${{ matrix.name }} + if: ${{ github.repository == 'MethanePowered/MethaneKit' }} strategy: fail-fast: false From fab383d11c3c778b9e7c6a1c2768e0c28d49a8d6 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Sun, 30 Jul 2023 20:59:25 +0300 Subject: [PATCH 38/64] Fix CI Build workflow --- .github/workflows/ci-build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index ca505f3ed..9a511a3e8 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -257,7 +257,7 @@ jobs: path: ${{ env.INSTALL_DIR }}/Tests/*_result.xml - name: Upload Test Results and Build Log to Testspace server - if: ${{ is_origin_repository && matrix.run_tests && (success() || failure()) }} + if: ${{ env.is_origin_repository && matrix.run_tests && (success() || failure()) }} run: testspace "[ ${{ matrix.name }} ]${{ env.INSTALL_DIR }}/Tests/*_result.xml" "[ ${{ matrix.name }} ]${{ env.BUILD_LOG_FILE }}" - name: Add README and BUILD files @@ -302,7 +302,7 @@ jobs: - name: Update Badge Parameters id: badge-params - if: ${{ is_origin_repository && github.event_name == 'push' && always() }} + if: ${{ env.is_origin_repository && github.event_name == 'push' && always() }} shell: bash run: | case "${{ job.status }}" in @@ -325,7 +325,7 @@ jobs: esac - name: Update Badge JSON - if: ${{ is_origin_repository && github.event_name == 'push' && always() }} + if: ${{ env.is_origin_repository && github.event_name == 'push' && always() }} uses: schneegans/dynamic-badges-action@v1.6.0 # https://github.com/marketplace/actions/dynamic-badges with: auth: ${{ secrets.GIST_TOKEN }} From 7ac0530872c14f48f191821ebcde24d9de38cc60 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Mon, 31 Jul 2023 23:13:13 +0300 Subject: [PATCH 39/64] Remove explicit Buffer size alignment, do it implicitly in DirectX RHI implementation --- .../ParallelRenderingApp.cpp | 6 ++-- .../Data/Types/Include/Methane/Data/Math.hpp | 21 ++++++++++++-- .../Include/Methane/Graphics/MeshBuffers.hpp | 6 ++-- .../Include/Methane/Graphics/DirectX/Buffer.h | 2 +- .../Methane/Graphics/DirectX/Buffer.cpp | 28 ++++++++++++++----- .../Include/Methane/Graphics/RHI/IBuffer.h | 1 - .../Sources/Methane/Graphics/RHI/IBuffer.cpp | 20 +++---------- Tests/Graphics/RHI/BufferTest.cpp | 2 +- 8 files changed, 51 insertions(+), 35 deletions(-) diff --git a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp index f347201f6..efbaca1a4 100644 --- a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp +++ b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp @@ -187,7 +187,7 @@ void ParallelRenderingApp::Init() // Create frame buffer resources const Data::Size uniforms_data_size = m_cube_array_buffers_ptr->GetUniformsBufferSize(); - const Data::Size uniform_data_size = MeshBuffers::GetAlignedUniformSize(); + const Data::Size uniform_data_size = MeshBuffers::GetUniformSize(); tf::Taskflow program_bindings_task_flow; for(ParallelRenderingFrame& frame : GetFrames()) { @@ -210,8 +210,8 @@ void ParallelRenderingApp::Init() rhi::ProgramBindings& cube_program_bindings = frame.cubes_array.program_bindings_per_instance[cube_index]; cube_program_bindings = rhi::ProgramBindings(frame.cubes_array.program_bindings_per_instance[0], { { - { rhi::ShaderType::All, "g_uniforms" }, - { { frame.cubes_array.uniforms_buffer.GetInterface(), m_cube_array_buffers_ptr->GetUniformsBufferOffset(cube_index), uniform_data_size } } + { rhi::ShaderType::All, "g_uniforms" }, + { { frame.cubes_array.uniforms_buffer.GetInterface(), m_cube_array_buffers_ptr->GetUniformsBufferOffset(cube_index), uniform_data_size } } } }, frame.index); cube_program_bindings.SetName(fmt::format("Cube {} Bindings {}", cube_index, frame.index)); diff --git a/Modules/Data/Types/Include/Methane/Data/Math.hpp b/Modules/Data/Types/Include/Methane/Data/Math.hpp index 2dec70375..8f36fd363 100644 --- a/Modules/Data/Types/Include/Methane/Data/Math.hpp +++ b/Modules/Data/Types/Include/Methane/Data/Math.hpp @@ -27,6 +27,8 @@ Math primitive functions. #include #include +#include + namespace Methane::Data { @@ -45,13 +47,26 @@ constexpr T RoundCast(V value) noexcept } template -std::enable_if_t, T> AbsSubtract(T a, T b) +constexpr bool IsPowerOfTwo(T value) noexcept +{ + return value > 0 && (value & (value - 1)) == 0; +} + +template +constexpr std::enable_if_t, T> AlignUp(T value, T alignment) +{ + META_CHECK_ARG_TRUE_DESCR(IsPowerOfTwo(alignment), "alignment {} must be a power of two", alignment); + return (value + alignment - 1) & ~(alignment - 1); +} + +template +constexpr std::enable_if_t, T> AbsSubtract(T a, T b) noexcept { return a >= b ? a - b : b - a; } template -T DivCeil(T numerator, T denominator) +constexpr T DivCeil(T numerator, T denominator) noexcept { if constexpr (std::is_signed_v) { @@ -63,7 +78,7 @@ T DivCeil(T numerator, T denominator) } else { - return numerator > 0 ? (1 + ((numerator - 1) / denominator)) : 0; + return numerator > 0 ? (1 + (numerator - 1) / denominator) : 0; } } diff --git a/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp b/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp index f3f1c40cd..d2052939e 100644 --- a/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp +++ b/Modules/Graphics/Primitives/Include/Methane/Graphics/MeshBuffers.hpp @@ -89,9 +89,9 @@ class MeshBuffers } [[nodiscard]] - static constexpr Data::Size GetAlignedUniformSize() noexcept + static constexpr Data::Size GetUniformSize() noexcept { - return Rhi::BufferSettings::GetAlignedSize(static_cast(sizeof(UniformsType))); + return static_cast(sizeof(UniformsType)); } [[nodiscard]] @@ -101,7 +101,7 @@ class MeshBuffers if (m_final_pass_instance_uniforms.empty()) return 0U; - return Rhi::BufferSettings::GetAlignedSize(static_cast(m_final_pass_instance_uniforms.size() * sizeof(m_final_pass_instance_uniforms[0]))); + return static_cast(m_final_pass_instance_uniforms.size() * sizeof(m_final_pass_instance_uniforms[0])); } [[nodiscard]] diff --git a/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Buffer.h b/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Buffer.h index 9737a05b6..294ab1b4e 100644 --- a/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Buffer.h +++ b/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Buffer.h @@ -36,7 +36,7 @@ class Buffer final // NOSONAR - inheritance hierarchy is greater than 5 : public Resource { public: - Buffer(const Base::Context& context, const Settings& settings); + Buffer(const Base::Context& context, const Settings& orig_settings); // IObject overrides bool SetName(std::string_view name) override; diff --git a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Buffer.cpp b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Buffer.cpp index 87952bcf4..28a6930ff 100644 --- a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Buffer.cpp +++ b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Buffer.cpp @@ -25,9 +25,10 @@ DirectX 12 implementation of the buffer interface. #include #include #include - #include #include + +#include #include #include @@ -37,10 +38,22 @@ DirectX 12 implementation of the buffer interface. namespace Methane::Graphics::DirectX { -Buffer::Buffer(const Base::Context& context, const Settings& settings) - : Resource(context, settings) +static Rhi::BufferSettings UpdateBufferSettings(const Rhi::BufferSettings& settings) +{ + Rhi::BufferSettings new_settings = settings; + if (new_settings.type == Rhi::BufferType::Constant || + new_settings.type == Rhi::BufferType::Storage) + { + new_settings.size = Data::AlignUp(settings.size, Data::Size(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT)); + } + return new_settings; +} + +Buffer::Buffer(const Base::Context& context, const Settings& orig_settings) + : Resource(context, UpdateBufferSettings(orig_settings)) { META_FUNCTION_TASK(); + const Settings& settings = GetSettings(); const bool is_private_storage = settings.storage_mode == IBuffer::StorageMode::Private; const bool is_read_back_buffer = settings.usage_mask.HasAnyBit(Usage::ReadBack); const D3D12_HEAP_TYPE normal_heap_type = is_private_storage ? D3D12_HEAP_TYPE_DEFAULT : D3D12_HEAP_TYPE_UPLOAD; @@ -53,12 +66,12 @@ Buffer::Buffer(const Base::Context& context, const Settings& settings) if (settings.usage_mask.HasAnyBit(Usage::ShaderWrite)) resource_flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - const CD3DX12_RESOURCE_DESC resource_desc = CD3DX12_RESOURCE_DESC::Buffer(settings.size, resource_flags); - + CD3DX12_RESOURCE_DESC resource_desc = CD3DX12_RESOURCE_DESC::Buffer(settings.size, resource_flags); InitializeCommittedResource(resource_desc, heap_type, resource_state); if (is_private_storage) { + resource_desc.Width = Data::AlignUp(resource_desc.Width, UINT64(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT)); m_cp_upload_resource = CreateCommittedResource(resource_desc, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ); } @@ -85,8 +98,9 @@ void Buffer::SetData(Rhi::ICommandQueue& target_cmd_queue, const SubResource& su META_FUNCTION_TASK(); Resource::SetData(target_cmd_queue, sub_resource); + const Settings& settings = GetSettings(); const CD3DX12_RANGE zero_read_range(0U, 0U); - const bool is_private_storage = GetSettings().storage_mode == IBuffer::StorageMode::Private; + const bool is_private_storage = settings.storage_mode == IBuffer::StorageMode::Private; ID3D12Resource& d3d12_resource = is_private_storage ? *m_cp_upload_resource.Get() : GetNativeResourceRef(); // Using zero range, since we're not going to read this resource on CPU @@ -117,7 +131,7 @@ void Buffer::SetData(Rhi::ICommandQueue& target_cmd_queue, const SubResource& su // In case of private GPU storage, copy buffer data from intermediate upload resource to the private GPU resource const TransferCommandList& upload_cmd_list = PrepareResourceTransfer(TransferOperation::Upload, target_cmd_queue, State::CopyDest); - upload_cmd_list.GetNativeCommandList().CopyResource(GetNativeResource(), m_cp_upload_resource.Get()); + upload_cmd_list.GetNativeCommandList().CopyBufferRegion(GetNativeResource(), 0U, m_cp_upload_resource.Get(), 0U, settings.size); GetContext().RequestDeferredAction(Rhi::IContext::DeferredAction::UploadResources); } diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h index 3de1ecaff..c282dd762 100644 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/IBuffer.h @@ -54,7 +54,6 @@ struct BufferSettings PixelFormat data_format; BufferStorageMode storage_mode = BufferStorageMode::Managed; - [[nodiscard]] static Data::Size GetAlignedSize(Data::Size size) noexcept; [[nodiscard]] static BufferSettings ForVertexBuffer(Data::Size size, Data::Size stride, bool is_volatile = false); [[nodiscard]] static BufferSettings ForIndexBuffer(Data::Size size, PixelFormat format, bool is_volatile = false); [[nodiscard]] static BufferSettings ForConstantBuffer(Data::Size size, bool addressable = false, bool is_volatile = false); diff --git a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp index 67bf4dfad..106500209 100644 --- a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp +++ b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IBuffer.cpp @@ -47,7 +47,7 @@ BufferSettings BufferSettings::ForVertexBuffer(Data::Size size, Data::Size strid return Rhi::BufferSettings{ Rhi::BufferType::Vertex, Rhi::ResourceUsageMask(), - GetAlignedSize(size), + size, stride, PixelFormat::Unknown, GetBufferStorageMode(is_volatile) @@ -60,7 +60,7 @@ BufferSettings BufferSettings::ForIndexBuffer(Data::Size size, PixelFormat forma return Rhi::BufferSettings{ Rhi::BufferType::Index, Rhi::ResourceUsageMask(), - GetAlignedSize(size), + size, GetPixelSize(format), format, GetBufferStorageMode(is_volatile) @@ -73,7 +73,7 @@ BufferSettings BufferSettings::ForConstantBuffer(Data::Size size, bool addressab return Rhi::BufferSettings{ Rhi::BufferType::Constant, Rhi::ResourceUsageMask(Rhi::ResourceUsage::ShaderRead).SetBit(Rhi::ResourceUsage::Addressable, addressable), - GetAlignedSize(size), + size, 0U, PixelFormat::Unknown, GetBufferStorageMode(is_volatile) @@ -86,7 +86,7 @@ BufferSettings BufferSettings::ForReadBackBuffer(Data::Size size) return Rhi::BufferSettings{ Rhi::BufferType::ReadBack, Rhi::ResourceUsageMask(Rhi::ResourceUsage::ReadBack), - GetAlignedSize(size), + size, 0U, PixelFormat::Unknown, Rhi::BufferStorageMode::Managed @@ -105,16 +105,4 @@ bool BufferSettings::operator!=(const BufferSettings& other) const != std::tie(other.type, other.usage_mask, other.size, other.item_stride_size, other.data_format, other.storage_mode); } -Data::Size BufferSettings::GetAlignedSize(Data::Size size) noexcept -{ -#ifdef METHANE_GFX_DIRECTX - // Aligned size must be a multiple 256 bytes - constexpr Data::Size data_alignment = 256U; - constexpr uint32_t data_placement_minus_one = data_alignment - 1; - return (size + data_placement_minus_one) & ~data_placement_minus_one; -#else - return size; -#endif -} - } // namespace Methane::Graphics::Rhi diff --git a/Tests/Graphics/RHI/BufferTest.cpp b/Tests/Graphics/RHI/BufferTest.cpp index 340cc481e..902d101f5 100644 --- a/Tests/Graphics/RHI/BufferTest.cpp +++ b/Tests/Graphics/RHI/BufferTest.cpp @@ -146,7 +146,7 @@ TEST_CASE("RHI Buffer Functions", "[rhi][buffer][resource]") SECTION("Get Data Size") { - CHECK(buffer.GetDataSize(Data::MemoryState::Reserved) == Rhi::BufferSettings::GetAlignedSize(constant_buffer_settings.size)); + CHECK(buffer.GetDataSize(Data::MemoryState::Reserved) == constant_buffer_settings.size); CHECK(buffer.GetDataSize(Data::MemoryState::Initialized) == 0U); } From 0d3553e057b627d71187e9aeee0e3cd628d79203 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Mon, 31 Jul 2023 23:25:37 +0300 Subject: [PATCH 40/64] Fix clang warning --- Apps/07-ParallelRendering/ParallelRenderingApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp index efbaca1a4..ea457990d 100644 --- a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp +++ b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp @@ -205,7 +205,7 @@ void ParallelRenderingApp::Init() frame.cubes_array.program_bindings_per_instance[0].SetName(fmt::format("Cube 0 Bindings {}", frame.index)); program_bindings_task_flow.for_each_index(1U, cubes_count, 1U, - [this, &frame, uniform_data_size](const uint32_t cube_index) + [this, &frame](const uint32_t cube_index) { rhi::ProgramBindings& cube_program_bindings = frame.cubes_array.program_bindings_per_instance[cube_index]; cube_program_bindings = rhi::ProgramBindings(frame.cubes_array.program_bindings_per_instance[0], { From 9ff4ddad7632467e66e6a6df5816418348bc230a Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Mon, 31 Jul 2023 23:55:07 +0300 Subject: [PATCH 41/64] Workaround false-positive Clang warning/error unused-lambda-capture --- Apps/07-ParallelRendering/ParallelRenderingApp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp index ea457990d..1e0819e19 100644 --- a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp +++ b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp @@ -205,8 +205,9 @@ void ParallelRenderingApp::Init() frame.cubes_array.program_bindings_per_instance[0].SetName(fmt::format("Cube 0 Bindings {}", frame.index)); program_bindings_task_flow.for_each_index(1U, cubes_count, 1U, - [this, &frame](const uint32_t cube_index) + [this, &frame, uniform_data_size](const uint32_t cube_index) { + META_UNUSED(uniform_data_size); // workaround for Clang error unused-lambda-capture uniform_data_size (false positive) rhi::ProgramBindings& cube_program_bindings = frame.cubes_array.program_bindings_per_instance[cube_index]; cube_program_bindings = rhi::ProgramBindings(frame.cubes_array.program_bindings_per_instance[0], { { From 9fcd5ee4a82b2c048253b998dff5503ec1261d8a Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Tue, 1 Aug 2023 23:59:29 +0300 Subject: [PATCH 42/64] Improve Vulkan frame synchronization reliability --- .../Methane/Graphics/Base/RenderContext.h | 1 + .../Methane/Graphics/Base/CommandQueue.cpp | 1 - .../Methane/Graphics/Base/RenderContext.cpp | 9 ++- .../Methane/Graphics/Vulkan/RenderContext.h | 9 ++- .../Graphics/Vulkan/CommandListSet.cpp | 22 ++++-- .../Methane/Graphics/Vulkan/RenderContext.cpp | 72 ++++++++++++++----- 6 files changed, 87 insertions(+), 27 deletions(-) diff --git a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderContext.h b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderContext.h index 775399066..989f1f2ea 100644 --- a/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderContext.h +++ b/Modules/Graphics/RHI/Base/Include/Methane/Graphics/Base/RenderContext.h @@ -67,6 +67,7 @@ class RenderContext // Rarely actual frame buffers count in swap-chain may be different from the requested, // so it may be changed from RenderContextXX::Initialize() method void InvalidateFrameBuffersCount(uint32_t frame_buffers_count); + void InvalidateFrameBufferIndex(uint32_t frame_buffer_index); Rhi::IFence& GetCurrentFrameFence() const; Rhi::IFence& GetRenderFence() const; diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueue.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueue.cpp index d70a72a46..ea23a4095 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueue.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/CommandQueue.cpp @@ -75,7 +75,6 @@ void CommandQueue::Execute(Rhi::ICommandListSet& command_lists, const Rhi::IComm { META_FUNCTION_TASK(); META_LOG("Command queue '{}' is executing", GetName()); - static_cast(command_lists).Execute(completed_callback); } diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderContext.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderContext.cpp index ecd797b99..e6665c993 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderContext.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/RenderContext.cpp @@ -198,7 +198,14 @@ void RenderContext::InvalidateFrameBuffersCount(uint32_t frame_buffers_count) // We just change count in settings assuming that this method is called only inside RenderContextXX::Initialize()s function m_settings.frame_buffers_count = frame_buffers_count; } - + +void RenderContext::InvalidateFrameBufferIndex(uint32_t frame_buffer_index) +{ + META_FUNCTION_TASK(); + META_CHECK_ARG_LESS(frame_buffer_index, m_settings.frame_buffers_count); + m_frame_buffer_index = frame_buffer_index; +} + uint32_t RenderContext::GetNextFrameBufferIndex() { META_FUNCTION_TASK(); diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h index 8e5475579..1ef7e27df 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h @@ -105,6 +105,13 @@ class RenderContext final // NOSONAR - this class requires destructor void ResetNativeSwapchain(); void ResetNativeObjectNames() const; + struct FrameSync + { + vk::UniqueSemaphore vk_unique_semaphore; + vk::UniqueFence vk_unique_fence; + bool is_submitted = false; + }; + const Methane::Platform::AppEnvironment m_app_env; const vk::Device m_vk_device; #ifdef __APPLE__ @@ -116,7 +123,7 @@ class RenderContext final // NOSONAR - this class requires destructor vk::Format m_vk_frame_format; vk::Extent2D m_vk_frame_extent; std::vector m_vk_frame_images; - std::vector m_vk_frame_semaphores_pool; + std::vector m_frame_sync_pool; std::vector m_vk_frame_image_available_semaphores; mutable std::deque m_vk_deferred_release_pipelines; }; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index 0e6500e66..9bd25e00e 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -128,11 +128,16 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet META_FUNCTION_TASK(); Base::CommandListSet::Execute(completed_callback); + const std::vector& wait_semaphores = GetWaitSemaphores(); + const std::vector& wait_stages = GetWaitStages(); vk::SubmitInfo submit_info( - GetWaitSemaphores(), - GetWaitStages(), - m_vk_command_buffers, - GetNativeExecutionCompletedSemaphore() + static_cast(wait_semaphores.size()), + wait_semaphores.empty() ? nullptr : wait_semaphores.data(), + wait_stages.data(), + static_cast(m_vk_command_buffers.size()), + m_vk_command_buffers.data(), + 1U, + &GetNativeExecutionCompletedSemaphore() ); Opt vk_timeline_submit_info_opt; @@ -189,11 +194,14 @@ const std::vector& CommandListSet::GetWaitSemaphores() return vk_wait_semaphores; m_vk_wait_semaphores = vk_wait_semaphores; + const Opt& frame_index_opt = GetFrameIndex(); const auto& render_context = dynamic_cast(command_queue.GetVulkanContext()); - m_vk_wait_semaphores.push_back( - frame_index_opt ? render_context.GetNativeFrameImageAvailableSemaphore(*frame_index_opt) - : render_context.GetNativeFrameImageAvailableSemaphore()); + const vk::Semaphore& frame_image_available_semaphore = frame_index_opt ? render_context.GetNativeFrameImageAvailableSemaphore(*frame_index_opt) + : render_context.GetNativeFrameImageAvailableSemaphore(); + if (frame_image_available_semaphore) + m_vk_wait_semaphores.push_back(frame_image_available_semaphore); + return m_vk_wait_semaphores; } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index 8ac693fb5..c605fec3e 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -116,7 +116,6 @@ void RenderContext::Initialize(Base::Device& device, bool is_callback_emitted) META_FUNCTION_TASK(); SetDevice(device); InitializeNativeSwapchain(); - UpdateFrameBufferIndex(); Context::Initialize(device, is_callback_emitted); } @@ -236,12 +235,34 @@ const vk::Semaphore& RenderContext::GetNativeFrameImageAvailableSemaphore() cons uint32_t RenderContext::GetNextFrameBufferIndex() { META_FUNCTION_TASK(); - uint32_t next_image_index = 0; - const uint32_t frame_semaphore_index = Base::RenderContext::GetFrameIndex() % m_vk_frame_semaphores_pool.size(); - const vk::Semaphore& vk_image_available_semaphore = m_vk_frame_semaphores_pool[frame_semaphore_index].get(); + const uint32_t frame_sync_index = Base::RenderContext::GetFrameIndex() % m_frame_sync_pool.size(); + const uint32_t await_sync_index = (frame_sync_index + 1U) % m_frame_sync_pool.size(); + + // Wait for the rendering of the frame [N - FBC] (where FBC is Frame Buffers Count) to be completed, + // which is accomplished by waiting for the next frame image availability [N - FBC - 1] + // or simply [N + 1] in the FBC ring buffer + if (FrameSync& await_frame_sync = m_frame_sync_pool[await_sync_index]; + await_frame_sync.is_submitted) + { + if (m_vk_device.getFenceStatus(await_frame_sync.vk_unique_fence.get()) == vk::Result::eNotReady) + { + const vk::Result wait_result = m_vk_device.waitForFences(await_frame_sync.vk_unique_fence.get(), true, std::numeric_limits::max()); + META_CHECK_ARG_EQUAL_DESCR(wait_result, vk::Result::eSuccess, "failed to wait for frame synchronization fence (-N-1)"); + } + m_vk_device.resetFences(await_frame_sync.vk_unique_fence.get()); + await_frame_sync.is_submitted = false; + } + + FrameSync& curr_frame_sync = m_frame_sync_pool[frame_sync_index]; + if (curr_frame_sync.is_submitted) + return GetFrameBufferIndex(); + // Acquire next frame image with signalling GPU semaphore and CPU fence when image will be acquired + uint32_t next_image_index = 0; switch (const vk::Result image_acquire_result = m_vk_device.acquireNextImageKHR(GetNativeSwapchain(), std::numeric_limits::max(), - vk_image_available_semaphore, {}, &next_image_index); + curr_frame_sync.vk_unique_semaphore.get(), + curr_frame_sync.vk_unique_fence.get(), + &next_image_index); image_acquire_result) { case vk::Result::eSuccess: @@ -260,7 +281,9 @@ uint32_t RenderContext::GetNextFrameBufferIndex() } const uint32_t next_frame_index = next_image_index % Base::RenderContext::GetSettings().frame_buffers_count; - m_vk_frame_image_available_semaphores[next_frame_index] = vk_image_available_semaphore; + m_vk_frame_image_available_semaphores[next_frame_index] = curr_frame_sync.vk_unique_semaphore.get(); + curr_frame_sync.is_submitted = true; + return next_frame_index; } @@ -376,18 +399,30 @@ void RenderContext::InitializeNativeSwapchain() // Create frame semaphores in pool const uint32_t frame_buffers_count = GetSettings().frame_buffers_count; - m_vk_frame_semaphores_pool.resize(frame_buffers_count); - for(vk::UniqueSemaphore& vk_unique_frame_semaphore : m_vk_frame_semaphores_pool) + m_frame_sync_pool.resize(frame_buffers_count); + for(FrameSync& frame_sync : m_frame_sync_pool) { - if (vk_unique_frame_semaphore) - continue; + if (!frame_sync.vk_unique_semaphore) + frame_sync.vk_unique_semaphore = m_vk_device.createSemaphoreUnique(vk::SemaphoreCreateInfo()); + + if (!frame_sync.vk_unique_fence) + frame_sync.vk_unique_fence = m_vk_device.createFenceUnique(vk::FenceCreateInfo()); - vk_unique_frame_semaphore = m_vk_device.createSemaphoreUnique(vk::SemaphoreCreateInfo()); + frame_sync.is_submitted = false; } // Image available semaphores are assigned from frame semaphores in GetNextFrameBufferIndex m_vk_frame_image_available_semaphores.resize(frame_buffers_count); + // Acquire first image from swapchain + const vk::UniqueFence first_image_fence = m_vk_device.createFenceUnique(vk::FenceCreateInfo()); + const vk::ResultValue first_image_acquire_result = m_vk_device.acquireNextImageKHR(GetNativeSwapchain(), std::numeric_limits::max(), {}, first_image_fence.get()); + META_CHECK_ARG_EQUAL_DESCR(first_image_acquire_result.result, vk::Result::eSuccess, "failed to acquire first image of the just created swapchain"); + InvalidateFrameBufferIndex(first_image_acquire_result.value);Improv + + const vk::Result wait_first_image_result = m_vk_device.waitForFences(first_image_fence.get(), true, std::numeric_limits::max()); + META_CHECK_ARG_EQUAL_DESCR(wait_first_image_result, vk::Result::eSuccess, "failed to wait for acquiring first image of the just created swapchain"); + ResetNativeObjectNames(); Data::Emitter::Emit(&IRenderContextCallback::OnRenderContextSwapchainChanged, std::ref(*this)); @@ -398,7 +433,7 @@ void RenderContext::ReleaseNativeSwapchainResources() META_FUNCTION_TASK(); WaitForGpu(WaitFor::RenderComplete); - m_vk_frame_semaphores_pool.clear(); + m_frame_sync_pool.clear(); m_vk_frame_image_available_semaphores.clear(); m_vk_frame_images.clear(); m_vk_unique_swapchain.reset(); @@ -424,13 +459,16 @@ void RenderContext::ResetNativeObjectNames() const SetVulkanObjectName(m_vk_device, m_vk_unique_swapchain.get(), context_name); uint32_t frame_index = 0u; - for (const vk::UniqueSemaphore& vk_unique_frame_semaphore : m_vk_frame_semaphores_pool) + for (const FrameSync& frame_sync : m_frame_sync_pool) { - if (!vk_unique_frame_semaphore) - continue; + if (!frame_sync.vk_unique_semaphore) + SetVulkanObjectName(m_vk_device, frame_sync.vk_unique_semaphore.get(), + fmt::format("{} Frame {} Image Available Semaphore", context_name, frame_index)); + + if (!frame_sync.vk_unique_fence) + SetVulkanObjectName(m_vk_device, frame_sync.vk_unique_fence.get(), + fmt::format("{} Frame {} Image Available Fence", context_name, frame_index)); - SetVulkanObjectName(m_vk_device, vk_unique_frame_semaphore.get(), - fmt::format("{} Frame {} Image Available", context_name, frame_index)); frame_index++; } } From fe7101b56694686413bdb3ae310d1c6daaa726b3 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Wed, 2 Aug 2023 00:24:22 +0300 Subject: [PATCH 43/64] Fix code typo and wait for semaphore values on execute --- .../Sources/Methane/Graphics/Vulkan/CommandListSet.cpp | 8 ++++---- .../Sources/Methane/Graphics/Vulkan/RenderContext.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index 9bd25e00e..29f18ad38 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -133,18 +133,18 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet vk::SubmitInfo submit_info( static_cast(wait_semaphores.size()), wait_semaphores.empty() ? nullptr : wait_semaphores.data(), - wait_stages.data(), + wait_stages.empty() ? nullptr : wait_stages.data(), static_cast(m_vk_command_buffers.size()), m_vk_command_buffers.data(), 1U, - &GetNativeExecutionCompletedSemaphore() + &m_vk_unique_execution_completed_semaphore.get() ); Opt vk_timeline_submit_info_opt; if (const std::vector& vk_wait_values = CommandListSet::GetWaitValues(); !vk_wait_values.empty()) { - META_CHECK_ARG_EQUAL(vk_wait_values.size(), submit_info.waitSemaphoreCount); + META_CHECK_ARG_EQUAL(vk_wait_values.size(), wait_semaphores.size()); vk_timeline_submit_info_opt.emplace(vk_wait_values); submit_info.setPNext(&vk_timeline_submit_info_opt.value()); } @@ -226,7 +226,7 @@ const std::vector& CommandListSet::GetWaitValues() META_CHECK_ARG_EQUAL(wait_before_exec.wait_values.size(), wait_before_exec.semaphores.size()); const std::vector& vk_wait_values = wait_before_exec.wait_values; - if (!m_vk_wait_frame_buffer_rendering_on_stages || vk_wait_values.empty()) + if (!m_vk_wait_frame_buffer_rendering_on_stages) return vk_wait_values; m_vk_wait_values = vk_wait_values; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index c605fec3e..8ffb1ad6d 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -418,7 +418,7 @@ void RenderContext::InitializeNativeSwapchain() const vk::UniqueFence first_image_fence = m_vk_device.createFenceUnique(vk::FenceCreateInfo()); const vk::ResultValue first_image_acquire_result = m_vk_device.acquireNextImageKHR(GetNativeSwapchain(), std::numeric_limits::max(), {}, first_image_fence.get()); META_CHECK_ARG_EQUAL_DESCR(first_image_acquire_result.result, vk::Result::eSuccess, "failed to acquire first image of the just created swapchain"); - InvalidateFrameBufferIndex(first_image_acquire_result.value);Improv + InvalidateFrameBufferIndex(first_image_acquire_result.value); const vk::Result wait_first_image_result = m_vk_device.waitForFences(first_image_fence.get(), true, std::numeric_limits::max()); META_CHECK_ARG_EQUAL_DESCR(wait_first_image_result, vk::Result::eSuccess, "failed to wait for acquiring first image of the just created swapchain"); From 890d3d1ae071de118b0fe402400ac4282b064f02 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Thu, 3 Aug 2023 22:09:40 +0300 Subject: [PATCH 44/64] Fix CommandListSet::Execute error due to unequal wait semaphores and values count --- .../Methane/Graphics/Vulkan/CommandListSet.h | 8 +- .../Methane/Graphics/Vulkan/CommandQueue.h | 2 +- .../Methane/Graphics/Vulkan/RenderContext.h | 3 +- .../Graphics/Vulkan/CommandListSet.cpp | 103 +++++++----------- .../Methane/Graphics/Vulkan/CommandQueue.cpp | 8 +- .../Methane/Graphics/Vulkan/RenderContext.cpp | 12 +- 6 files changed, 63 insertions(+), 73 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h index e2be37593..2a0f6e24c 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandListSet.h @@ -45,8 +45,8 @@ class CommandListSet final void WaitUntilCompleted() override; const std::vector& GetNativeCommandBuffers() const noexcept { return m_vk_command_buffers; } - const vk::Semaphore& GetNativeExecutionCompletedSemaphore() const noexcept { return m_vk_unique_execution_completed_semaphore.get(); } - const vk::Fence& GetNativeExecutionCompletedFence() const noexcept { return m_vk_unique_execution_completed_fence.get(); } + const vk::Semaphore& GetNativeExecutionCompletedSemaphore() const noexcept { return m_vk_unique_execution_completed_semaphore.get(); } + const vk::Fence& GetNativeExecutionCompletedFence() const noexcept { return m_vk_unique_execution_completed_fence.get(); } CommandQueue& GetVulkanCommandQueue() noexcept; const CommandQueue& GetVulkanCommandQueue() const noexcept; @@ -56,6 +56,8 @@ class CommandListSet final void OnObjectNameChanged(Rhi::IObject& object, const std::string& old_name) override; private: + using SubmitInfo = std::pair; + SubmitInfo GetSubmitInfo(); const std::vector& GetWaitSemaphores(); const std::vector& GetWaitStages(); const std::vector& GetWaitValues(); @@ -70,7 +72,7 @@ class CommandListSet final vk::UniqueSemaphore m_vk_unique_execution_completed_semaphore; vk::UniqueFence m_vk_unique_execution_completed_fence; bool m_signalled_execution_completed_fence = false; - TracyLockable(std::mutex, m_vk_unique_execution_completed_fence_mutex); + TracyLockable(std::mutex, m_execution_completed_fence_mutex); }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandQueue.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandQueue.h index f2a78177f..218ec9320 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandQueue.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/CommandQueue.h @@ -45,7 +45,7 @@ class CommandQueue final // NOSONAR - custom destructor is required { std::vector semaphores; std::vector stages; - std::vector wait_values; + std::vector values; }; CommandQueue(const Base::Context& context, Rhi::CommandListType command_lists_type); diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h index 1ef7e27df..e29389110 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h @@ -87,8 +87,9 @@ class RenderContext final // NOSONAR - this class requires destructor const vk::Extent2D& GetNativeFrameExtent() const noexcept { return m_vk_frame_extent; } vk::Format GetNativeFrameFormat() const noexcept { return m_vk_frame_format; } const vk::Image& GetNativeFrameImage(uint32_t frame_buffer_index) const; - const vk::Semaphore& GetNativeFrameImageAvailableSemaphore(uint32_t frame_buffer_index) const; const vk::Semaphore& GetNativeFrameImageAvailableSemaphore() const; + const vk::Semaphore& GetNativeFrameImageAvailableSemaphore(uint32_t frame_buffer_index) const; + const vk::Semaphore& GetNativeFrameImageAvailableSemaphore(Opt frame_buffer_index_opt) const; void DeferredRelease(vk::UniquePipeline&& pipeline) const { m_vk_deferred_release_pipelines.emplace_back(std::move(pipeline)); } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index 29f18ad38..53d09c970 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -128,43 +128,27 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet META_FUNCTION_TASK(); Base::CommandListSet::Execute(completed_callback); - const std::vector& wait_semaphores = GetWaitSemaphores(); - const std::vector& wait_stages = GetWaitStages(); - vk::SubmitInfo submit_info( - static_cast(wait_semaphores.size()), - wait_semaphores.empty() ? nullptr : wait_semaphores.data(), - wait_stages.empty() ? nullptr : wait_stages.data(), - static_cast(m_vk_command_buffers.size()), - m_vk_command_buffers.data(), - 1U, - &m_vk_unique_execution_completed_semaphore.get() - ); - - Opt vk_timeline_submit_info_opt; - if (const std::vector& vk_wait_values = CommandListSet::GetWaitValues(); - !vk_wait_values.empty()) + SubmitInfo submit_info = GetSubmitInfo(); + if (submit_info.second.waitSemaphoreValueCount || submit_info.second.signalSemaphoreValueCount) { - META_CHECK_ARG_EQUAL(vk_wait_values.size(), wait_semaphores.size()); - vk_timeline_submit_info_opt.emplace(vk_wait_values); - submit_info.setPNext(&vk_timeline_submit_info_opt.value()); + submit_info.first.setPNext(&submit_info.second); } - std::scoped_lock fence_guard(m_vk_unique_execution_completed_fence_mutex); - const vk::Fence& vk_fence = GetNativeExecutionCompletedFence(); + std::scoped_lock fence_guard(m_execution_completed_fence_mutex); if (m_signalled_execution_completed_fence) { // Do not reset not-signalled fence to workaround crash in validation layer on MacOS // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/4974 - m_vk_device.resetFences(vk_fence); + m_vk_device.resetFences(m_vk_unique_execution_completed_fence.get()); } - GetVulkanCommandQueue().GetNativeQueue().submit(submit_info, vk_fence); + GetVulkanCommandQueue().GetNativeQueue().submit(submit_info.first, m_vk_unique_execution_completed_fence.get()); m_signalled_execution_completed_fence = true; } void CommandListSet::WaitUntilCompleted() { META_FUNCTION_TASK(); - std::scoped_lock fence_guard(m_vk_unique_execution_completed_fence_mutex); + std::scoped_lock fence_guard(m_execution_completed_fence_mutex); const vk::Result execution_completed_fence_wait_result = m_vk_device.waitForFences( GetNativeExecutionCompletedFence(), true, std::numeric_limits::max() @@ -185,53 +169,50 @@ const CommandQueue& CommandListSet::GetVulkanCommandQueue() const noexcept return static_cast(GetBaseCommandQueue()); } -const std::vector& CommandListSet::GetWaitSemaphores() +CommandListSet::SubmitInfo CommandListSet::GetSubmitInfo() { META_FUNCTION_TASK(); const CommandQueue& command_queue = GetVulkanCommandQueue(); - const std::vector& vk_wait_semaphores = command_queue.GetWaitBeforeExecuting().semaphores; - if (!m_vk_wait_frame_buffer_rendering_on_stages) - return vk_wait_semaphores; - - m_vk_wait_semaphores = vk_wait_semaphores; - - const Opt& frame_index_opt = GetFrameIndex(); - const auto& render_context = dynamic_cast(command_queue.GetVulkanContext()); - const vk::Semaphore& frame_image_available_semaphore = frame_index_opt ? render_context.GetNativeFrameImageAvailableSemaphore(*frame_index_opt) - : render_context.GetNativeFrameImageAvailableSemaphore(); - if (frame_image_available_semaphore) - m_vk_wait_semaphores.push_back(frame_image_available_semaphore); + const CommandQueue::WaitInfo& wait_before_exec = command_queue.GetWaitBeforeExecuting(); + META_CHECK_ARG_EQUAL(wait_before_exec.values.size(), wait_before_exec.semaphores.size()); - return m_vk_wait_semaphores; -} + const std::vector& vk_wait_semaphores = m_vk_wait_frame_buffer_rendering_on_stages ? m_vk_wait_semaphores : wait_before_exec.semaphores; + const std::vector& vk_wait_values = m_vk_wait_frame_buffer_rendering_on_stages ? m_vk_wait_values : wait_before_exec.values; + const std::vector& vk_wait_stages = m_vk_wait_frame_buffer_rendering_on_stages ? m_vk_wait_stages : wait_before_exec.stages; -const std::vector& CommandListSet::GetWaitStages() -{ - META_FUNCTION_TASK(); - const CommandQueue& command_queue = GetVulkanCommandQueue(); - const std::vector& vk_wait_stages = command_queue.GetWaitBeforeExecuting().stages; - if (!m_vk_wait_frame_buffer_rendering_on_stages) - return vk_wait_stages; + if (m_vk_wait_frame_buffer_rendering_on_stages) + { + m_vk_wait_semaphores = wait_before_exec.semaphores; + m_vk_wait_values = wait_before_exec.values; + m_vk_wait_stages = wait_before_exec.stages; - m_vk_wait_stages = vk_wait_stages; - m_vk_wait_stages.push_back(m_vk_wait_frame_buffer_rendering_on_stages); - return m_vk_wait_stages; -} + const auto& render_context = dynamic_cast(command_queue.GetVulkanContext()); + const vk::Semaphore& frame_image_available_semaphore = render_context.GetNativeFrameImageAvailableSemaphore(GetFrameIndex()); + if (frame_image_available_semaphore) + { + m_vk_wait_semaphores.push_back(frame_image_available_semaphore); + m_vk_wait_values.push_back(0U); + m_vk_wait_stages.push_back(m_vk_wait_frame_buffer_rendering_on_stages); + } + } -const std::vector& CommandListSet::GetWaitValues() -{ - META_FUNCTION_TASK(); - const CommandQueue& command_queue = GetVulkanCommandQueue(); - const CommandQueue::WaitInfo& wait_before_exec = command_queue.GetWaitBeforeExecuting(); - META_CHECK_ARG_EQUAL(wait_before_exec.wait_values.size(), wait_before_exec.semaphores.size()); + SubmitInfo submit_info; + submit_info.first = vk::SubmitInfo( + static_cast(vk_wait_semaphores.size()), + vk_wait_semaphores.empty() ? nullptr : vk_wait_semaphores.data(), + vk_wait_stages.empty() ? nullptr : vk_wait_stages.data(), + static_cast(m_vk_command_buffers.size()), + m_vk_command_buffers.data(), + 1U, + &m_vk_unique_execution_completed_semaphore.get() + ); - const std::vector& vk_wait_values = wait_before_exec.wait_values; - if (!m_vk_wait_frame_buffer_rendering_on_stages) - return vk_wait_values; + if (!vk_wait_values.empty()) + { + submit_info.second = vk::TimelineSemaphoreSubmitInfo(vk_wait_values); + } - m_vk_wait_values = vk_wait_values; - m_vk_wait_values.push_back(0U); - return m_vk_wait_values; + return submit_info; } void CommandListSet::OnObjectNameChanged(Rhi::IObject& object, const std::string& old_name) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandQueue.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandQueue.cpp index c5f7ce1aa..9506f3d03 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandQueue.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandQueue.cpp @@ -179,7 +179,7 @@ void CommandQueue::Execute(Rhi::ICommandListSet& command_list_set, const Rhi::IC m_wait_before_executing.semaphores.clear(); m_wait_before_executing.stages.clear(); - m_wait_before_executing.wait_values.clear(); + m_wait_before_executing.values.clear(); } void CommandQueue::WaitForSemaphore(const vk::Semaphore& semaphore, vk::PipelineStageFlags stage_flags, const uint64_t* timeline_wait_value_ptr) @@ -188,14 +188,14 @@ void CommandQueue::WaitForSemaphore(const vk::Semaphore& semaphore, vk::Pipeline m_wait_before_executing.semaphores.emplace_back(semaphore); m_wait_before_executing.stages.emplace_back(stage_flags); - const bool no_timeline_waits = m_wait_before_executing.wait_values.empty(); + const bool no_timeline_waits = m_wait_before_executing.values.empty(); if (timeline_wait_value_ptr && no_timeline_waits) { - m_wait_before_executing.wait_values.resize(m_wait_before_executing.semaphores.size() - 1U, 0U); + m_wait_before_executing.values.resize(m_wait_before_executing.semaphores.size() - 1U, 0U); } if (timeline_wait_value_ptr || !no_timeline_waits) { - m_wait_before_executing.wait_values.push_back(timeline_wait_value_ptr ? *timeline_wait_value_ptr : 0U); + m_wait_before_executing.values.push_back(timeline_wait_value_ptr ? *timeline_wait_value_ptr : 0U); } } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index 8ffb1ad6d..87f21c27e 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -219,6 +219,12 @@ const vk::Image& RenderContext::GetNativeFrameImage(uint32_t frame_buffer_index) return m_vk_frame_images[frame_buffer_index]; } +const vk::Semaphore& RenderContext::GetNativeFrameImageAvailableSemaphore() const +{ + META_FUNCTION_TASK(); + return GetNativeFrameImageAvailableSemaphore(GetFrameBufferIndex()); +} + const vk::Semaphore& RenderContext::GetNativeFrameImageAvailableSemaphore(uint32_t frame_buffer_index) const { META_FUNCTION_TASK(); @@ -226,10 +232,10 @@ const vk::Semaphore& RenderContext::GetNativeFrameImageAvailableSemaphore(uint32 return m_vk_frame_image_available_semaphores[frame_buffer_index]; } -const vk::Semaphore& RenderContext::GetNativeFrameImageAvailableSemaphore() const +const vk::Semaphore& RenderContext::GetNativeFrameImageAvailableSemaphore(Opt frame_buffer_index_opt) const { - META_FUNCTION_TASK(); - return GetNativeFrameImageAvailableSemaphore(GetFrameBufferIndex()); + return frame_buffer_index_opt ? GetNativeFrameImageAvailableSemaphore(*frame_buffer_index_opt) + : GetNativeFrameImageAvailableSemaphore(); } uint32_t RenderContext::GetNextFrameBufferIndex() From 27ee6c2a0e16da422cee5a39d8d96d8d50f6799b Mon Sep 17 00:00:00 2001 From: egorodet Date: Thu, 3 Aug 2023 22:57:28 +0300 Subject: [PATCH 45/64] Fix wait for frame synchronization fence upon release of swapchain --- .../Methane/Graphics/Vulkan/RenderContext.h | 2 ++ .../Methane/Graphics/Vulkan/RenderContext.cpp | 33 ++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h index e29389110..e4a7cf997 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h @@ -111,6 +111,8 @@ class RenderContext final // NOSONAR - this class requires destructor vk::UniqueSemaphore vk_unique_semaphore; vk::UniqueFence vk_unique_fence; bool is_submitted = false; + + void Wait(const vk::Device& vk_device); }; const Methane::Platform::AppEnvironment m_app_env; diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index 87f21c27e..7c7df6f12 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -247,17 +247,7 @@ uint32_t RenderContext::GetNextFrameBufferIndex() // Wait for the rendering of the frame [N - FBC] (where FBC is Frame Buffers Count) to be completed, // which is accomplished by waiting for the next frame image availability [N - FBC - 1] // or simply [N + 1] in the FBC ring buffer - if (FrameSync& await_frame_sync = m_frame_sync_pool[await_sync_index]; - await_frame_sync.is_submitted) - { - if (m_vk_device.getFenceStatus(await_frame_sync.vk_unique_fence.get()) == vk::Result::eNotReady) - { - const vk::Result wait_result = m_vk_device.waitForFences(await_frame_sync.vk_unique_fence.get(), true, std::numeric_limits::max()); - META_CHECK_ARG_EQUAL_DESCR(wait_result, vk::Result::eSuccess, "failed to wait for frame synchronization fence (-N-1)"); - } - m_vk_device.resetFences(await_frame_sync.vk_unique_fence.get()); - await_frame_sync.is_submitted = false; - } + m_frame_sync_pool[await_sync_index].Wait(m_vk_device); FrameSync& curr_frame_sync = m_frame_sync_pool[frame_sync_index]; if (curr_frame_sync.is_submitted) @@ -439,6 +429,11 @@ void RenderContext::ReleaseNativeSwapchainResources() META_FUNCTION_TASK(); WaitForGpu(WaitFor::RenderComplete); + for(FrameSync& frame_sync : m_frame_sync_pool) + { + frame_sync.Wait(m_vk_device); + } + m_frame_sync_pool.clear(); m_vk_frame_image_available_semaphores.clear(); m_vk_frame_images.clear(); @@ -479,4 +474,20 @@ void RenderContext::ResetNativeObjectNames() const } } +void RenderContext::FrameSync::Wait(const vk::Device& vk_device) +{ + META_FUNCTION_TASK(); + if (!is_submitted) + return; + + if (vk_device.getFenceStatus(vk_unique_fence.get()) == vk::Result::eNotReady) + { + const vk::Result wait_result = vk_device.waitForFences(vk_unique_fence.get(), true, std::numeric_limits::max()); + META_CHECK_ARG_EQUAL_DESCR(wait_result, vk::Result::eSuccess, "failed to wait for frame synchronization fence (-N-1)"); + } + + vk_device.resetFences(vk_unique_fence.get()); + is_submitted = false; +} + } // namespace Methane::Graphics::Vulkan From a2eb69fce63a2d9f34d57bbaa86bc6826096ef0f Mon Sep 17 00:00:00 2001 From: egorodet Date: Thu, 3 Aug 2023 22:58:04 +0300 Subject: [PATCH 46/64] Add new CMake options to log output and to CMake presets --- CMakeLists.txt | 3 +++ CMakePresets.json | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e45e33d06..e657d070d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,8 @@ message(STATUS "METHANE applications build....................... ${METHANE_APPS message(STATUS "METHANE tests build.............................. ${METHANE_TESTS_BUILD_ENABLED}") message(STATUS "METHANE tests running during build............... ${METHANE_RUN_TESTS_DURING_BUILD}") message(STATUS "METHANE runtime validation checks................ ${METHANE_CHECKS_ENABLED}") +message(STATUS "METHANE unity build.............................. ${METHANE_UNITY_BUILD_ENABLED}") +message(STATUS "METHANE code coverage............................ ${METHANE_CODE_COVERAGE_ENABLED}") message(STATUS "METHANE debug logging............................ ${METHANE_LOGGING_ENABLED}") message(STATUS "METHANE command list debug groups................ ${METHANE_COMMAND_DEBUG_GROUPS_ENABLED}") message(STATUS "METHANE shaders code symbols..................... ${METHANE_SHADERS_CODEVIEW_ENABLED}") @@ -133,6 +135,7 @@ message(STATUS "METHANE ITT metadata............................. ${METHANE_ITT_ message(STATUS "METHANE GPU instrumentation...................... ${METHANE_GPU_INSTRUMENTATION_ENABLED}") message(STATUS "METHANE Tracy profiling.......................... ${METHANE_TRACY_PROFILING_ENABLED}") message(STATUS "METHANE Tracy profiling on demand................ ${METHANE_TRACY_PROFILING_ON_DEMAND}") +message(STATUS "METHANE memory sanitizer......................... ${METHANE_MEMORY_SANITIZER_ENABLED}") if (APPLE) message(STATUS "METHANE Apple code signing....................... ${METHANE_APPLE_CODE_SIGNING_ENABLED} (dev.team: '${APPLE_DEVELOPMENT_TEAM}')") diff --git a/CMakePresets.json b/CMakePresets.json index 32f38b5bc..69570851e 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -92,6 +92,10 @@ "type": "BOOL", "value": "OFF" }, + "METHANE_MEMORY_SANITIZER_ENABLED": { + "type": "BOOL", + "value": "OFF" + }, "METHANE_APPLE_CODE_SIGNING_ENABLED": { "type": "BOOL", "value": "OFF" From 155ecf8086126b87e8e39748e081a4bf20e27e16 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Fri, 4 Aug 2023 20:19:45 +0300 Subject: [PATCH 47/64] Bump Sonar-Scanner install action to v2 --- .github/workflows/ci-sonar-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-sonar-scan.yml b/.github/workflows/ci-sonar-scan.yml index 0e4d2bed9..c47f059cc 100644 --- a/.github/workflows/ci-sonar-scan.yml +++ b/.github/workflows/ci-sonar-scan.yml @@ -111,7 +111,7 @@ jobs: dotnet-version: 6.0.400 - name: Install Sonar-Scanner - uses: sonarsource/sonarcloud-github-c-cpp@v1 + uses: sonarsource/sonarcloud-github-c-cpp@v2 - name: Install Ninja uses: MethanePowered/gha-setup-ninja@master From 6939827ad031d3d6d646f5c23e73dc80ab75ed66 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Fri, 4 Aug 2023 22:42:40 +0300 Subject: [PATCH 48/64] Fix support of Vulkan on MacOS via MoltenVK by disabling timeline semaphore values in vk::SubmitInfo; fix VSync switch for Vulkan on MacOS --- Build/README.md | 2 +- CMake/MethaneGlobalOptions.cmake | 1 - .../Methane/Graphics/Vulkan/RenderContext.h | 23 ++++++++++--------- .../Graphics/Vulkan/CommandListSet.cpp | 23 +++++++++++-------- .../Methane/Graphics/Vulkan/RenderContext.cpp | 4 ++++ .../Methane/Graphics/Vulkan/RenderContext.mm | 14 ++++++++++- .../Methane/Graphics/Vulkan/System.cpp | 8 +++++++ 7 files changed, 52 insertions(+), 23 deletions(-) diff --git a/Build/README.md b/Build/README.md index 513f45d2e..d724687c9 100644 --- a/Build/README.md +++ b/Build/README.md @@ -142,7 +142,7 @@ Alternatively root [CMakeLists.txt](/CMakeLists.txt) can be opened directly in V [Methane Graphics RHI](/Modules/Graphics/RHI) is built using **Metal** graphics API on MacOS by default. Vulkan graphics API can be used instead by adding cmake generator option `-DMETHANE_GFX_VULKAN_ENABLED:BOOL=ON` or by running `Build/Unix/Build.sh --vulkan`, but it requires Vulkan SDK installation with MoltenVK driver implementation -on top of Metal, which is not currently supporting all extensions required by Methane Kit. +on top of Metal. Run built applications from the installation directory `Build/Output/XCode/Install/Apps`. diff --git a/CMake/MethaneGlobalOptions.cmake b/CMake/MethaneGlobalOptions.cmake index 74cf20fc8..97af1b295 100644 --- a/CMake/MethaneGlobalOptions.cmake +++ b/CMake/MethaneGlobalOptions.cmake @@ -94,7 +94,6 @@ elseif(APPLE) if (METHANE_GFX_API EQUAL METHANE_GFX_VULKAN) # * On Windows and Linux, only Vulkan-Headers are required to build Methane Kit, # because it is dynamically loading Vulkan library in runtime. Vulkan SDK is not required for build. - message(WARNING "METHANE RHI: Vulkan API is not fully supported on MacOS due to weired crash on submit to Transfer command queue") # * To enable Vulkan API on MacOS we link statically with MoltenVK framework (translation layer to Metal). # in order to enable finding Vulkan SDK with MoltenVK framework, environment variable might need to be set: # - VULKAN_SDK to full installation path before running CMake generator ($HOME/VulkanSDK/1.3.250.1/macOS) diff --git a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h index e4a7cf997..64c74b5ef 100644 --- a/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h +++ b/Modules/Graphics/RHI/Vulkan/Include/Methane/Graphics/Vulkan/RenderContext.h @@ -115,20 +115,21 @@ class RenderContext final // NOSONAR - this class requires destructor void Wait(const vk::Device& vk_device); }; - const Methane::Platform::AppEnvironment m_app_env; - const vk::Device m_vk_device; #ifdef __APPLE__ // MacOS metal app view with swap-chain implementation to work via MoltenVK - AppViewMetal* m_metal_view; + const AppViewMetal* m_metal_view; #endif - vk::UniqueSurfaceKHR m_vk_unique_surface; - vk::UniqueSwapchainKHR m_vk_unique_swapchain; - vk::Format m_vk_frame_format; - vk::Extent2D m_vk_frame_extent; - std::vector m_vk_frame_images; - std::vector m_frame_sync_pool; - std::vector m_vk_frame_image_available_semaphores; - mutable std::deque m_vk_deferred_release_pipelines; + + const Methane::Platform::AppEnvironment m_app_env; + const vk::Device m_vk_device; + vk::UniqueSurfaceKHR m_vk_unique_surface; + vk::UniqueSwapchainKHR m_vk_unique_swapchain; + vk::Format m_vk_frame_format; + vk::Extent2D m_vk_frame_extent; + std::vector m_vk_frame_images; + std::vector m_frame_sync_pool; + std::vector m_vk_frame_image_available_semaphores; + mutable std::deque m_vk_deferred_release_pipelines; }; } // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index 53d09c970..aafc81017 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -129,10 +129,16 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet Base::CommandListSet::Execute(completed_callback); SubmitInfo submit_info = GetSubmitInfo(); + + // FIXME: MoltenVK is crashing on Apple platforms on attempt to use submit info with timeline semaphore values, + // while timeline semaphore extension is properly enabled in Device.cpp and this code works fine on Linux. +#ifndef __APPLE__ if (submit_info.second.waitSemaphoreValueCount || submit_info.second.signalSemaphoreValueCount) { + // Bind vk::TimelineSemaphoreSubmitInfo to the vk::SubmitInfo submit_info.first.setPNext(&submit_info.second); } +#endif std::scoped_lock fence_guard(m_execution_completed_fence_mutex); if (m_signalled_execution_completed_fence) @@ -141,6 +147,7 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/4974 m_vk_device.resetFences(m_vk_unique_execution_completed_fence.get()); } + GetVulkanCommandQueue().GetNativeQueue().submit(submit_info.first, m_vk_unique_execution_completed_fence.get()); m_signalled_execution_completed_fence = true; } @@ -174,7 +181,6 @@ CommandListSet::SubmitInfo CommandListSet::GetSubmitInfo() META_FUNCTION_TASK(); const CommandQueue& command_queue = GetVulkanCommandQueue(); const CommandQueue::WaitInfo& wait_before_exec = command_queue.GetWaitBeforeExecuting(); - META_CHECK_ARG_EQUAL(wait_before_exec.values.size(), wait_before_exec.semaphores.size()); const std::vector& vk_wait_semaphores = m_vk_wait_frame_buffer_rendering_on_stages ? m_vk_wait_semaphores : wait_before_exec.semaphores; const std::vector& vk_wait_values = m_vk_wait_frame_buffer_rendering_on_stages ? m_vk_wait_values : wait_before_exec.values; @@ -196,19 +202,18 @@ CommandListSet::SubmitInfo CommandListSet::GetSubmitInfo() } } - SubmitInfo submit_info; + META_CHECK_ARG_EQUAL_DESCR(vk_wait_semaphores.size(), vk_wait_stages.size(), "number of wait semaphores and stages must be equal"); + SubmitInfo submit_info{}; submit_info.first = vk::SubmitInfo( - static_cast(vk_wait_semaphores.size()), - vk_wait_semaphores.empty() ? nullptr : vk_wait_semaphores.data(), - vk_wait_stages.empty() ? nullptr : vk_wait_stages.data(), - static_cast(m_vk_command_buffers.size()), - m_vk_command_buffers.data(), - 1U, - &m_vk_unique_execution_completed_semaphore.get() + vk_wait_semaphores, + vk_wait_stages, + m_vk_command_buffers, + m_vk_unique_execution_completed_semaphore.get() ); if (!vk_wait_values.empty()) { + META_CHECK_ARG_EQUAL_DESCR(vk_wait_semaphores.size(), vk_wait_values.size(), "number of wait timeline semaphores and values must be equal"); submit_info.second = vk::TimelineSemaphoreSubmitInfo(vk_wait_values); } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp index 7c7df6f12..41c3169b7 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.cpp @@ -190,6 +190,8 @@ void RenderContext::Present() UpdateFrameBufferIndex(); } +#ifndef __APPLE__ + bool RenderContext::SetVSyncEnabled(bool vsync_enabled) { META_FUNCTION_TASK(); @@ -201,6 +203,8 @@ bool RenderContext::SetVSyncEnabled(bool vsync_enabled) return false; } +#endif // # !defined(__APPLE__) + bool RenderContext::SetFrameBuffersCount(uint32_t frame_buffers_count) { META_FUNCTION_TASK(); diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm index 9e3cdf9f9..cf0f4bf03 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/RenderContext.mm @@ -32,9 +32,9 @@ RenderContext::RenderContext(const Methane::Platform::AppEnvironment& app_env, Device& device, tf::Executor& parallel_executor, const Rhi::RenderContextSettings& settings) : Context(device, parallel_executor, settings) + , m_metal_view(Metal::CreateRenderContextAppView(app_env, settings)) , m_app_env(app_env) , m_vk_device(device.GetNativeDevice()) - , m_metal_view(Metal::CreateRenderContextAppView(app_env, settings)) , m_vk_unique_surface(Platform::CreateVulkanSurfaceForWindow(static_cast(Rhi::ISystem::Get()).GetNativeInstance(), app_env)) { META_FUNCTION_TASK(); @@ -43,4 +43,16 @@ m_metal_view.redrawing = YES; } +bool RenderContext::SetVSyncEnabled(bool vsync_enabled) +{ + META_FUNCTION_TASK(); + if (Base::RenderContext::SetVSyncEnabled(vsync_enabled)) + { + ResetNativeSwapchain(); + m_metal_view.vsyncEnabled = vsync_enabled; + return true; + } + return false; } + +} // namespace Methane::Graphics::Vulkan diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp index 81e919791..3b3210ba5 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp @@ -149,6 +149,14 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(VkDebugUtilsMessageSe callback_data_ptr->messageIdNumber == 1630022081) // VUID-vkCmdPipelineBarrier-dstStageMask-03937 (vkCmdPipelineBarrier(): .dstStageMask must not be 0 unless synchronization2 is enabled) return VK_FALSE; +#ifdef __APPLE__ + // FIXME: disable warning on Apple "VkSemaphore is a timeline semaphore, but VkSubmitInfo does not include an instance of VkTimelineSemaphoreSubmitInfo", + // which was introduced as the result of the workaround of crash on vk::Queue::submit with vk::SubmitInfo containing a pointer to vk::TimelineSemaphoreSubmitInfo + // see Vulkan::CommandListSet::Execute() for more details + if (callback_data_ptr->messageIdNumber == -410448035) // VUID-VkSubmitInfo-pWaitSemaphores-03239 + return VK_FALSE; +#endif + if (callback_data_ptr->messageIdNumber == 0 && ( strstr(callback_data_ptr->pMessage, "loader_get_json: Failed to open JSON file") || strstr(callback_data_ptr->pMessage, "terminator_CreateInstance: Failed to CreateInstance in ICD"))) From 3545edbbc28bdd13a9e752a67ab1abf48ab28c48 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 5 Aug 2023 14:14:11 +0300 Subject: [PATCH 49/64] Use structured bindings for vk_submit_info, disable warning about dstStageMask on MacOS --- .../Sources/Methane/Graphics/Vulkan/CommandListSet.cpp | 9 +++++---- .../Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp index aafc81017..e3bd4c87f 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/CommandListSet.cpp @@ -128,15 +128,16 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet META_FUNCTION_TASK(); Base::CommandListSet::Execute(completed_callback); - SubmitInfo submit_info = GetSubmitInfo(); + auto [vk_submit_info, vk_timeline_semaphore_submit_info] = GetSubmitInfo(); // FIXME: MoltenVK is crashing on Apple platforms on attempt to use submit info with timeline semaphore values, // while timeline semaphore extension is properly enabled in Device.cpp and this code works fine on Linux. #ifndef __APPLE__ - if (submit_info.second.waitSemaphoreValueCount || submit_info.second.signalSemaphoreValueCount) + if (vk_timeline_semaphore_submit_info.waitSemaphoreValueCount || + vk_timeline_semaphore_submit_info.signalSemaphoreValueCount) { // Bind vk::TimelineSemaphoreSubmitInfo to the vk::SubmitInfo - submit_info.first.setPNext(&submit_info.second); + vk_submit_info.setPNext(&vk_timeline_semaphore_submit_info); } #endif @@ -148,7 +149,7 @@ void CommandListSet::Execute(const Rhi::ICommandList::CompletedCallback& complet m_vk_device.resetFences(m_vk_unique_execution_completed_fence.get()); } - GetVulkanCommandQueue().GetNativeQueue().submit(submit_info.first, m_vk_unique_execution_completed_fence.get()); + GetVulkanCommandQueue().GetNativeQueue().submit(vk_submit_info, m_vk_unique_execution_completed_fence.get()); m_signalled_execution_completed_fence = true; } diff --git a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp index 3b3210ba5..ccac9b320 100644 --- a/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp +++ b/Modules/Graphics/RHI/Vulkan/Sources/Methane/Graphics/Vulkan/System.cpp @@ -143,10 +143,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(VkDebugUtilsMessageSe // Assert on calling vkBeginCommandBuffer() on active VkCommandBuffer before it has completed. You must check command buffer fence before this call. //assert(callback_data_ptr->messageIdNumber == -2080204129); // VUID-vkBeginCommandBuffer-commandBuffer-00049 - if (callback_data_ptr->messageIdNumber == 648835635 || // UNASSIGNED-khronos-Validation-debug-build-warning-message - callback_data_ptr->messageIdNumber == 767975156 || // UNASSIGNED-BestPractices-vkCreateInstance-specialise-extension - callback_data_ptr->messageIdNumber == -400166253 || // UNASSIGNED-CoreValidation-DrawState-QueueForwardProgress - callback_data_ptr->messageIdNumber == 1630022081) // VUID-vkCmdPipelineBarrier-dstStageMask-03937 (vkCmdPipelineBarrier(): .dstStageMask must not be 0 unless synchronization2 is enabled) + if (callback_data_ptr->messageIdNumber == 648835635 || // UNASSIGNED-khronos-Validation-debug-build-warning-message + callback_data_ptr->messageIdNumber == 767975156 || // UNASSIGNED-BestPractices-vkCreateInstance-specialise-extension + callback_data_ptr->messageIdNumber == -400166253 || // UNASSIGNED-CoreValidation-DrawState-QueueForwardProgress + callback_data_ptr->messageIdNumber == -2117225404 || // VUID-vkCmdPipelineBarrier-dstStageMask-04996 (vkCmdPipelineBarrier(): .dstStageMask must not be 0 unless synchronization2 is enabled) + callback_data_ptr->messageIdNumber == 1630022081) // VUID-vkCmdPipelineBarrier-dstStageMask-03937 (vkCmdPipelineBarrier(): .dstStageMask must not be 0 unless synchronization2 is enabled) return VK_FALSE; #ifdef __APPLE__ From b18f6ff3bf4f650ca23974eedfa8bdd28d8889df Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 5 Aug 2023 17:33:35 +0300 Subject: [PATCH 50/64] Update External libraries: - Catch2 v3.1.0 -> v3.4.0, - CLI11 v2.2.0 -> v2.3.2, - CMRC v2.0.1 -> v2.0.2, - CPM v0.38.0 -> v0.38.2, - FMT v8.1.1 -> v10.0.0, - FTXUI v4.0.0 -> v4.1.1 - ITT Api v3.23.0 -> v3.24.2 - MagicEnum v0.8.0 -> v0.9.3 - TaskFlow v3.4.0 -> v3.6.0 - STB 2021-09-10 -> 2023-01-29 --- .../ParallelRenderingApp.cpp | 4 +- Externals/CLI11.cmake | 2 +- Externals/CMRC.cmake | 2 +- Externals/CPM.cmake | 9 ++-- Externals/Catch2.cmake | 2 +- Externals/FMT.cmake | 4 +- Externals/FTXUI.cmake | 3 +- Externals/IttApi.cmake | 2 +- Externals/MagicEnum.cmake | 2 +- Externals/README.md | 44 ++++++++--------- Externals/STB.cmake | 2 +- Externals/TaskFlow.cmake | 2 +- .../RangeSet/Include/Methane/Data/Range.hpp | 9 ---- .../Include/Methane/Data/RangeUtils.hpp | 12 +++++ .../Include/Methane/Data/TypeFormatters.hpp | 49 +++++++++++++------ .../Sources/Methane/Graphics/ImageLoader.cpp | 3 +- .../Methane/Graphics/MeshBuffersBase.cpp | 2 +- .../Graphics/Base/DescriptorManager.cpp | 4 +- .../Base/ParallelRenderCommandList.cpp | 2 +- .../Graphics/Base/ProgramArgumentBinding.cpp | 19 ++++--- .../Methane/Graphics/DirectX/IResource.cpp | 7 ++- .../Methane/Graphics/DirectX/Texture.cpp | 7 ++- .../Methane/Graphics/RHI/TypeFormatters.hpp | 14 ++++-- .../Methane/Graphics/RHI/IProgramBindings.cpp | 5 +- .../Methane/Graphics/RHI/IRenderPattern.cpp | 7 ++- .../Methane/Graphics/RHI/IRenderState.cpp | 5 +- .../Methane/Graphics/TypeFormatters.hpp | 21 +++++--- .../App/Sources/Methane/Platform/AppBase.cpp | 1 + .../Include/Methane/HlslCatchHelpers.hpp | 2 +- 29 files changed, 152 insertions(+), 95 deletions(-) diff --git a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp index 1e0819e19..fb18ec7f6 100644 --- a/Apps/07-ParallelRendering/ParallelRenderingApp.cpp +++ b/Apps/07-ParallelRendering/ParallelRenderingApp.cpp @@ -30,7 +30,7 @@ Tutorial demonstrating parallel rendering with Methane graphics API #include #include -#include +#include #include #include #include @@ -305,7 +305,7 @@ ParallelRenderingApp::CubeArrayParameters ParallelRenderingApp::InitializeCubeAr }); // Sort cubes parameters by thread index - // to make sure that actual cubes distrubution by render threads will match thread_index in parameters + // to make sure that actual cubes distribution by render threads will match thread_index in parameters // NOTE-1: thread index is displayed on cube faces as text label using an element of Texture 2D Array. // NOTE-2: Sorting also improves rendering performance because it ensures using one texture for all cubes per thread. tf::Task sort_task = task_flow.sort(cube_array_parameters.begin(), cube_array_parameters.end(), diff --git a/Externals/CLI11.cmake b/Externals/CLI11.cmake index 3f8ee4dbb..81879c9a1 100644 --- a/Externals/CLI11.cmake +++ b/Externals/CLI11.cmake @@ -1,5 +1,5 @@ CPMAddPackage( NAME CLI11 GITHUB_REPOSITORY MethanePowered/CLI11 - VERSION 2.2.0 + VERSION 2.3.2 ) diff --git a/Externals/CMRC.cmake b/Externals/CMRC.cmake index 2de2dd07f..16b2840ba 100644 --- a/Externals/CMRC.cmake +++ b/Externals/CMRC.cmake @@ -1,7 +1,7 @@ CPMAddPackage( NAME CMRC GITHUB_REPOSITORY MethanePowered/CMRC - GIT_TAG a64bea50c05594c8e7cf1f08e441bb9507742e2e # last commit from 'master' branch + GIT_TAG 2.0.2 DOWNLOAD_ONLY YES ) diff --git a/Externals/CPM.cmake b/Externals/CPM.cmake index 3f8ca3814..f49d74341 100644 --- a/Externals/CPM.cmake +++ b/Externals/CPM.cmake @@ -1,4 +1,4 @@ -set(CPM_DOWNLOAD_VERSION 0.38.0) +set(CPM_DOWNLOAD_VERSION 0.38.2) if(CPM_SOURCE_CACHE) set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") @@ -14,9 +14,9 @@ get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) function(download_cpm) message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") file(DOWNLOAD - https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake - ${CPM_DOWNLOAD_LOCATION} - ) + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} + ) endfunction() if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) @@ -27,6 +27,7 @@ else() if("${check}" STREQUAL "") download_cpm() endif() + unset(check) endif() include(${CPM_DOWNLOAD_LOCATION}) diff --git a/Externals/Catch2.cmake b/Externals/Catch2.cmake index 017eb4512..ead92dd5e 100644 --- a/Externals/Catch2.cmake +++ b/Externals/Catch2.cmake @@ -1,7 +1,7 @@ CPMAddPackage( NAME Catch2 GITHUB_REPOSITORY MethanePowered/Catch2 - VERSION 3.1.0 + VERSION 3.4.0 ) list(APPEND CMAKE_MODULE_PATH "${Catch2_SOURCE_DIR}/extras") diff --git a/Externals/FMT.cmake b/Externals/FMT.cmake index 45092b953..b8f476a3d 100644 --- a/Externals/FMT.cmake +++ b/Externals/FMT.cmake @@ -1,8 +1,8 @@ CPMAddPackage( NAME FMT GITHUB_REPOSITORY MethanePowered/FMT - GIT_TAG 8.1.1 - VERSION 8.1.1 + GIT_TAG 10.0.0 + VERSION 10.0.0 ) set_target_properties(fmt diff --git a/Externals/FTXUI.cmake b/Externals/FTXUI.cmake index b03aa32ac..9a0c10a98 100644 --- a/Externals/FTXUI.cmake +++ b/Externals/FTXUI.cmake @@ -1,8 +1,7 @@ CPMAddPackage( NAME FTXUI GITHUB_REPOSITORY MethanePowered/FTXUI - GIT_TAG 436c237213a75107bea99a41a9672fca6c86de02 - #VERSION 4.0.0 + VERSION 4.1.1 OPTIONS "FTXUI_BUILD_DOCS OFF" "FTXUI_BUILD_EXAMPLES OFF" diff --git a/Externals/IttApi.cmake b/Externals/IttApi.cmake index d080f06c9..9ac095b5b 100644 --- a/Externals/IttApi.cmake +++ b/Externals/IttApi.cmake @@ -2,7 +2,7 @@ CPMAddPackage( NAME IttApi GITHUB_REPOSITORY MethanePowered/IttApi GIT_TAG 19ab01fb45aa9f4050a22026929417ade689a36a # last commit in 'fix_cmake_policy_0048_warning' branch - VERSION 3.23.0 + VERSION 3.24.2 ) set_target_properties(ittnotify diff --git a/Externals/MagicEnum.cmake b/Externals/MagicEnum.cmake index 75e28b7d1..ae8adfde3 100644 --- a/Externals/MagicEnum.cmake +++ b/Externals/MagicEnum.cmake @@ -1,7 +1,7 @@ CPMAddPackage( NAME MagicEnum GITHUB_REPOSITORY MethanePowered/MagicEnum - VERSION 0.8.0 + VERSION 0.9.3 OPTIONS "MAGIC_ENUM_OPT_INSTALL ON" ) diff --git a/Externals/README.md b/Externals/README.md index 170b7b03d..a102a5097 100644 --- a/Externals/README.md +++ b/Externals/README.md @@ -10,33 +10,33 @@ to support parallel cmake configurations processing. ## Libraries -| Libraries | Version | Linkage | License | Description | -|-------------------------------------------------------------------|------------|-------------------|---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------| -| [Boost Nowide](https://github.com/boostorg/nowide) | 11.1.4 | Static | [BSL 1.0](https://github.com/boostorg/nowide/blob/develop/LICENSE) | Standard library functions with UTF-8 API on Windows. | -| [Catch2](https://github.com/catchorg/Catch2) | 3.1.0 | Static (tests) | [BSL 1.0](https://github.com/catchorg/Catch2/blob/devel/LICENSE.txt) | A modern, C++-native, test framework for unit-tests, TDD and BDD - using C++14, C++17 and later. | -| [CLI11](https://github.com/CLIUtils/CLI11) | 2.2.0 | Header-only | [CLI11 2.2](https://github.com/CLIUtils/CLI11/blob/main/LICENSE) | CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface. | -| [DirectX Headers](https://github.com/microsoft/DirectX-Headers) | 1.608.2b | Header-only | [MIT](https://github.com/microsoft/DirectX-Headers/blob/main/LICENSE) | Official DirectX headers available under an open source license | -| [DirectX Tex](https://github.com/microsoft/DirectXTex) | 1.9.6 | Static | [MIT](https://github.com/microsoft/DirectXTex/blob/main/LICENSE) | Texture processing library. | -| [FMT](https://github.com/fmtlib/fmt) | 8.1.1 | Header-only | [Victor Zverovich](https://github.com/fmtlib/fmt/blob/master/LICENSE.rst) | A modern formatting library. | -| [FreeType](https://gitlab.freedesktop.org/freetype/freetype/) | 2.12.1 | Static | [FreeType (GPL 3.0)](https://gitlab.freedesktop.org/freetype/freetype/-/blob/master/docs/FTL.TXT) | FreeType is a freely available software library to render fonts. | -| [FTXUI](https://github.com/ArthurSonzogni/FTXUI/) | 4.0.0 | Static | [MIT](https://github.com/ArthurSonzogni/FTXUI/blob/main/LICENSE) | C++ Functional Terminal User Interface. | -| [HLSL++](https://github.com/redorav/hlslpp) | 3.3.1 | Header-only | [MIT](https://github.com/MethanePowered/HLSLpp/blob/master/LICENSE) | Math library using hlsl syntax with SSE/NEON support. | -| [ITT API](https://github.com/intel/ittapi) | 3.23.0 | Static | [BSD 3.0](https://github.com/MethanePowered/IttApi/blob/master/LICENSES/BSD-3-Clause.txt) | IntelĀ® Instrumentation and Tracing Technology (ITT) and Just-In-Time (JIT) API. | -| [Magic Enum](https://github.com/Neargye/magic_enum) | 0.8.0 | Header-only | [MIT](https://github.com/Neargye/magic_enum/blob/master/LICENSE) | Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code. | -| [OpenImageIO](https://github.com/OpenImageIO/oiio) | 2.0.5 | Static (optional) | [GPL 3.0](https://github.com/OpenCppCoverage/OpenCppCoverage/blob/master/LICENSE.txt) | Reading, writing, and processing images in a wide variety of file formats, using a format-agnostic API, aimed at VFX applications. | -| [Perlin Noise](https://github.com/stegu/perlin-noise/) | 1.0 | Static | [Public Domain](https://github.com/stegu/perlin-noise/blob/master/LICENSE.md) | Simplex and Perlin noise implementation by Stefan Gustavson. | -| [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross) | 1.3.216.0 | Static | [Apache 2.0](https://github.com/KhronosGroup/SPIRV-Cross/blob/master/LICENSE) | A library for performing reflection on SPIR-V and disassembling SPIR-V back to high level languages. | -| [STB](https://github.com/nothings/stb) | 2021-09-10 | Header-only | [MIT, Public Domain](https://github.com/nothings/stb/blob/master/LICENSE) | Single-file public domain libraries for C/C++. | -| [TaskFlow](https://github.com/taskflow/taskflow) | 3.4.0 | Header-only | [MIT](https://github.com/taskflow/taskflow/blob/master/LICENSE) | A General-purpose Parallel and Heterogeneous Task Programming System. | -| [Tracy](https://github.com/wolfpld/tracy) | 0.9.1 | Static | [BSD 3.0](https://github.com/wolfpld/tracy/blob/master/LICENSE) | A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications. | -| [Vulkan Headers](https://github.com/MethanePowered/VulkanHeaders) | 1.3.219 | Header-only | [Apache 2.0](https://github.com/KhronosGroup/Vulkan-Headers/blob/main/LICENSE.txt) | Vulkan Header files and API registry. | +| Libraries | Version | Linkage | License | Description | +|-------------------------------------------------------------------|------------------------------|-------------------|---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------| +| [Boost Nowide](https://github.com/boostorg/nowide) | [README.md](README.md)11.1.4 | Static | [BSL 1.0](https://github.com/boostorg/nowide/blob/develop/LICENSE) | Standard library functions with UTF-8 API on Windows. | +| [Catch2](https://github.com/catchorg/Catch2) | 3.4.0 | Static (tests) | [BSL 1.0](https://github.com/catchorg/Catch2/blob/devel/LICENSE.txt) | A modern, C++-native, test framework for unit-tests, TDD and BDD - using C++14, C++17 and later. | +| [CLI11](https://github.com/CLIUtils/CLI11) | 2.3.2 | Header-only | [CLI11 2.2](https://github.com/CLIUtils/CLI11/blob/main/LICENSE) | CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface. | +| [DirectX Headers](https://github.com/microsoft/DirectX-Headers) | 1.608.2b | Header-only | [MIT](https://github.com/microsoft/DirectX-Headers/blob/main/LICENSE) | Official DirectX headers available under an open source license | +| [DirectX Tex](https://github.com/microsoft/DirectXTex) | 1.9.6 | Static | [MIT](https://github.com/microsoft/DirectXTex/blob/main/LICENSE) | Texture processing library. | +| [FMT](https://github.com/fmtlib/fmt) | 10.0.0 | Header-only | [Victor Zverovich](https://github.com/fmtlib/fmt/blob/master/LICENSE.rst) | A modern formatting library. | +| [FreeType](https://gitlab.freedesktop.org/freetype/freetype/) | 2.12.1 | Static | [FreeType (GPL 3.0)](https://gitlab.freedesktop.org/freetype/freetype/-/blob/master/docs/FTL.TXT) | FreeType is a freely available software library to render fonts. | +| [FTXUI](https://github.com/ArthurSonzogni/FTXUI/) | 4.1.1 | Static | [MIT](https://github.com/ArthurSonzogni/FTXUI/blob/main/LICENSE) | C++ Functional Terminal User Interface. | +| [HLSL++](https://github.com/redorav/hlslpp) | 3.3.1 | Header-only | [MIT](https://github.com/MethanePowered/HLSLpp/blob/master/LICENSE) | Math library using hlsl syntax with SSE/NEON support. | +| [ITT API](https://github.com/intel/ittapi) | 3.24.2 | Static | [BSD 3.0](https://github.com/MethanePowered/IttApi/blob/master/LICENSES/BSD-3-Clause.txt) | IntelĀ® Instrumentation and Tracing Technology (ITT) and Just-In-Time (JIT) API. | +| [Magic Enum](https://github.com/Neargye/magic_enum) | 0.9.3 | Header-only | [MIT](https://github.com/Neargye/magic_enum/blob/master/LICENSE) | Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code. | +| [OpenImageIO](https://github.com/OpenImageIO/oiio) | 2.0.5 | Static (optional) | [GPL 3.0](https://github.com/OpenCppCoverage/OpenCppCoverage/blob/master/LICENSE.txt) | Reading, writing, and processing images in a wide variety of file formats, using a format-agnostic API, aimed at VFX applications. | +| [Perlin Noise](https://github.com/stegu/perlin-noise/) | 1.0 | Static | [Public Domain](https://github.com/stegu/perlin-noise/blob/master/LICENSE.md) | Simplex and Perlin noise implementation by Stefan Gustavson. | +| [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross) | 1.3.216.0 | Static | [Apache 2.0](https://github.com/KhronosGroup/SPIRV-Cross/blob/master/LICENSE) | A library for performing reflection on SPIR-V and disassembling SPIR-V back to high level languages. | +| [STB](https://github.com/nothings/stb) | 2023-01-29 | Header-only | [MIT, Public Domain](https://github.com/nothings/stb/blob/master/LICENSE) | Single-file public domain libraries for C/C++. | +| [TaskFlow](https://github.com/taskflow/taskflow) | 3.6.0 | Header-only | [MIT](https://github.com/taskflow/taskflow/blob/master/LICENSE) | A General-purpose Parallel and Heterogeneous Task Programming System. | +| [Tracy](https://github.com/wolfpld/tracy) | 0.9.1 | Static | [BSD 3.0](https://github.com/wolfpld/tracy/blob/master/LICENSE) | A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications. | +| [Vulkan Headers](https://github.com/MethanePowered/VulkanHeaders) | 1.3.219 | Header-only | [Apache 2.0](https://github.com/KhronosGroup/Vulkan-Headers/blob/main/LICENSE.txt) | Vulkan Header files and API registry. | ## Build Tools | Script or Tool | Version | Usage | License | Description | |-------------------------------------------------------------------------------|-----------|--------------------------|------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------| -| [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) | 0.38.0 | CMake | [MIT](https://github.com/cpm-cmake/CPM.cmake/blob/master/LICENSE) | CMake's missing package manager. | -| [CMRC](https://github.com/vector-of-bool/cmrc) | n/a | CMake | [MIT](https://github.com/vector-of-bool/cmrc/blob/master/LICENSE.txt) | A Resource Compiler in a Single CMake script. | +| [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) | 0.38.2 | CMake | [MIT](https://github.com/cpm-cmake/CPM.cmake/blob/master/LICENSE) | CMake's missing package manager. | +| [CMRC](https://github.com/vector-of-bool/cmrc) | 2.0.2 | CMake | [MIT](https://github.com/vector-of-bool/cmrc/blob/master/LICENSE.txt) | A Resource Compiler in a Single CMake script. | | [CMake Modules](https://github.com/rpavlik/cmake-modules) | n/a | CMake | [BSL 1.0](https://github.com/microsoft/CMakeModules/blob/main/LICENSE_1_0.txt) | R.Pavlik collection of CMake modules. | | [iOS-Toolchain.cmake](https://github.com/leetal/ios-cmake) | 4.3.0 | CMake | [BSD 3.0](https://github.com/leetal/ios-cmake/blob/master/LICENSE.md) | A CMake toolchain file for iOS, macOS, watchOS & tvOS C/C++/Obj-C++ development. | | | [DirectX Shader Compiler](https://github.com/microsoft/DirectXShaderCompiler) | 1.6.2104 | HLSL Compiler to SPIRV | [LLVM Release](https://github.com/microsoft/DirectXShaderCompiler/blob/main/LICENSE.TXT) | Open-source HLSL Shader Compiler which is based on LLVM/Clang. | diff --git a/Externals/STB.cmake b/Externals/STB.cmake index 804dbbaac..eafe7925a 100644 --- a/Externals/STB.cmake +++ b/Externals/STB.cmake @@ -1,7 +1,7 @@ CPMAddPackage( NAME STB GITHUB_REPOSITORY MethanePowered/STB - GIT_TAG af1a5bc352164740c1cc1354942b1c6b72eacb8a + GIT_TAG master ) add_library(STB INTERFACE) diff --git a/Externals/TaskFlow.cmake b/Externals/TaskFlow.cmake index 75276b418..b75245c4b 100644 --- a/Externals/TaskFlow.cmake +++ b/Externals/TaskFlow.cmake @@ -1,7 +1,7 @@ CPMAddPackage( NAME TaskFlow GITHUB_REPOSITORY MethanePowered/TaskFlow - VERSION 3.4.0 + VERSION 3.6.0 OPTIONS "TF_BUILD_BENCHMARKS OFF" "TF_BUILD_CUDA OFF" diff --git a/Modules/Data/RangeSet/Include/Methane/Data/Range.hpp b/Modules/Data/RangeSet/Include/Methane/Data/Range.hpp index d02312072..d1e57e7f7 100644 --- a/Modules/Data/RangeSet/Include/Methane/Data/Range.hpp +++ b/Modules/Data/RangeSet/Include/Methane/Data/Range.hpp @@ -28,7 +28,6 @@ till end (exclusively): [start, end) #include #include -#include #include #include @@ -102,11 +101,3 @@ class Range }; } // namespace Methane::Data - -template -struct fmt::formatter> -{ - template - auto format(const Methane::Data::Range& range, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(range)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } -}; diff --git a/Modules/Data/RangeSet/Include/Methane/Data/RangeUtils.hpp b/Modules/Data/RangeSet/Include/Methane/Data/RangeUtils.hpp index 2207fd070..400ab60d4 100644 --- a/Modules/Data/RangeSet/Include/Methane/Data/RangeUtils.hpp +++ b/Modules/Data/RangeSet/Include/Methane/Data/RangeUtils.hpp @@ -29,8 +29,20 @@ minimum number of continuous ranges by merging or splitting adjacent ranges in s #include +#include #include +template +struct fmt::formatter> +{ + template + auto format(const Methane::Data::Range& range, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(range)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } +}; + namespace Methane::Data { diff --git a/Modules/Data/Types/Include/Methane/Data/TypeFormatters.hpp b/Modules/Data/Types/Include/Methane/Data/TypeFormatters.hpp index 22fb4dadd..d16ee17c9 100644 --- a/Modules/Data/Types/Include/Methane/Data/TypeFormatters.hpp +++ b/Modules/Data/Types/Include/Methane/Data/TypeFormatters.hpp @@ -33,54 +33,75 @@ template<> struct fmt::formatter { template - [[nodiscard]] auto format(const hlslpp::float2& v, FormatContext& ctx) { return format_to(ctx.out(), "V({}, {})", v.x, v.y); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const hlslpp::float2& v, FormatContext& ctx) const + { return format_to(ctx.out(), "V({}, {})", v[0], v[1]); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template<> struct fmt::formatter { template - [[nodiscard]] auto format(const hlslpp::float3& v, FormatContext& ctx) { return format_to(ctx.out(), "V({}, {}, {})", v.x, v.y, v.z); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const hlslpp::float3& v, FormatContext& ctx) const + { return format_to(ctx.out(), "V({}, {}, {})", v[0], v[1], v[2]); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template<> struct fmt::formatter { template - [[nodiscard]] auto format(const hlslpp::float4& v, FormatContext& ctx) { return format_to(ctx.out(), "V({}, {}, {}, {})", v.x, v.y, v.z, v.w); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const hlslpp::float4& v, FormatContext& ctx) const + { return format_to(ctx.out(), "V({}, {}, {}, {})", v[0], v[1], v[2], v[3]); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template struct fmt::formatter> { template - [[nodiscard]] auto format(const Methane::Data::RawVector& v, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(v)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Data::RawVector& v, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(v)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template struct fmt::formatter> { template - [[nodiscard]] auto format(const Methane::Data::Point& point, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(point)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Data::Point& point, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(point)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template struct fmt::formatter> { template - [[nodiscard]] auto format(const Methane::Data::RectSize& rect_size, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(rect_size)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Data::RectSize& rect_size, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(rect_size)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template struct fmt::formatter> { template - [[nodiscard]] auto format(const Methane::Data::Rect& rect, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(rect)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Data::Rect& rect, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(rect)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; \ No newline at end of file diff --git a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp index b8a608854..8f389bdc8 100644 --- a/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp +++ b/Modules/Graphics/Primitives/Sources/Methane/Graphics/ImageLoader.cpp @@ -27,11 +27,10 @@ by decoding them from popular image formats. #include #include #include -#include #include #include -#include +#include #ifdef USE_OPEN_IMAGE_IO diff --git a/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp b/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp index a5a6cd145..a8ccdf493 100644 --- a/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp +++ b/Modules/Graphics/Primitives/Sources/Methane/Graphics/MeshBuffersBase.cpp @@ -28,7 +28,7 @@ Mesh buffers base implementation class. #include #include -#include +#include #include namespace Methane::Graphics diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/DescriptorManager.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/DescriptorManager.cpp index 1e77a32d2..051b27ada 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/DescriptorManager.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/DescriptorManager.cpp @@ -27,7 +27,7 @@ Base descriptor manager implementation. #include -#include +#include namespace Methane::Graphics::Base { @@ -49,7 +49,7 @@ void DescriptorManager::CompleteInitialization() m_program_bindings.erase(program_bindings_end_it, m_program_bindings.end()); - static const auto binding_initialization_completer = [](const WeakPtr& program_bindings_wptr) + constexpr auto binding_initialization_completer = [](const WeakPtr& program_bindings_wptr) { META_FUNCTION_TASK(); // Some binding pointers may become expired here due to command list retained resources cleanup on execution completion diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp index c35a5a4a6..1cba8da37 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ParallelRenderCommandList.cpp @@ -34,7 +34,7 @@ Base implementation of the parallel render command list interface. #include -#include +#include #include #include diff --git a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ProgramArgumentBinding.cpp b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ProgramArgumentBinding.cpp index 57182af9e..34b5b4a11 100644 --- a/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ProgramArgumentBinding.cpp +++ b/Modules/Graphics/RHI/Base/Sources/Methane/Graphics/Base/ProgramArgumentBinding.cpp @@ -33,26 +33,33 @@ template<> struct fmt::formatter { template - [[nodiscard]] auto format(const Methane::Graphics::Rhi::IResource::View& rl, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(rl)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::Rhi::IResource::View& rl, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(rl)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template<> struct fmt::formatter { template - [[nodiscard]] auto format(const Methane::Graphics::Rhi::ProgramArgumentAccessor& rl, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(rl)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::Rhi::ProgramArgumentAccessor& rl, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(rl)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template<> struct fmt::formatter { template - [[nodiscard]] auto format(const Methane::Graphics::Rhi::ResourceUsageMask& rl, FormatContext& ctx) + [[nodiscard]] auto format(const Methane::Graphics::Rhi::ResourceUsageMask& rl, FormatContext& ctx) const { return format_to(ctx.out(), "{}", Methane::Data::GetEnumMaskName(rl)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; namespace Methane::Graphics::Base diff --git a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/IResource.cpp b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/IResource.cpp index 09c6938ca..9a203fb6c 100644 --- a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/IResource.cpp +++ b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/IResource.cpp @@ -29,8 +29,11 @@ template<> struct fmt::formatter { template - [[nodiscard]] auto format(const Methane::Graphics::Rhi::ResourceUsage& rl, FormatContext& ctx) { return format_to(ctx.out(), "{}", fmt::join(rl.GetBitNames(), "|")); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::Rhi::ResourceUsage& rl, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", fmt::join(rl.GetBitNames(), "|")); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; namespace Methane::Graphics::DirectX diff --git a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp index 7fe8e53bf..734256109 100644 --- a/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp +++ b/Modules/Graphics/RHI/DirectX/Sources/Methane/Graphics/DirectX/Texture.cpp @@ -45,8 +45,11 @@ template<> struct fmt::formatter { template - [[nodiscard]] auto format(const Methane::Graphics::Rhi::ResourceUsage& rl, FormatContext& ctx) { return format_to(ctx.out(), "{}", fmt::join(rl.GetBitNames(), "|")); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::Rhi::ResourceUsage& rl, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", fmt::join(rl.GetBitNames(), "|")); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; namespace Methane::Graphics::DirectX diff --git a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/TypeFormatters.hpp b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/TypeFormatters.hpp index 653f0285a..5fe2af92d 100644 --- a/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/TypeFormatters.hpp +++ b/Modules/Graphics/RHI/Interface/Include/Methane/Graphics/RHI/TypeFormatters.hpp @@ -29,14 +29,20 @@ template<> struct fmt::formatter { template - auto format(const Methane::Graphics::Rhi::SubResource::Index& index, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(index)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + auto format(const Methane::Graphics::Rhi::SubResource::Index& index, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(index)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template<> struct fmt::formatter { template - auto format(const Methane::Graphics::Rhi::SubResource::Count& count, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(count)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + auto format(const Methane::Graphics::Rhi::SubResource::Count& count, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(count)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; \ No newline at end of file diff --git a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IProgramBindings.cpp b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IProgramBindings.cpp index 7093035b5..9fdb622f8 100644 --- a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IProgramBindings.cpp +++ b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IProgramBindings.cpp @@ -33,10 +33,11 @@ Methane program bindings interface for resources binding to program arguments. template<> struct fmt::formatter { - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } template - auto format(const Methane::Graphics::Rhi::ProgramArgument& program_argument, FormatContext& ctx) + auto format(const Methane::Graphics::Rhi::ProgramArgument& program_argument, FormatContext& ctx) const { return format_to(ctx.out(), "{}", static_cast(program_argument)); } diff --git a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderPattern.cpp b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderPattern.cpp index cbb875de1..4d098799c 100644 --- a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderPattern.cpp +++ b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderPattern.cpp @@ -33,8 +33,11 @@ template<> struct fmt::formatter { template - [[nodiscard]] auto format(const Methane::Graphics::Rhi::RenderPassColorAttachment& ca, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(ca)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::Rhi::RenderPassColorAttachment& ca, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(ca)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; namespace Methane::Graphics::Rhi diff --git a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderState.cpp b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderState.cpp index 3a3940547..0db97716d 100644 --- a/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderState.cpp +++ b/Modules/Graphics/RHI/Interface/Sources/Methane/Graphics/RHI/IRenderState.cpp @@ -34,10 +34,11 @@ template<> struct fmt::formatter { template - [[nodiscard]] auto format(const Methane::Graphics::Rhi::RenderTargetSettings& rt, FormatContext& ctx) + [[nodiscard]] auto format(const Methane::Graphics::Rhi::RenderTargetSettings& rt, FormatContext& ctx) const { return format_to(ctx.out(), "{}", static_cast(rt)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; namespace Methane::Graphics::Rhi diff --git a/Modules/Graphics/Types/Include/Methane/Graphics/TypeFormatters.hpp b/Modules/Graphics/Types/Include/Methane/Graphics/TypeFormatters.hpp index 0d7140860..b9d50bf83 100644 --- a/Modules/Graphics/Types/Include/Methane/Graphics/TypeFormatters.hpp +++ b/Modules/Graphics/Types/Include/Methane/Graphics/TypeFormatters.hpp @@ -32,22 +32,31 @@ template struct fmt::formatter> { template - [[nodiscard]] auto format(const Methane::Graphics::VolumeSize& vol_size, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(vol_size)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::VolumeSize& vol_size, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(vol_size)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template struct fmt::formatter> { template - [[nodiscard]] auto format(const Methane::Graphics::Volume& vol, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(vol)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::Volume& vol, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(vol)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; template struct fmt::formatter> { template - [[nodiscard]] auto format(const Methane::Graphics::ColorF& color, FormatContext& ctx) { return format_to(ctx.out(), "{}", static_cast(color)); } - [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const { return ctx.end(); } + [[nodiscard]] auto format(const Methane::Graphics::ColorF& color, FormatContext& ctx) const + { return format_to(ctx.out(), "{}", static_cast(color)); } + + [[nodiscard]] constexpr auto parse(const format_parse_context& ctx) const + { return ctx.end(); } }; diff --git a/Modules/Platform/App/Sources/Methane/Platform/AppBase.cpp b/Modules/Platform/App/Sources/Methane/Platform/AppBase.cpp index 47489da01..8eaead078 100644 --- a/Modules/Platform/App/Sources/Methane/Platform/AppBase.cpp +++ b/Modules/Platform/App/Sources/Methane/Platform/AppBase.cpp @@ -31,6 +31,7 @@ Base application interface and platform-independent implementation. #include #include +#include #include #include diff --git a/Tests/CatchHelpers/Include/Methane/HlslCatchHelpers.hpp b/Tests/CatchHelpers/Include/Methane/HlslCatchHelpers.hpp index e69ac017b..0f67c0e06 100644 --- a/Tests/CatchHelpers/Include/Methane/HlslCatchHelpers.hpp +++ b/Tests/CatchHelpers/Include/Methane/HlslCatchHelpers.hpp @@ -87,7 +87,7 @@ class HlslVectorApproxEqualsMatcher std::string describe() const override { - return fmt::format("approximately equals to {} with precision {}", m_reference_vector, m_precision_vector.x); + return fmt::format("approximately equals to {} with precision {}", m_reference_vector, m_precision_vector[0]); } private: From 07b092d411dc82d5d95742c14f45e0cd6e5f44bb Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 5 Aug 2023 18:11:09 +0300 Subject: [PATCH 51/64] Mute clang warning in Taskflow headers --- Externals/TaskFlow.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Externals/TaskFlow.cmake b/Externals/TaskFlow.cmake index b75245c4b..acd02b14f 100644 --- a/Externals/TaskFlow.cmake +++ b/Externals/TaskFlow.cmake @@ -15,4 +15,8 @@ if(MSVC) target_compile_options(Taskflow INTERFACE /wd4456 # declaration of 'lock' hides previous local declaration (taskflow/core/executor.hpp:1842) ) +else() # Clang or GCC + target_compile_options(Taskflow INTERFACE + -Wno-shorten-64-to-32 # implicit conversion loses integer precision: 'unsigned long' to 'int' (taskflow/core/observer.hpp:568:24) + ) endif() \ No newline at end of file From 0ca34c034e8ad5205b8e5539a573855e337d72fd Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sat, 5 Aug 2023 18:11:21 +0300 Subject: [PATCH 52/64] Add new CI Build for MacOS with Vulkan RHI --- .github/workflows/ci-build.yml | 31 ++++++++++++++++++ CMakePresets.json | 57 ++++++++++++++++++++++++++++++++++ README.md | 1 + 3 files changed, 89 insertions(+) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 9a511a3e8..8632ba69a 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -54,6 +54,7 @@ jobs: named_logo: Windows run_tests: true add_tracy_app: false + install_vulkan_sdk: false - os: windows-latest os_name: Windows @@ -63,6 +64,7 @@ jobs: named_logo: Windows run_tests: true add_tracy_app: false + install_vulkan_sdk: false - os: windows-latest os_name: Windows @@ -72,6 +74,7 @@ jobs: named_logo: Windows run_tests: false add_tracy_app: true + install_vulkan_sdk: false - os: windows-latest os_name: Windows @@ -81,6 +84,7 @@ jobs: named_logo: Windows run_tests: false add_tracy_app: true + install_vulkan_sdk: false - os: windows-latest os_name: Windows @@ -90,6 +94,7 @@ jobs: named_logo: Windows run_tests: true add_tracy_app: false + install_vulkan_sdk: false - os: windows-latest os_name: Windows @@ -99,6 +104,7 @@ jobs: named_logo: Windows run_tests: true add_tracy_app: false + install_vulkan_sdk: false - os: windows-latest os_name: Windows @@ -108,6 +114,7 @@ jobs: named_logo: Windows run_tests: false add_tracy_app: true + install_vulkan_sdk: false - os: windows-latest os_name: Windows @@ -117,6 +124,7 @@ jobs: named_logo: Windows run_tests: false add_tracy_app: true + install_vulkan_sdk: false - os: ubuntu-latest os_name: Ubuntu @@ -126,6 +134,7 @@ jobs: named_logo: Linux run_tests: true add_tracy_app: false + install_vulkan_sdk: false - os: ubuntu-latest os_name: Ubuntu @@ -135,6 +144,17 @@ jobs: named_logo: Linux run_tests: false add_tracy_app: true + install_vulkan_sdk: false + + - os: macos-latest + os_name: MacOS + name: "MacOS_VK_Release" + config_preset: "Xcode-Mac-VK-Default" + build_preset: "Xcode-Mac-VK-Release" + named_logo: Apple + run_tests: true + add_tracy_app: false + install_vulkan_sdk: true - os: macos-latest os_name: MacOS @@ -144,6 +164,7 @@ jobs: named_logo: Apple run_tests: true add_tracy_app: false + install_vulkan_sdk: false - os: macos-latest os_name: MacOS @@ -153,6 +174,7 @@ jobs: named_logo: Apple run_tests: false add_tracy_app: true + install_vulkan_sdk: false - os: macos-latest os_name: MacOS @@ -162,6 +184,7 @@ jobs: named_logo: Apple run_tests: false add_tracy_app: false + install_vulkan_sdk: false - os: macos-latest os_name: MacOS @@ -171,6 +194,7 @@ jobs: named_logo: Apple run_tests: false add_tracy_app: false + install_vulkan_sdk: false runs-on: ${{ matrix.os }} @@ -193,6 +217,13 @@ jobs: with: domain: ${{ github.repository_owner }} + - name: Install Vulkan SDK + if: ${{ matrix.install_vulkan_sdk }} + uses: humbletim/install-vulkan-sdk@v1.1.1 + with: + version: 1.3.204.0 + cache: true + - name: Initialize Externals Cache uses: actions/cache@v3 with: diff --git a/CMakePresets.json b/CMakePresets.json index 69570851e..53f45fe0a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -704,6 +704,30 @@ } }, + { + "name": "Ninja-Mac-VK-Default", + "displayName": "Default - Ninja Multi-Config - MacOS (Vulkan)", + "description": "Default configuration using Ninja Multi-Config generator for MacOS (Vulkan)", + "inherits": [ + "Ninja-Mac-Default" + ], + "cacheVariables": { + "METHANE_GFX_VULKAN_ENABLED": { + "type": "BOOL", + "value": "ON" + } + } + }, + { + "name": "Xcode-Mac-VK-Default", + "displayName": "Default - Xcode - MacOS (Vulkan)", + "description": "Default configuration using Xcode generator for MacOS (Vulkan)", + "generator": "Xcode", + "inherits": [ + "Ninja-Mac-VK-Default" + ] + }, + { "name": "Ninja-Mac-MTL-Default", "displayName": "Default - Ninja Multi-Config - MacOS (Metal)", @@ -1266,6 +1290,39 @@ "configurePreset": "Make-Lin-VK-Scan" }, + { + "name": "Ninja-Mac-VK-Debug", + "displayName": "Debug - Ninja Multi-Config - MacOS (Vulkan)", + "description": "Debug build with Ninja Multi-Config for MacOS (Vulkan)", + "inherits": [ "MacOS-Build" ], + "configurePreset": "Ninja-Mac-VK-Default", + "configuration": "Debug" + }, + { + "name": "Ninja-Mac-VK-Release", + "displayName": "Release - Ninja Multi-Config - MacOS (Vulkan)", + "description": "Release build with Ninja Multi-Config for MacOS (Vulkan)", + "inherits": [ "MacOS-Build" ], + "configurePreset": "Ninja-Mac-VK-Default", + "configuration": "Release" + }, + { + "name": "Xcode-Mac-VK-Debug", + "displayName": "Debug - Xcode - MacOS (Vulkan)", + "description": "Debug build with Xcode for MacOS (Vulkan)", + "inherits": [ "MacOS-Build" ], + "configurePreset": "Xcode-Mac-VK-Default", + "configuration": "Debug" + }, + { + "name": "Xcode-Mac-VK-Release", + "displayName": "Release - Xcode - MacOS (Vulkan)", + "description": "Release build with Xcode for MacOS (Vulkan)", + "inherits": [ "MacOS-Build" ], + "configurePreset": "Xcode-Mac-VK-Default", + "configuration": "Release" + }, + { "name": "Ninja-Mac-MTL-Debug", "displayName": "Debug - Ninja Multi-Config - MacOS (Metal)", diff --git a/README.md b/README.md index 35e5fff4e..f91237db1 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ See [Build Instructions](/Build/README.md) topic for manual build instructions a | **Windows x64** | Vulkan | [![Windows x64 Master Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_Win64_VK_Release_master.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Amaster) | [![Windows x64 Develop Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_Win64_VK_Release_develop.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Adevelop) | | **Windows x86** | Vulkan | [![Windows x86 Master Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_Win32_VK_Release_master.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Amaster) | [![Windows x86 Develop Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_Win32_VK_Release_develop.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Adevelop) | | **Linux** | Vulkan | [![Ubuntu Master Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_Ubuntu_VK_Release_master.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Amaster) | [![Ubuntu Develop Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_Ubuntu_VK_Release_develop.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Adevelop) | +| **MacOS** | Vulkan | [![MacOS Master Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_MacOS_VK_Release_master.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Amaster) | [![MacOS Develop Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_MacOS_VK_Release_develop.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Adevelop) | | **MacOS** | Metal | [![MacOS Master Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_MacOS_MTL_Release_master.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Amaster) | [![MacOS Develop Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_MacOS_MTL_Release_develop.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Adevelop) | | **iOS** (Sim) | Metal | [![iOS Master Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_iOS_Sim_MTL_Release_master.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Amaster) | [![iOS Develop Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_iOS_Sim_MTL_Release_develop.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Adevelop) | | **tvOS** (Sim) | Metal | [![tvOS Master Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_tvOS_Sim_MTL_Release_master.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Amaster) | [![tvOS Develop Build](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/egorodet/96d788046ccd52b45b3354a99f8569c3/raw/MethaneKit_tvOS_Sim_MTL_Release_develop.json)](https://github.com/MethanePowered/MethaneKit/actions/workflows/ci-build.yml?query=branch%3Adevelop) | From 38a656cc5254d90c35410b5c411ce13681b5918f Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Sat, 5 Aug 2023 19:21:21 +0300 Subject: [PATCH 53/64] Fix build errors --- .github/workflows/ci-build.yml | 4 ++-- Externals/STB.cmake | 6 ++++++ Externals/TaskFlow.cmake | 3 +++ .../DirectX/Include/Methane/Graphics/DirectX/Resource.hpp | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 8632ba69a..4396f0217 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -219,9 +219,9 @@ jobs: - name: Install Vulkan SDK if: ${{ matrix.install_vulkan_sdk }} - uses: humbletim/install-vulkan-sdk@v1.1.1 + uses: humbletim/install-vulkan-sdk@v1 with: - version: 1.3.204.0 + version: 1.3.250.1 cache: true - name: Initialize Externals Cache diff --git a/Externals/STB.cmake b/Externals/STB.cmake index eafe7925a..bb018ae3e 100644 --- a/Externals/STB.cmake +++ b/Externals/STB.cmake @@ -6,3 +6,9 @@ CPMAddPackage( add_library(STB INTERFACE) target_include_directories(STB INTERFACE "${STB_SOURCE_DIR}") + +if(MSVC) + target_compile_options(STB INTERFACE + /wd4244 # conversion from 'int' to 'short', possible loss of data (stb_image.h:2224) + ) +endif() # MSVC \ No newline at end of file diff --git a/Externals/TaskFlow.cmake b/Externals/TaskFlow.cmake index acd02b14f..1e4d06886 100644 --- a/Externals/TaskFlow.cmake +++ b/Externals/TaskFlow.cmake @@ -5,6 +5,7 @@ CPMAddPackage( OPTIONS "TF_BUILD_BENCHMARKS OFF" "TF_BUILD_CUDA OFF" + "TF_BUILD_SYCL OFF" "TF_BUILD_TESTS OFF" "TF_BUILD_EXAMPLES OFF" ) @@ -14,6 +15,8 @@ add_library(TaskFlow ALIAS Taskflow) if(MSVC) target_compile_options(Taskflow INTERFACE /wd4456 # declaration of 'lock' hides previous local declaration (taskflow/core/executor.hpp:1842) + /wd4267 # conversion from 'size_t' to 'unsigned char', possible loss of data (taskflow/algorithm/sort.hpp:229) + /wd4146 # unary minus operator applied to unsigned type, result still unsigned (taskflow/algorithm/sort.hpp:42) ) else() # Clang or GCC target_compile_options(Taskflow INTERFACE diff --git a/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Resource.hpp b/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Resource.hpp index ca9508c67..825f9e7c5 100644 --- a/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Resource.hpp +++ b/Modules/Graphics/RHI/DirectX/Include/Methane/Graphics/DirectX/Resource.hpp @@ -159,7 +159,7 @@ class Resource // NOSONAR - destructor in use Rhi::ResourceState resource_state, const D3D12_CLEAR_VALUE* p_clear_value = nullptr) { META_FUNCTION_TASK(); - META_CHECK_ARG_DESCR(m_cp_resource, !m_cp_resource, "committed resource is already initialized"); + META_CHECK_ARG_DESCR(m_cp_resource.Get(), !m_cp_resource, "committed resource is already initialized"); const D3D12_RESOURCE_STATES d3d_resource_state = IResource::GetNativeResourceState(resource_state); m_cp_resource = CreateCommittedResource(resource_desc, heap_type, d3d_resource_state, p_clear_value); SetState(resource_state); From 87d3681885d2eefadb9bd60ce4f47e12aed880b6 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Sat, 5 Aug 2023 20:27:11 +0300 Subject: [PATCH 54/64] Mute one more MSVC warning in Taskflow headers --- Externals/TaskFlow.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/Externals/TaskFlow.cmake b/Externals/TaskFlow.cmake index 1e4d06886..2d7c9f282 100644 --- a/Externals/TaskFlow.cmake +++ b/Externals/TaskFlow.cmake @@ -17,6 +17,7 @@ if(MSVC) /wd4456 # declaration of 'lock' hides previous local declaration (taskflow/core/executor.hpp:1842) /wd4267 # conversion from 'size_t' to 'unsigned char', possible loss of data (taskflow/algorithm/sort.hpp:229) /wd4146 # unary minus operator applied to unsigned type, result still unsigned (taskflow/algorithm/sort.hpp:42) + /wd4244 # conversion from '_Rep' to 'size_t', possible loss of data (taskflow/core/observer.hpp:884) ) else() # Clang or GCC target_compile_options(Taskflow INTERFACE From 2a93d576362094cdf9f92748cb54a3bd139fc1d5 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Sat, 5 Aug 2023 20:29:07 +0300 Subject: [PATCH 55/64] Try to fix Vulkan SDK install action by running image mount with 'sudo' --- .github/workflows/ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 4396f0217..9875ae685 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -219,7 +219,7 @@ jobs: - name: Install Vulkan SDK if: ${{ matrix.install_vulkan_sdk }} - uses: humbletim/install-vulkan-sdk@v1 + uses: MethanePowered/InstallVulkanSdk@v1 with: version: 1.3.250.1 cache: true From 13ba90c0e097e21aed9d69f106a1283edc6c462e Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetsky Date: Sat, 5 Aug 2023 20:36:07 +0300 Subject: [PATCH 56/64] Fix version of the forked action --- .github/workflows/ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 9875ae685..7ff9b2765 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -219,7 +219,7 @@ jobs: - name: Install Vulkan SDK if: ${{ matrix.install_vulkan_sdk }} - uses: MethanePowered/InstallVulkanSdk@v1 + uses: MethanePowered/InstallVulkanSdk@main with: version: 1.3.250.1 cache: true From 3f7c5470c64d4a13ff4e334d3055cb61b57b86d9 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 00:20:01 +0300 Subject: [PATCH 57/64] Configure InstallVulkanSdk action with destination path --- .github/workflows/ci-build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 7ff9b2765..c4709339f 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -222,7 +222,8 @@ jobs: uses: MethanePowered/InstallVulkanSdk@main with: version: 1.3.250.1 - cache: true + destination: ${{ runner.tool_cache }}/VulkanSdk + use_cache: true - name: Initialize Externals Cache uses: actions/cache@v3 From f55de7d5b58ce4771b8da628a3cc347029b522fe Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 11:39:41 +0300 Subject: [PATCH 58/64] Manually unpack Vulkan SDK on MacOS in CI Build --- .github/workflows/ci-build.yml | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index c4709339f..576844c4b 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -34,6 +34,7 @@ env: product_ver_patch: 2 product_ver_build: ${{ github.run_number }} tracy_release_version: "0.9.1" + vulkan_sdk_version: "1.3.250.1" is_origin_repository: ${{ github.repository == 'MethanePowered/MethaneKit' }} # TSC Invariant check is disabled to allow running Catch test executables only for tests list query by CTest TRACY_NO_INVARIANT_CHECK: 1 @@ -219,11 +220,27 @@ jobs: - name: Install Vulkan SDK if: ${{ matrix.install_vulkan_sdk }} - uses: MethanePowered/InstallVulkanSdk@main - with: - version: 1.3.250.1 - destination: ${{ runner.tool_cache }}/VulkanSdk - use_cache: true + run: | + runner_os=$(uname -s) + case $runner_os in + macOS|Darwin) sdk_os=mac ;; + Linux) sdk_os=linux ;; + Windows|MINGW*) sdk_os=windows ;; + *) echo "unknown runner_os: $runner_os" ; exit 7 ; ;; + esac + sdk_ver=${{ env.vulkan_sdk_version }} + sdk_dir=${{ runner.tool_cache }}/VulkanSDK + test -d $sdk_dir || mkdir -pv $sdk_dir + curl -sSLo vulkan_sdk.7z https://github.com/MethanePowered/VulkanHeaders/releases/download/sdk-$sdk_ver/vulkan_sdk_$sdk_os.7z + 7z x vulkan_sdk.7z -o$sdk_dir + sdk_ver_dir=$sdk_dir/$sdk_ver + test -d $sdk_ver_dir + fi + ( + echo VULKAN_SDK=$sdk_ver_dir + echo VULKAN_SDK_VERSION=$sdk_ver + echo VULKAN_SDK_PLATFORM=$sdk_os + ) | tee -a $GITHUB_ENV - name: Initialize Externals Cache uses: actions/cache@v3 From 343df59ee361ba26718249bb3ac612661a47e3d3 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 12:06:20 +0300 Subject: [PATCH 59/64] Fix VulkanSDK unpack script --- .github/workflows/ci-build.yml | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 576844c4b..ede54eceb 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -226,21 +226,26 @@ jobs: macOS|Darwin) sdk_os=mac ;; Linux) sdk_os=linux ;; Windows|MINGW*) sdk_os=windows ;; - *) echo "unknown runner_os: $runner_os" ; exit 7 ; ;; + *) echo "Unknown runner_os: $runner_os" ; exit 7 ; ;; esac - sdk_ver=${{ env.vulkan_sdk_version }} - sdk_dir=${{ runner.tool_cache }}/VulkanSDK - test -d $sdk_dir || mkdir -pv $sdk_dir - curl -sSLo vulkan_sdk.7z https://github.com/MethanePowered/VulkanHeaders/releases/download/sdk-$sdk_ver/vulkan_sdk_$sdk_os.7z - 7z x vulkan_sdk.7z -o$sdk_dir - sdk_ver_dir=$sdk_dir/$sdk_ver - test -d $sdk_ver_dir + sdk_ver="${{ env.vulkan_sdk_version }}" + sdk_dir="${{ runner.tool_cache }}/VulkanSDK" + sdk_ver_dir="$sdk_dir/$sdk_ver" + if [ -d "$sdk_ver_dir" ]; then + echo "Vulkan SDK version directory already exists: $sdk_ver_dir" + else + test -d $sdk_dir || mkdir -pv $sdk_dir + vulkan_sdk_url=https://github.com/MethanePowered/VulkanHeaders/releases/download/sdk-$sdk_ver/vulkan_sdk_$sdk_os.7z + echo "Downloading Vulkan SDK archive $vulkan_sdk_url ..." + curl -sSLo vulkan_sdk.7z $vulkan_sdk_url + echo "Unpacking Vulkan SDK archive to $sdk_dir ..." + 7z x vulkan_sdk.7z -o$sdk_dir + test -d $sdk_ver_dir fi - ( - echo VULKAN_SDK=$sdk_ver_dir - echo VULKAN_SDK_VERSION=$sdk_ver - echo VULKAN_SDK_PLATFORM=$sdk_os - ) | tee -a $GITHUB_ENV + echo "Setting VULKAN_SDK* environment variables..." + echo "VULKAN_SDK=$sdk_ver_dir" >> $GITHUB_ENV + echo "VULKAN_SDK_VERSION=$sdk_ver" >> $GITHUB_ENV + echo "VULKAN_SDK_PLATFORM=$sdk_os" >> $GITHUB_ENV - name: Initialize Externals Cache uses: actions/cache@v3 From ae1fbbab024137cf5fa9fab2b31c61f9125c5221 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 12:42:50 +0300 Subject: [PATCH 60/64] Fix VulkanSDK unpack script --- .github/workflows/ci-build.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index ede54eceb..2d36d145b 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -223,14 +223,14 @@ jobs: run: | runner_os=$(uname -s) case $runner_os in - macOS|Darwin) sdk_os=mac ;; - Linux) sdk_os=linux ;; - Windows|MINGW*) sdk_os=windows ;; + macOS|Darwin) sdk_os=mac ; sdk_os_subdir=macOS ;; + Linux) sdk_os=linux ; sdk_os_subdir=linux ;; + Windows|MINGW*) sdk_os=windows ; sdk_os_subdir=windows ;; *) echo "Unknown runner_os: $runner_os" ; exit 7 ; ;; esac sdk_ver="${{ env.vulkan_sdk_version }}" - sdk_dir="${{ runner.tool_cache }}/VulkanSDK" - sdk_ver_dir="$sdk_dir/$sdk_ver" + sdk_dir="Build/Output/ExternalsCache/VulkanSDK" + sdk_ver_dir="$sdk_dir/$sdk_ver/$sdk_os_subdir" if [ -d "$sdk_ver_dir" ]; then echo "Vulkan SDK version directory already exists: $sdk_ver_dir" else @@ -240,12 +240,17 @@ jobs: curl -sSLo vulkan_sdk.7z $vulkan_sdk_url echo "Unpacking Vulkan SDK archive to $sdk_dir ..." 7z x vulkan_sdk.7z -o$sdk_dir - test -d $sdk_ver_dir + if [ ! -d $sdk_ver_dir ]; then + echo "Vulkan SDK subdirectory not found: $sdk_ver_dir" + exit 7 + fi fi echo "Setting VULKAN_SDK* environment variables..." echo "VULKAN_SDK=$sdk_ver_dir" >> $GITHUB_ENV echo "VULKAN_SDK_VERSION=$sdk_ver" >> $GITHUB_ENV echo "VULKAN_SDK_PLATFORM=$sdk_os" >> $GITHUB_ENV + echo "PATH=$PATH:$sdk_ver_dir/bin" >> $GITHUB_ENV + echo "DYLD_LIBRARY_PATH="$sdk_ver_dir/lib:${DYLD_LIBRARY_PATH:-}" >> $GITHUB_ENV - name: Initialize Externals Cache uses: actions/cache@v3 From e84d82827737a93fc2ba54e947667dfe1b67f9e7 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 13:07:40 +0300 Subject: [PATCH 61/64] Fix VulkanSDK unpack script --- .github/workflows/ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 2d36d145b..e0dd5b326 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -250,7 +250,7 @@ jobs: echo "VULKAN_SDK_VERSION=$sdk_ver" >> $GITHUB_ENV echo "VULKAN_SDK_PLATFORM=$sdk_os" >> $GITHUB_ENV echo "PATH=$PATH:$sdk_ver_dir/bin" >> $GITHUB_ENV - echo "DYLD_LIBRARY_PATH="$sdk_ver_dir/lib:${DYLD_LIBRARY_PATH:-}" >> $GITHUB_ENV + echo "DYLD_LIBRARY_PATH=$sdk_ver_dir/lib:${DYLD_LIBRARY_PATH:-}" >> $GITHUB_ENV - name: Initialize Externals Cache uses: actions/cache@v3 From 71b0c3bd54a9bfcc238b0538a757b4e8a3714cf8 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 13:27:22 +0300 Subject: [PATCH 62/64] Unpack VulkanSDK to tool-cache dir --- .github/workflows/ci-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index e0dd5b326..c7765ebfc 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -218,7 +218,7 @@ jobs: with: domain: ${{ github.repository_owner }} - - name: Install Vulkan SDK + - name: Install Vulkan SDK ${{ env.vulkan_sdk_version }} if: ${{ matrix.install_vulkan_sdk }} run: | runner_os=$(uname -s) @@ -229,7 +229,7 @@ jobs: *) echo "Unknown runner_os: $runner_os" ; exit 7 ; ;; esac sdk_ver="${{ env.vulkan_sdk_version }}" - sdk_dir="Build/Output/ExternalsCache/VulkanSDK" + sdk_dir="${{ runner.tool_cache }}/VulkanSDK" sdk_ver_dir="$sdk_dir/$sdk_ver/$sdk_os_subdir" if [ -d "$sdk_ver_dir" ]; then echo "Vulkan SDK version directory already exists: $sdk_ver_dir" From bb67aaf685d7dcebcedf7300e96b4beda30b70d4 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 14:12:20 +0300 Subject: [PATCH 63/64] Add MacOS_VK_Release test report --- .github/workflows/ci-tests-report.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-tests-report.yml b/.github/workflows/ci-tests-report.yml index 8fb2c0108..cda882b49 100644 --- a/.github/workflows/ci-tests-report.yml +++ b/.github/workflows/ci-tests-report.yml @@ -22,6 +22,7 @@ jobs: - name: "Win32_DX_Release" - name: "Win32_VK_Release" - name: "Ubuntu_VK_Release" + - name: "MacOS_VK_Release" - name: "MacOS_MTL_Release" runs-on: ubuntu-latest From 2627d3b9ec3efb40c9a0d3a7d7237acdf4040ea7 Mon Sep 17 00:00:00 2001 From: Evgeny Gorodetskiy Date: Sun, 6 Aug 2023 14:12:45 +0300 Subject: [PATCH 64/64] Bump Methane Kit version to v0.7.3 --- .github/workflows/ci-build.yml | 2 +- .github/workflows/ci-codeql-scan.yml | 2 ++ .github/workflows/ci-sonar-scan.yml | 2 +- Build/Unix/Build.sh | 2 +- Build/Windows/Build.bat | 2 +- CMakeLists.txt | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index c7765ebfc..586411158 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -31,7 +31,7 @@ on: env: product_ver_major: 0 product_ver_minor: 7 - product_ver_patch: 2 + product_ver_patch: 3 product_ver_build: ${{ github.run_number }} tracy_release_version: "0.9.1" vulkan_sdk_version: "1.3.250.1" diff --git a/.github/workflows/ci-codeql-scan.yml b/.github/workflows/ci-codeql-scan.yml index ab693c584..1d45cb42a 100644 --- a/.github/workflows/ci-codeql-scan.yml +++ b/.github/workflows/ci-codeql-scan.yml @@ -42,10 +42,12 @@ jobs: # name: "Win64_DX_CodeQL-Scan" # config_preset: "VS2022-Win64-DX-Scan" # build_preset: "VS2022-Win64-DX-Scan" + - os: ubuntu-latest name: "Ubuntu_VK_CodeQL-Scan" config_preset: "Make-Lin-VK-Scan" build_preset: "Make-Lin-VK-Scan" + - os: macos-latest name: "MacOS_MTL_CodeQL-Scan" config_preset: "Xcode-Mac-MTL-Scan" diff --git a/.github/workflows/ci-sonar-scan.yml b/.github/workflows/ci-sonar-scan.yml index c47f059cc..9d3dca0e6 100644 --- a/.github/workflows/ci-sonar-scan.yml +++ b/.github/workflows/ci-sonar-scan.yml @@ -38,7 +38,7 @@ on: env: product_ver_major: 0 product_ver_minor: 7 - product_ver_patch: 2 + product_ver_patch: 3 product_ver_build: ${{ github.run_number }} sonar_server_url: "https://sonarcloud.io" sonar_organization: methane-powered diff --git a/Build/Unix/Build.sh b/Build/Unix/Build.sh index 42dbad22c..4bda78275 100755 --- a/Build/Unix/Build.sh +++ b/Build/Unix/Build.sh @@ -10,7 +10,7 @@ BUILD_VERSION_MAJOR=0 BUILD_VERSION_MINOR=7 -BUILD_VERSION_PATCH=2 +BUILD_VERSION_PATCH=3 BUILD_VERSION=$BUILD_VERSION_MAJOR.$BUILD_VERSION_MINOR.$BUILD_VERSION_PATCH SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd ) diff --git a/Build/Windows/Build.bat b/Build/Windows/Build.bat index 5aa769d41..97cc133bd 100644 --- a/Build/Windows/Build.bat +++ b/Build/Windows/Build.bat @@ -10,7 +10,7 @@ SETLOCAL ENABLEDELAYEDEXPANSION SET BUILD_VERSION_MAJOR=0 SET BUILD_VERSION_MINOR=7 -SET BUILD_VERSION_PATCH=2 +SET BUILD_VERSION_PATCH=3 SET BUILD_VERSION=%BUILD_VERSION_MAJOR%.%BUILD_VERSION_MINOR%.%BUILD_VERSION_PATCH% SET OUTPUT_DIR=%~dp0..\Output diff --git a/CMakeLists.txt b/CMakeLists.txt index e657d070d..d69e4659d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.21.0) # Methane version, build & product info set(METHANE_VERSION_MAJOR 0 CACHE STRING "Methane major version") set(METHANE_VERSION_MINOR 7 CACHE STRING "Methane minor version") -set(METHANE_VERSION_PATCH 2 CACHE STRING "Methane patch version") +set(METHANE_VERSION_PATCH 3 CACHE STRING "Methane patch version") set(METHANE_VERSION_BUILD 0 CACHE STRING "Methane build version") # Define CMake languages list