diff options
| author | 2021-07-27 19:15:32 -0300 | |
|---|---|---|
| committer | 2021-07-27 21:29:24 -0300 | |
| commit | 3b006f4fe28006d320c60fd2b4393fd3f27eacd7 (patch) | |
| tree | e8704a3796e766a764e2643a2621451a8fe4ea49 /src/video_core/vulkan_common | |
| parent | Merge pull request #6748 from lioncash/engine-init (diff) | |
| download | yuzu-3b006f4fe28006d320c60fd2b4393fd3f27eacd7.tar.gz yuzu-3b006f4fe28006d320c60fd2b4393fd3f27eacd7.tar.xz yuzu-3b006f4fe28006d320c60fd2b4393fd3f27eacd7.zip | |
renderer_vulkan: Add setting to log pipeline statistics
Use VK_KHR_pipeline_executable_properties when enabled and available to
log statistics about the pipeline cache in a game.
For example, this is on Turing GPUs when generating a pipeline cache
from Super Smash Bros. Ultimate:
Average pipeline statistics
==========================================
Code size: 6433.167
Register count: 32.939
More advanced results could be presented, at the moment it's just an
average of all 3D and compute pipelines.
Diffstat (limited to 'src/video_core/vulkan_common')
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 6 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 38 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 8 |
4 files changed, 81 insertions, 0 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 44afdc1cd..8e56a89e1 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -526,6 +526,17 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 526 | SetNext(next, workgroup_layout); | 526 | SetNext(next, workgroup_layout); |
| 527 | } | 527 | } |
| 528 | 528 | ||
| 529 | VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR executable_properties; | ||
| 530 | if (khr_pipeline_executable_properties) { | ||
| 531 | LOG_INFO(Render_Vulkan, "Enabling shader feedback, expect slower shader build times"); | ||
| 532 | executable_properties = { | ||
| 533 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, | ||
| 534 | .pNext = nullptr, | ||
| 535 | .pipelineExecutableInfo = VK_TRUE, | ||
| 536 | }; | ||
| 537 | SetNext(next, executable_properties); | ||
| 538 | } | ||
| 539 | |||
| 529 | if (!ext_depth_range_unrestricted) { | 540 | if (!ext_depth_range_unrestricted) { |
| 530 | LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted"); | 541 | LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted"); |
| 531 | } | 542 | } |
| @@ -824,6 +835,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 824 | 835 | ||
| 825 | bool has_khr_shader_float16_int8{}; | 836 | bool has_khr_shader_float16_int8{}; |
| 826 | bool has_khr_workgroup_memory_explicit_layout{}; | 837 | bool has_khr_workgroup_memory_explicit_layout{}; |
| 838 | bool has_khr_pipeline_executable_properties{}; | ||
| 827 | bool has_ext_subgroup_size_control{}; | 839 | bool has_ext_subgroup_size_control{}; |
| 828 | bool has_ext_transform_feedback{}; | 840 | bool has_ext_transform_feedback{}; |
| 829 | bool has_ext_custom_border_color{}; | 841 | bool has_ext_custom_border_color{}; |
| @@ -878,6 +890,10 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 878 | test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, | 890 | test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, |
| 879 | true); | 891 | true); |
| 880 | } | 892 | } |
| 893 | if (Settings::values.renderer_shader_feedback) { | ||
| 894 | test(has_khr_pipeline_executable_properties, | ||
| 895 | VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME, false); | ||
| 896 | } | ||
| 881 | } | 897 | } |
| 882 | VkPhysicalDeviceFeatures2KHR features{}; | 898 | VkPhysicalDeviceFeatures2KHR features{}; |
| 883 | features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; | 899 | features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; |
| @@ -1033,6 +1049,19 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1033 | khr_workgroup_memory_explicit_layout = true; | 1049 | khr_workgroup_memory_explicit_layout = true; |
| 1034 | } | 1050 | } |
| 1035 | } | 1051 | } |
| 1052 | if (has_khr_pipeline_executable_properties) { | ||
| 1053 | VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR executable_properties; | ||
| 1054 | executable_properties.sType = | ||
| 1055 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR; | ||
| 1056 | executable_properties.pNext = nullptr; | ||
| 1057 | features.pNext = &executable_properties; | ||
| 1058 | physical.GetFeatures2KHR(features); | ||
| 1059 | |||
| 1060 | if (executable_properties.pipelineExecutableInfo) { | ||
| 1061 | extensions.push_back(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); | ||
| 1062 | khr_pipeline_executable_properties = true; | ||
| 1063 | } | ||
| 1064 | } | ||
| 1036 | if (khr_push_descriptor) { | 1065 | if (khr_push_descriptor) { |
| 1037 | VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor; | 1066 | VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor; |
| 1038 | push_descriptor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR; | 1067 | push_descriptor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR; |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index df394e384..c19f40746 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -214,6 +214,11 @@ public: | |||
| 214 | return khr_push_descriptor; | 214 | return khr_push_descriptor; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | /// Returns true if VK_KHR_pipeline_executable_properties is enabled. | ||
| 218 | bool IsKhrPipelineEexecutablePropertiesEnabled() const { | ||
| 219 | return khr_pipeline_executable_properties; | ||
| 220 | } | ||
| 221 | |||
| 217 | /// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout. | 222 | /// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout. |
| 218 | bool IsKhrWorkgroupMemoryExplicitLayoutSupported() const { | 223 | bool IsKhrWorkgroupMemoryExplicitLayoutSupported() const { |
| 219 | return khr_workgroup_memory_explicit_layout; | 224 | return khr_workgroup_memory_explicit_layout; |
| @@ -378,6 +383,7 @@ private: | |||
| 378 | bool khr_spirv_1_4{}; ///< Support for VK_KHR_spirv_1_4. | 383 | bool khr_spirv_1_4{}; ///< Support for VK_KHR_spirv_1_4. |
| 379 | bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts. | 384 | bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts. |
| 380 | bool khr_push_descriptor{}; ///< Support for VK_KHR_push_descritor. | 385 | bool khr_push_descriptor{}; ///< Support for VK_KHR_push_descritor. |
| 386 | bool khr_pipeline_executable_properties{}; ///< Support for executable properties. | ||
| 381 | bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. | 387 | bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. |
| 382 | bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. | 388 | bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. |
| 383 | bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. | 389 | bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 70898004a..a9faa4807 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -181,6 +181,8 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 181 | X(vkGetMemoryWin32HandleKHR); | 181 | X(vkGetMemoryWin32HandleKHR); |
| 182 | #endif | 182 | #endif |
| 183 | X(vkGetQueryPoolResults); | 183 | X(vkGetQueryPoolResults); |
| 184 | X(vkGetPipelineExecutablePropertiesKHR); | ||
| 185 | X(vkGetPipelineExecutableStatisticsKHR); | ||
| 184 | X(vkGetSemaphoreCounterValueKHR); | 186 | X(vkGetSemaphoreCounterValueKHR); |
| 185 | X(vkMapMemory); | 187 | X(vkMapMemory); |
| 186 | X(vkQueueSubmit); | 188 | X(vkQueueSubmit); |
| @@ -809,6 +811,42 @@ VkMemoryRequirements Device::GetImageMemoryRequirements(VkImage image) const noe | |||
| 809 | return requirements; | 811 | return requirements; |
| 810 | } | 812 | } |
| 811 | 813 | ||
| 814 | std::vector<VkPipelineExecutablePropertiesKHR> Device::GetPipelineExecutablePropertiesKHR( | ||
| 815 | VkPipeline pipeline) const { | ||
| 816 | const VkPipelineInfoKHR info{ | ||
| 817 | .sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, | ||
| 818 | .pNext = nullptr, | ||
| 819 | .pipeline = pipeline, | ||
| 820 | }; | ||
| 821 | u32 num{}; | ||
| 822 | dld->vkGetPipelineExecutablePropertiesKHR(handle, &info, &num, nullptr); | ||
| 823 | std::vector<VkPipelineExecutablePropertiesKHR> properties(num); | ||
| 824 | for (auto& property : properties) { | ||
| 825 | property.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR; | ||
| 826 | } | ||
| 827 | Check(dld->vkGetPipelineExecutablePropertiesKHR(handle, &info, &num, properties.data())); | ||
| 828 | return properties; | ||
| 829 | } | ||
| 830 | |||
| 831 | std::vector<VkPipelineExecutableStatisticKHR> Device::GetPipelineExecutableStatisticsKHR( | ||
| 832 | VkPipeline pipeline, u32 executable_index) const { | ||
| 833 | const VkPipelineExecutableInfoKHR executable_info{ | ||
| 834 | .sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, | ||
| 835 | .pNext = nullptr, | ||
| 836 | .pipeline = pipeline, | ||
| 837 | .executableIndex = executable_index, | ||
| 838 | }; | ||
| 839 | u32 num{}; | ||
| 840 | dld->vkGetPipelineExecutableStatisticsKHR(handle, &executable_info, &num, nullptr); | ||
| 841 | std::vector<VkPipelineExecutableStatisticKHR> statistics(num); | ||
| 842 | for (auto& statistic : statistics) { | ||
| 843 | statistic.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR; | ||
| 844 | } | ||
| 845 | Check(dld->vkGetPipelineExecutableStatisticsKHR(handle, &executable_info, &num, | ||
| 846 | statistics.data())); | ||
| 847 | return statistics; | ||
| 848 | } | ||
| 849 | |||
| 812 | void Device::UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes, | 850 | void Device::UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes, |
| 813 | Span<VkCopyDescriptorSet> copies) const noexcept { | 851 | Span<VkCopyDescriptorSet> copies) const noexcept { |
| 814 | dld->vkUpdateDescriptorSets(handle, writes.size(), writes.data(), copies.size(), copies.data()); | 852 | dld->vkUpdateDescriptorSets(handle, writes.size(), writes.data(), copies.size(), copies.data()); |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index d76bb4324..b7ae01c6c 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -295,6 +295,8 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 295 | #ifdef _WIN32 | 295 | #ifdef _WIN32 |
| 296 | PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR{}; | 296 | PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR{}; |
| 297 | #endif | 297 | #endif |
| 298 | PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR{}; | ||
| 299 | PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR{}; | ||
| 298 | PFN_vkGetQueryPoolResults vkGetQueryPoolResults{}; | 300 | PFN_vkGetQueryPoolResults vkGetQueryPoolResults{}; |
| 299 | PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR{}; | 301 | PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR{}; |
| 300 | PFN_vkMapMemory vkMapMemory{}; | 302 | PFN_vkMapMemory vkMapMemory{}; |
| @@ -879,6 +881,12 @@ public: | |||
| 879 | 881 | ||
| 880 | VkMemoryRequirements GetImageMemoryRequirements(VkImage image) const noexcept; | 882 | VkMemoryRequirements GetImageMemoryRequirements(VkImage image) const noexcept; |
| 881 | 883 | ||
| 884 | std::vector<VkPipelineExecutablePropertiesKHR> GetPipelineExecutablePropertiesKHR( | ||
| 885 | VkPipeline pipeline) const; | ||
| 886 | |||
| 887 | std::vector<VkPipelineExecutableStatisticKHR> GetPipelineExecutableStatisticsKHR( | ||
| 888 | VkPipeline pipeline, u32 executable_index) const; | ||
| 889 | |||
| 882 | void UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes, | 890 | void UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes, |
| 883 | Span<VkCopyDescriptorSet> copies) const noexcept; | 891 | Span<VkCopyDescriptorSet> copies) const noexcept; |
| 884 | 892 | ||