vk_instance: Clean up extension management. (#2342)

This commit is contained in:
squidbus 2025-02-06 16:38:02 -08:00 committed by GitHub
parent 0d498f12b9
commit 1eb0affdea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 80 additions and 133 deletions

View file

@ -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],

View file

@ -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<vk::PhysicalDeviceVulkan11Properties>().subgroupSize;
push_descriptor_props = properties_chain.get<vk::PhysicalDevicePushDescriptorPropertiesKHR>();
vk12_props = properties_chain.get<vk::PhysicalDeviceVulkan12Properties>();
LOG_INFO(Render_Vulkan, "Physical device subgroup size {}", subgroup_size);
const vk::StructureChain feature_chain =
physical_device
.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan12Features,
vk::PhysicalDeviceRobustness2FeaturesEXT,
vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT,
vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT,
vk::PhysicalDevicePortabilitySubsetFeaturesKHR>();
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<vk::PhysicalDeviceVulkan11Properties>();
vk12_props = properties_chain.get<vk::PhysicalDeviceVulkan12Properties>();
push_descriptor_props = properties_chain.get<vk::PhysicalDevicePushDescriptorPropertiesKHR>();
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<vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT>()
.extendedDynamicState3ColorWriteMask;
}
null_descriptor = add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
if (null_descriptor) {
null_descriptor =
feature_chain.get<vk::PhysicalDeviceRobustness2FeaturesEXT>().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<f32, 1> queue_priorities = {1.0f};
static constexpr std::array queue_priorities = {1.0f};
const vk::DeviceQueueCreateInfo queue_info = {
.queueFamilyIndex = queue_family_index,
.queueCount = static_cast<u32>(queue_priorities.size()),
@ -320,7 +316,6 @@ bool Instance::CreateDevice() {
const auto topology_list_restart_features =
feature_chain.get<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>();
const auto vk12_features = feature_chain.get<vk::PhysicalDeviceVulkan12Features>();
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<vk::PhysicalDeviceCustomBorderColorFeaturesEXT>();
}
if (!color_write_en) {
device_chain.unlink<vk::PhysicalDeviceColorWriteEnableFeaturesEXT>();
if (!dynamic_color_write_mask) {
device_chain.unlink<vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT>();
}
if (!depth_clip_control) {
device_chain.unlink<vk::PhysicalDeviceDepthClipControlFeaturesEXT>();
}
if (!workgroup_memory_explicit_layout) {
device_chain.unlink<vk::PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR>();
}
if (!list_restart) {
device_chain.unlink<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>();
}
if (robustness) {
null_descriptor =
feature_chain.get<vk::PhysicalDeviceRobustness2FeaturesEXT>().nullDescriptor;
device_chain.get<vk::PhysicalDeviceRobustness2FeaturesEXT>().nullDescriptor =
null_descriptor;
} else {
null_descriptor = false;
if (!null_descriptor) {
device_chain.unlink<vk::PhysicalDeviceRobustness2FeaturesEXT>();
}
if (!vertex_input_dynamic_state) {
device_chain.unlink<vk::PhysicalDeviceVertexInputDynamicStateFeaturesEXT>();
}
if (!list_restart) {
device_chain.unlink<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>();
}
if (!fragment_shader_barycentric) {
device_chain.unlink<vk::PhysicalDeviceFragmentShaderBarycentricFeaturesKHR>();
}

View file

@ -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<vk::Format, vk::FormatProperties3> 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

View file

@ -1062,14 +1062,8 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) {
const auto cmdbuf = scheduler.CommandBuffer();
cmdbuf.setBlendConstants(&regs.blend_constants.red);
if (instance.IsColorWriteEnableSupported()) {
const auto& write_masks = pipeline.GetWriteMasks();
std::array<vk::Bool32, Liverpool::NumColorBuffers> 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);