From 1eb0affdea69e9ef10aa84b709afd447642940b2 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:38:02 -0800 Subject: [PATCH] vk_instance: Clean up extension management. (#2342) --- .../renderer_vulkan/vk_graphics_pipeline.cpp | 5 +- .../renderer_vulkan/vk_instance.cpp | 155 ++++++++---------- src/video_core/renderer_vulkan/vk_instance.h | 43 +---- .../renderer_vulkan/vk_rasterizer.cpp | 10 +- 4 files changed, 80 insertions(+), 133 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 4ca3a7f27..330a8ab7f 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -131,8 +131,7 @@ GraphicsPipeline::GraphicsPipeline( vk::DynamicState::eStencilOpEXT, }; - if (instance.IsColorWriteEnableSupported()) { - dynamic_states.push_back(vk::DynamicState::eColorWriteEnableEXT); + if (instance.IsDynamicColorWriteMaskSupported()) { dynamic_states.push_back(vk::DynamicState::eColorWriteMaskEXT); } if (instance.IsVertexInputDynamicState()) { @@ -241,7 +240,7 @@ GraphicsPipeline::GraphicsPipeline( ? LiverpoolToVK::BlendOp(control.alpha_func) : color_blend, .colorWriteMask = - instance.IsColorWriteEnableSupported() + instance.IsDynamicColorWriteMaskSupported() ? vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA : key.write_masks[i], diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index a722b5322..52c67d002 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -206,27 +206,23 @@ std::string Instance::GetDriverVersionName() { } bool Instance::CreateDevice() { - const vk::StructureChain feature_chain = physical_device.getFeatures2< - vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT, - vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, - vk::PhysicalDeviceExtendedDynamicState2FeaturesEXT, - vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT, - vk::PhysicalDeviceCustomBorderColorFeaturesEXT, - vk::PhysicalDeviceColorWriteEnableFeaturesEXT, vk::PhysicalDeviceVulkan12Features, - vk::PhysicalDeviceVulkan13Features, - vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, - vk::PhysicalDeviceDepthClipControlFeaturesEXT, vk::PhysicalDeviceRobustness2FeaturesEXT, - vk::PhysicalDevicePortabilitySubsetFeaturesKHR>(); - const vk::StructureChain properties_chain = physical_device.getProperties2< - vk::PhysicalDeviceProperties2, vk::PhysicalDevicePortabilitySubsetPropertiesKHR, - vk::PhysicalDeviceExternalMemoryHostPropertiesEXT, vk::PhysicalDeviceVulkan11Properties, - vk::PhysicalDevicePushDescriptorPropertiesKHR, vk::PhysicalDeviceVulkan12Properties>(); - subgroup_size = properties_chain.get().subgroupSize; - push_descriptor_props = properties_chain.get(); - vk12_props = properties_chain.get(); - LOG_INFO(Render_Vulkan, "Physical device subgroup size {}", subgroup_size); - + const vk::StructureChain feature_chain = + physical_device + .getFeatures2(); features = feature_chain.get().features; + + const vk::StructureChain properties_chain = physical_device.getProperties2< + vk::PhysicalDeviceProperties2, vk::PhysicalDeviceVulkan11Properties, + vk::PhysicalDeviceVulkan12Properties, vk::PhysicalDevicePushDescriptorPropertiesKHR>(); + vk11_props = properties_chain.get(); + vk12_props = properties_chain.get(); + push_descriptor_props = properties_chain.get(); + LOG_INFO(Render_Vulkan, "Physical device subgroup size {}", vk11_props.subgroupSize); + if (available_extensions.empty()) { LOG_CRITICAL(Render_Vulkan, "No extensions supported by device."); return false; @@ -248,42 +244,43 @@ bool Instance::CreateDevice() { return false; }; - add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - shader_stencil_export = add_extension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); - external_memory_host = add_extension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME); - custom_border_color = add_extension(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); - add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); - depth_clip_control = add_extension(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); - add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); - workgroup_memory_explicit_layout = - add_extension(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); - vertex_input_dynamic_state = add_extension(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); - fragment_shader_barycentric = add_extension(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME); - - // The next two extensions are required to be available together in order to support write masks - color_write_en = add_extension(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME); - color_write_en &= add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); - const bool calibrated_timestamps = - TRACY_GPU_ENABLED ? add_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME) : false; - const bool robustness = add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME); - list_restart = add_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME); - maintenance5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); - legacy_vertex_attributes = add_extension(VK_EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME); - image_load_store_lod = add_extension(VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME); - amd_gcn_shader = add_extension(VK_AMD_GCN_SHADER_EXTENSION_NAME); - // These extensions are promoted by Vulkan 1.3, but for greater compatibility we use Vulkan 1.2 // with extensions. - if (Config::vkValidationEnabled() || Config::isRdocEnabled()) { - tooling_info = add_extension(VK_EXT_TOOLING_INFO_EXTENSION_NAME); - } - const bool maintenance4 = add_extension(VK_KHR_MAINTENANCE_4_EXTENSION_NAME); add_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME); add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); add_extension(VK_EXT_4444_FORMATS_EXTENSION_NAME); + tooling_info = add_extension(VK_EXT_TOOLING_INFO_EXTENSION_NAME); + const bool maintenance4 = add_extension(VK_KHR_MAINTENANCE_4_EXTENSION_NAME); + + add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); + dynamic_color_write_mask = add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + if (dynamic_color_write_mask) { + dynamic_color_write_mask = + feature_chain.get() + .extendedDynamicState3ColorWriteMask; + } + null_descriptor = add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME); + if (null_descriptor) { + null_descriptor = + feature_chain.get().nullDescriptor; + } + maintenance5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); + custom_border_color = add_extension(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + depth_clip_control = add_extension(VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); + vertex_input_dynamic_state = add_extension(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + list_restart = add_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME); + fragment_shader_barycentric = add_extension(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME); + legacy_vertex_attributes = add_extension(VK_EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME); + shader_stencil_export = add_extension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); + image_load_store_lod = add_extension(VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME); + amd_gcn_shader = add_extension(VK_AMD_GCN_SHADER_EXTENSION_NAME); + const bool calibrated_timestamps = + TRACY_GPU_ENABLED ? add_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME) : false; #ifdef __APPLE__ // Required by Vulkan spec if supported. @@ -310,8 +307,7 @@ bool Instance::CreateDevice() { return false; } - static constexpr std::array queue_priorities = {1.0f}; - + static constexpr std::array queue_priorities = {1.0f}; const vk::DeviceQueueCreateInfo queue_info = { .queueFamilyIndex = queue_family_index, .queueCount = static_cast(queue_priorities.size()), @@ -320,7 +316,6 @@ bool Instance::CreateDevice() { const auto topology_list_restart_features = feature_chain.get(); - const auto vk12_features = feature_chain.get(); vk::StructureChain device_chain = { vk::DeviceCreateInfo{ @@ -365,46 +360,42 @@ bool Instance::CreateDevice() { .hostQueryReset = vk12_features.hostQueryReset, .timelineSemaphore = vk12_features.timelineSemaphore, }, - vk::PhysicalDeviceMaintenance4FeaturesKHR{ - .maintenance4 = true, - }, - vk::PhysicalDeviceMaintenance5FeaturesKHR{ - .maintenance5 = true, - }, + // Vulkan 1.3 promoted extensions vk::PhysicalDeviceDynamicRenderingFeaturesKHR{ .dynamicRendering = true, }, vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT{ .shaderDemoteToHelperInvocation = true, }, - vk::PhysicalDeviceCustomBorderColorFeaturesEXT{ - .customBorderColors = true, - .customBorderColorWithoutFormat = true, - }, - vk::PhysicalDeviceColorWriteEnableFeaturesEXT{ - .colorWriteEnable = true, + vk::PhysicalDeviceSynchronization2Features{ + .synchronization2 = true, }, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT{ .extendedDynamicState = true, }, + vk::PhysicalDevice4444FormatsFeaturesEXT{ + .formatA4B4G4R4 = true, + }, + vk::PhysicalDeviceMaintenance4FeaturesKHR{ + .maintenance4 = true, + }, + // Other extensions + vk::PhysicalDeviceMaintenance5FeaturesKHR{ + .maintenance5 = true, + }, + vk::PhysicalDeviceCustomBorderColorFeaturesEXT{ + .customBorderColors = true, + .customBorderColorWithoutFormat = true, + }, vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT{ .extendedDynamicState3ColorWriteMask = true, }, vk::PhysicalDeviceDepthClipControlFeaturesEXT{ .depthClipControl = true, }, - vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR{ - .workgroupMemoryExplicitLayout = true, - .workgroupMemoryExplicitLayoutScalarBlockLayout = true, - .workgroupMemoryExplicitLayout8BitAccess = true, - .workgroupMemoryExplicitLayout16BitAccess = true, - }, vk::PhysicalDeviceRobustness2FeaturesEXT{ .nullDescriptor = true, }, - vk::PhysicalDeviceSynchronization2Features{ - .synchronization2 = true, - }, vk::PhysicalDeviceVertexInputDynamicStateFeaturesEXT{ .vertexInputDynamicState = true, }, @@ -433,31 +424,21 @@ bool Instance::CreateDevice() { if (!custom_border_color) { device_chain.unlink(); } - if (!color_write_en) { - device_chain.unlink(); + if (!dynamic_color_write_mask) { device_chain.unlink(); } if (!depth_clip_control) { device_chain.unlink(); } - if (!workgroup_memory_explicit_layout) { - device_chain.unlink(); - } - if (!list_restart) { - device_chain.unlink(); - } - if (robustness) { - null_descriptor = - feature_chain.get().nullDescriptor; - device_chain.get().nullDescriptor = - null_descriptor; - } else { - null_descriptor = false; + if (!null_descriptor) { device_chain.unlink(); } if (!vertex_input_dynamic_state) { device_chain.unlink(); } + if (!list_restart) { + device_chain.unlink(); + } if (!fragment_shader_barycentric) { device_chain.unlink(); } diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 8c4752c3f..532696f0f 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -89,34 +89,19 @@ public: return custom_border_color; } - /// Returns true when VK_EXT_fragment_shader_interlock is supported - bool IsFragmentShaderInterlockSupported() const { - return fragment_shader_interlock; - } - - /// Returns true when VK_EXT_pipeline_creation_cache_control is supported - bool IsPipelineCreationCacheControlSupported() const { - return pipeline_creation_cache_control; - } - /// Returns true when VK_EXT_shader_stencil_export is supported bool IsShaderStencilExportSupported() const { return shader_stencil_export; } - /// Returns true when VK_EXT_external_memory_host is supported - bool IsExternalMemoryHostSupported() const { - return external_memory_host; - } - /// Returns true when VK_EXT_depth_clip_control is supported bool IsDepthClipControlSupported() const { return depth_clip_control; } - /// Returns true when VK_EXT_color_write_enable is supported - bool IsColorWriteEnableSupported() const { - return color_write_en; + /// Returns true when dynamic color write mask state is supported + bool IsDynamicColorWriteMaskSupported() const { + return dynamic_color_write_mask; } /// Returns true when VK_EXT_vertex_input_dynamic_state is supported. @@ -236,7 +221,7 @@ public: /// Returns the subgroup size of the selected physical device. u32 SubgroupSize() const { - return subgroup_size; + return vk11_props.subgroupSize; } /// Returns the maximum size of compute shared memory. @@ -274,11 +259,6 @@ public: return features.shaderClipDistance; } - /// Returns the minimum imported host pointer alignment - u64 GetMinImportedHostPointerAlignment() const { - return min_imported_host_pointer_alignment; - } - u32 GetMaxViewportWidth() const { return properties.limits.maxViewportDimensions[0]; } @@ -316,8 +296,9 @@ private: vk::PhysicalDevice physical_device; vk::UniqueDevice device; vk::PhysicalDeviceProperties properties; - vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props; + vk::PhysicalDeviceVulkan11Properties vk11_props; vk::PhysicalDeviceVulkan12Properties vk12_props; + vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props; vk::PhysicalDeviceFeatures features; vk::DriverIdKHR driver_id; vk::UniqueDebugUtilsMessengerEXT debug_callback{}; @@ -330,27 +311,19 @@ private: std::unordered_map format_properties; TracyVkCtx profiler_context{}; u32 queue_family_index{0}; - bool image_view_reinterpretation{true}; - bool timeline_semaphores{}; bool custom_border_color{}; - bool fragment_shader_interlock{}; - bool pipeline_creation_cache_control{}; bool fragment_shader_barycentric{}; - bool shader_stencil_export{}; - bool external_memory_host{}; bool depth_clip_control{}; - bool workgroup_memory_explicit_layout{}; - bool color_write_en{}; + bool dynamic_color_write_mask{}; bool vertex_input_dynamic_state{}; bool null_descriptor{}; bool maintenance5{}; bool list_restart{}; bool legacy_vertex_attributes{}; + bool shader_stencil_export{}; bool image_load_store_lod{}; bool amd_gcn_shader{}; bool tooling_info{}; - u64 min_imported_host_pointer_alignment{}; - u32 subgroup_size{}; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 7f2db3f8d..8da27de00 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1062,14 +1062,8 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) { const auto cmdbuf = scheduler.CommandBuffer(); cmdbuf.setBlendConstants(®s.blend_constants.red); - if (instance.IsColorWriteEnableSupported()) { - const auto& write_masks = pipeline.GetWriteMasks(); - std::array write_ens{}; - std::transform(write_masks.cbegin(), write_masks.cend(), write_ens.begin(), - [](auto in) { return in ? vk::True : vk::False; }); - - cmdbuf.setColorWriteEnableEXT(write_ens); - cmdbuf.setColorWriteMaskEXT(0, write_masks); + if (instance.IsDynamicColorWriteMaskSupported()) { + cmdbuf.setColorWriteMaskEXT(0, pipeline.GetWriteMasks()); } if (regs.depth_control.depth_bounds_enable) { cmdbuf.setDepthBounds(regs.depth_bounds_min, regs.depth_bounds_max);