diff --git a/compiler/compiler.cpp b/compiler/compiler.cpp index 3df673f49..10470a37e 100644 --- a/compiler/compiler.cpp +++ b/compiler/compiler.cpp @@ -332,9 +332,9 @@ std::vector GLSLCompiler::compile(std::string &error_message, const st } options.SetTargetEnvironment(shaderc_target_env_vulkan, - target == Target::Vulkan11_Spirv14 ? - shaderc_env_version_vulkan_1_2 : shaderc_env_version_vulkan_1_1); - options.SetTargetSpirv(target == Target::Vulkan11_Spirv14 ? shaderc_spirv_version_1_4 : shaderc_spirv_version_1_3); + target == Target::Vulkan13 ? + shaderc_env_version_vulkan_1_3 : shaderc_env_version_vulkan_1_1); + options.SetTargetSpirv(target == Target::Vulkan13 ? shaderc_spirv_version_1_6 : shaderc_spirv_version_1_3); options.SetSourceLanguage(shaderc_source_language_glsl); shaderc::SpvCompilationResult result; @@ -370,7 +370,7 @@ std::vector GLSLCompiler::compile(std::string &error_message, const st } std::vector compiled_spirv(result.cbegin(), result.cend()); - spvtools::SpirvTools core(target == Target::Vulkan11_Spirv14 ? SPV_ENV_VULKAN_1_1_SPIRV_1_4 : SPV_ENV_VULKAN_1_1); + spvtools::SpirvTools core(target == Target::Vulkan13 ? SPV_ENV_VULKAN_1_3 : SPV_ENV_VULKAN_1_1); core.SetMessageConsumer([&error_message](spv_message_level_t, const char *, const spv_position_t&, const char *message) { error_message = message; }); diff --git a/compiler/compiler.hpp b/compiler/compiler.hpp index 7b8425f7c..807c3a8cc 100644 --- a/compiler/compiler.hpp +++ b/compiler/compiler.hpp @@ -48,7 +48,7 @@ enum class Stage enum class Target { Vulkan11, - Vulkan11_Spirv14 + Vulkan13 }; class GLSLCompiler diff --git a/renderer/animation_system.cpp b/renderer/animation_system.cpp index fecc7e507..9ed18a3a6 100644 --- a/renderer/animation_system.cpp +++ b/renderer/animation_system.cpp @@ -486,13 +486,13 @@ void AnimationSystem::update(AnimationState *anim, double frame_time, double ela { auto *node = anim->skinned_node; anim->animation.animate(anim->transforms_base, - node->get_skin()->skin.data(), node->get_skin()->skin.size(), float(offset)); + node->get_skin()->skin.data(), node->get_skin()->skin.size(), float(offset)); node->invalidate_cached_transform(); } else { anim->animation.animate(anim->transforms_base, - anim->channel_transforms.data(), anim->channel_transforms.size(), float(offset)); + anim->channel_transforms.data(), anim->channel_transforms.size(), float(offset)); for (auto *node : anim->channel_nodes) node->invalidate_cached_transform(); } @@ -553,7 +553,7 @@ void AnimationSystem::animate(TaskComposer &composer, double frame_time, double } AnimationSystem::AnimationState::AnimationState(const AnimationUnrolled &anim, - Transform *transforms_base_, + Transform *transforms_base_, Util::SmallVector channel_transforms_, Util::SmallVector channel_nodes_, double start_time_) diff --git a/renderer/animation_system.hpp b/renderer/animation_system.hpp index 92a31fab5..b5641725c 100644 --- a/renderer/animation_system.hpp +++ b/renderer/animation_system.hpp @@ -105,7 +105,7 @@ class AnimationSystem struct AnimationState : Util::IntrusiveUnorderedArrayEnabled { AnimationState(const AnimationUnrolled &anim, - Transform *transforms_base_, + Transform *transforms_base_, Util::SmallVector channel_transforms_, Util::SmallVector channel_nodes_, double start_time_); diff --git a/renderer/fft/fft.cpp b/renderer/fft/fft.cpp index 285a577ee..82d2b9699 100644 --- a/renderer/fft/fft.cpp +++ b/renderer/fft/fft.cpp @@ -200,7 +200,7 @@ void FFT::Impl::optimize_multi_fft(unsigned &multi_fft_x, unsigned &multi_fft_y, unsigned split = split_first + split_second + split_third; unsigned subgroup_size_log2 = - Util::floor_log2(std::max(1u, device->get_device_features().subgroup_properties.subgroupSize)); + Util::floor_log2(std::max(1u, device->get_device_features().vk11_props.subgroupSize)); if (!subgroup_size_log2) subgroup_size_log2 = 5; @@ -231,7 +231,7 @@ void FFT::Impl::optimize_multi_fft(unsigned &multi_fft_x, unsigned &multi_fft_y, void FFT::Impl::optimize_multi_fft_resolve(unsigned &multi_fft_x, unsigned &multi_fft_y) const { unsigned subgroup_size_log2 = - Util::floor_log2(std::max(1u, device->get_device_features().subgroup_properties.subgroupSize)); + Util::floor_log2(std::max(1u, device->get_device_features().vk11_props.subgroupSize)); if (!subgroup_size_log2) subgroup_size_log2 = 5; @@ -254,8 +254,8 @@ void FFT::Impl::optimize_multi_fft_resolve(unsigned &multi_fft_x, unsigned &mult const char *FFT::Impl::get_fp16_define() const { - if (device->get_device_features().float16_int8_features.shaderFloat16 && - device->get_device_features().storage_16bit_features.storageBuffer16BitAccess) + if (device->get_device_features().vk12_features.shaderFloat16 && + device->get_device_features().vk11_features.storageBuffer16BitAccess) { return "FFT_FULL_FP16"; } diff --git a/renderer/lights/clusterer.cpp b/renderer/lights/clusterer.cpp index c0854ecd2..265753d98 100644 --- a/renderer/lights/clusterer.cpp +++ b/renderer/lights/clusterer.cpp @@ -1661,7 +1661,7 @@ void LightClusterer::update_bindless_range_buffer_gpu(Vulkan::CommandBuffer &cmd constexpr VkSubgroupFeatureFlags required = VK_SUBGROUP_FEATURE_SHUFFLE_BIT | VK_SUBGROUP_FEATURE_BASIC_BIT; - if ((features.subgroup_properties.supportedOperations & required) == required && + if ((features.vk11_props.subgroupSupportedOperations & required) == required && cmd.get_device().supports_subgroup_size_log2(true, 5, 7)) { cmd.set_program("builtin://shaders/lights/clusterer_bindless_z_range_opt.comp"); @@ -1780,8 +1780,8 @@ void LightClusterer::update_bindless_mask_buffer_decal_gpu(Vulkan::CommandBuffer constexpr VkSubgroupFeatureFlags required = VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT; - if ((features.subgroup_properties.supportedOperations & required) == required && - (features.subgroup_properties.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0) + if ((features.vk11_props.subgroupSupportedOperations & required) == required && + (features.vk11_props.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0) { // Our desired range is either 32 threads or 64 threads, 32 threads is preferred. @@ -1881,8 +1881,8 @@ void LightClusterer::update_bindless_mask_buffer_gpu(Vulkan::CommandBuffer &cmd) constexpr VkSubgroupFeatureFlags required = VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_BASIC_BIT; - if ((features.subgroup_properties.supportedOperations & required) == required && - (features.subgroup_properties.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0) + if ((features.vk11_props.subgroupSupportedOperations & required) == required && + (features.vk11_props.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0) { // Our desired range is either 32 threads or 64 threads, 32 threads is preferred. diff --git a/renderer/post/aa.cpp b/renderer/post/aa.cpp index 3bfb58d7c..9f406f8dc 100644 --- a/renderer/post/aa.cpp +++ b/renderer/post/aa.cpp @@ -114,7 +114,7 @@ bool setup_after_post_chain_upscaling(RenderGraph &graph, const std::string &inp const char *vert = "builtin://shaders/post/ffx-fsr/upscale.vert"; const char *frag = "builtin://shaders/post/ffx-fsr/upscale.frag"; - bool fp16 = cmd.get_device().get_device_features().float16_int8_features.shaderFloat16; + bool fp16 = cmd.get_device().get_device_features().vk12_features.shaderFloat16; const char *fsr_fp16 = getenv("FIDELITYFX_FSR_FP16"); if (fsr_fp16) { diff --git a/renderer/post/spd.cpp b/renderer/post/spd.cpp index 7d2ba341a..e5d454712 100644 --- a/renderer/post/spd.cpp +++ b/renderer/post/spd.cpp @@ -34,22 +34,22 @@ bool supports_single_pass_downsample(Vulkan::Device &device, VkFormat format) bool supports_full_group = device.supports_subgroup_size_log2(true, 2, 7); - bool supports_compute = (features.subgroup_properties.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0; + bool supports_compute = (features.vk11_props.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) != 0; if (device.get_gpu_properties().limits.maxComputeWorkGroupSize[0] < 256) return false; if (!features.enabled_features.shaderStorageImageArrayDynamicIndexing) return false; - VkFormatProperties3KHR props3 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR }; + VkFormatProperties3 props3 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 }; device.get_format_properties(format, &props3); - if ((props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR) == 0) + if ((props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT) == 0) return false; - if ((props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) == 0) + if ((props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT) == 0) return false; constexpr VkSubgroupFeatureFlags required = VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_QUAD_BIT; - bool supports_quad_basic = (features.subgroup_properties.supportedOperations & required) == required; + bool supports_quad_basic = (features.vk11_props.subgroupSupportedOperations & required) == required; return supports_full_group && supports_compute && supports_quad_basic; } diff --git a/renderer/post/ssr.cpp b/renderer/post/ssr.cpp index 302459554..ee15af3b6 100644 --- a/renderer/post/ssr.cpp +++ b/renderer/post/ssr.cpp @@ -126,11 +126,11 @@ struct SSRState : RenderPassInterface VK_ACCESS_2_SHADER_SAMPLED_READ_BIT | VK_ACCESS_2_SHADER_STORAGE_READ_BIT); - VkFormatProperties3KHR props3 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR }; + VkFormatProperties3 props3 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 }; cmd.get_device().get_format_properties(output_view->get_format(), &props3); - if (!(props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR)) + if (!(props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT)) LOGW("Cannot read without format.\n"); - if (!(props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR)) + if (!(props3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT)) LOGW("Cannot write without format.\n"); defines.clear(); diff --git a/renderer/render_graph.cpp b/renderer/render_graph.cpp index a137635c9..4c45f17b2 100644 --- a/renderer/render_graph.cpp +++ b/renderer/render_graph.cpp @@ -2181,7 +2181,7 @@ void RenderGraph::physical_pass_enqueue_graphics_commands(const PhysicalPass &ph } else if (multiview_count) { - if (device->get_device_features().multiview_features.multiview) + if (device->get_device_features().vk11_features.multiview) { rp_info.num_layers = physical_pass.layers; rp_info.base_layer = 0; diff --git a/renderer/renderer.cpp b/renderer/renderer.cpp index cabdfaca2..d2705bdfb 100644 --- a/renderer/renderer.cpp +++ b/renderer/renderer.cpp @@ -299,11 +299,11 @@ static const char *renderer_to_define(RendererType type) void Renderer::add_subgroup_defines(Vulkan::Device &device, std::vector> &defines, VkShaderStageFlagBits stage) { - auto &subgroup = device.get_device_features().subgroup_properties; + auto &vk11 = device.get_device_features().vk11_props; - if ((subgroup.supportedStages & stage) != 0 && + if ((vk11.subgroupSupportedStages & stage) != 0 && !ImplementationQuirks::get().force_no_subgroups && - subgroup.subgroupSize >= 4) + vk11.subgroupSize >= 4) { const VkSubgroupFeatureFlags quad_required = (stage & (VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT)) != 0 ? @@ -316,11 +316,11 @@ void Renderer::add_subgroup_defines(Vulkan::Device &device, std::vectorget_device_features().demote_to_helper_invocation_features.shaderDemoteToHelperInvocation) + if (device->get_device_features().vk13_features.shaderDemoteToHelperInvocation) global_defines.emplace_back("DEMOTE", 1); add_subgroup_defines(*device, global_defines, VK_SHADER_STAGE_FRAGMENT_BIT); } @@ -872,14 +872,14 @@ void DeferredLightRenderer::render_light(Vulkan::CommandBuffer &cmd, const Rende "builtin://shaders/lights/directional.frag"); auto &light = *context.get_lighting_parameters(); - auto &subgroup = device.get_device_features().subgroup_properties; + auto &vk11 = device.get_device_features().vk11_props; std::vector> defines; if (light.shadows && light.shadows->get_create_info().layers > 1) { defines.emplace_back("SHADOW_CASCADES", 1); - if ((subgroup.supportedOperations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) != 0 && - (subgroup.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) != 0 && + if ((vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) != 0 && + (vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) != 0 && !ImplementationQuirks::get().force_no_subgroups) { // For cascaded shadows. diff --git a/slangmosh/slangmosh.cpp b/slangmosh/slangmosh.cpp index 1cfc81ea8..42276d03a 100644 --- a/slangmosh/slangmosh.cpp +++ b/slangmosh/slangmosh.cpp @@ -44,7 +44,7 @@ using namespace Granite; static void print_help() { - LOGE("slangmosh [-O] [--strip] [--spv14] [--output header.hpp] [--help] [--output-interface interface.hpp]\n"); + LOGE("slangmosh [-O] [--strip] [--vk13] [--output header.hpp] [--help] [--output-interface interface.hpp]\n"); } struct ShaderVariant @@ -675,7 +675,7 @@ static int main_inner(int argc, char **argv) cbs.add("--output", [&](CLIParser &parser) { output_path = parser.next_string(); }); cbs.add("-O", [&](CLIParser &) { opt = true; }); cbs.add("--strip", [&](CLIParser &) { strip = true; }); - cbs.add("--spv14", [&](CLIParser &) { target = Target::Vulkan11_Spirv14; }); + cbs.add("--vk13", [&](CLIParser &) { target = Target::Vulkan13; }); cbs.add("--namespace", [&](CLIParser &parser) { generated_namespace = parser.next_string(); }); cbs.add("--output-interface", [&](CLIParser &parser) { output_interface_path = parser.next_string(); }); cbs.default_handler = [&](const char *str) { input_path = str; }; diff --git a/tests/d3d11_interop_test.cpp b/tests/d3d11_interop_test.cpp index def4f46b4..793f56a6f 100644 --- a/tests/d3d11_interop_test.cpp +++ b/tests/d3d11_interop_test.cpp @@ -236,7 +236,7 @@ int main() return EXIT_FAILURE; } - auto timeline = device.request_semaphore_external(VK_SEMAPHORE_TYPE_TIMELINE_KHR, + auto timeline = device.request_semaphore_external(VK_SEMAPHORE_TYPE_TIMELINE, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT); if (!timeline) { diff --git a/tests/d3d12_interop_test.cpp b/tests/d3d12_interop_test.cpp index b388798d3..f090b8b90 100644 --- a/tests/d3d12_interop_test.cpp +++ b/tests/d3d12_interop_test.cpp @@ -253,7 +253,7 @@ int main() return EXIT_FAILURE; } - auto timeline = device.request_semaphore_external(VK_SEMAPHORE_TYPE_TIMELINE_KHR, + auto timeline = device.request_semaphore_external(VK_SEMAPHORE_TYPE_TIMELINE, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT); if (!timeline) { diff --git a/tests/external_objects.cpp b/tests/external_objects.cpp index df334b8db..8285432df 100644 --- a/tests/external_objects.cpp +++ b/tests/external_objects.cpp @@ -46,7 +46,7 @@ static bool run_test(Device &producer, Device &consumer) // Fallback to binary if we have to. write_timeline = producer.request_semaphore_external( - VK_SEMAPHORE_TYPE_TIMELINE_KHR, + VK_SEMAPHORE_TYPE_TIMELINE, ExternalHandle::get_opaque_semaphore_handle_type()); if (write_timeline) @@ -56,7 +56,7 @@ static bool run_test(Device &producer, Device &consumer) { // No reason for this to fail if we can export timeline ... read_timeline = consumer.request_semaphore_external( - VK_SEMAPHORE_TYPE_TIMELINE_KHR, + VK_SEMAPHORE_TYPE_TIMELINE, ExternalHandle::get_opaque_semaphore_handle_type()); if (!read_timeline) @@ -148,7 +148,7 @@ static bool run_test(Device &producer, Device &consumer) VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT); producer.submit(fill_cmd); auto external = producer.request_semaphore_external( - VK_SEMAPHORE_TYPE_BINARY_KHR, ExternalHandle::get_opaque_semaphore_handle_type()); + VK_SEMAPHORE_TYPE_BINARY, ExternalHandle::get_opaque_semaphore_handle_type()); producer.submit_empty(CommandBuffer::Type::Generic, nullptr, external.get()); ExternalHandle handle = external->export_to_handle(); @@ -157,7 +157,7 @@ static bool run_test(Device &producer, Device &consumer) // Consume auto import = consumer.request_semaphore_external( - VK_SEMAPHORE_TYPE_BINARY_KHR, ExternalHandle::get_opaque_semaphore_handle_type()); + VK_SEMAPHORE_TYPE_BINARY, ExternalHandle::get_opaque_semaphore_handle_type()); if (!import->import_from_handle(handle)) { close_native_handle(handle.handle); @@ -191,7 +191,7 @@ static bool run_test(Device &producer, Device &consumer) // Binary path. external = consumer.request_semaphore_external( - VK_SEMAPHORE_TYPE_BINARY_KHR, ExternalHandle::get_opaque_semaphore_handle_type()); + VK_SEMAPHORE_TYPE_BINARY, ExternalHandle::get_opaque_semaphore_handle_type()); consumer.submit_empty(CommandBuffer::Type::AsyncTransfer, nullptr, external.get()); handle = external->export_to_handle(); @@ -199,7 +199,7 @@ static bool run_test(Device &producer, Device &consumer) break; import = producer.request_semaphore_external( - VK_SEMAPHORE_TYPE_BINARY_KHR, ExternalHandle::get_opaque_semaphore_handle_type()); + VK_SEMAPHORE_TYPE_BINARY, ExternalHandle::get_opaque_semaphore_handle_type()); if (!import->import_from_handle(handle)) { close_native_handle(handle.handle); diff --git a/tests/gl_interop_test.cpp b/tests/gl_interop_test.cpp index 56ef6177a..d81453a7b 100644 --- a/tests/gl_interop_test.cpp +++ b/tests/gl_interop_test.cpp @@ -231,7 +231,7 @@ int main() { // Synchronize with OpenGL. Export a handle. auto ext_semaphore = device.request_semaphore_external( - VK_SEMAPHORE_TYPE_BINARY_KHR, ExternalHandle::get_opaque_semaphore_handle_type()); + VK_SEMAPHORE_TYPE_BINARY, ExternalHandle::get_opaque_semaphore_handle_type()); device.submit_empty(CommandBuffer::Type::Generic, nullptr, ext_semaphore.get()); auto exported_semaphore = ext_semaphore->export_to_handle(); @@ -255,7 +255,7 @@ int main() { // Synchronize with OpenGL. Export a handle that GL can signal. auto ext_semaphore = device.request_semaphore_external( - VK_SEMAPHORE_TYPE_BINARY_KHR, ExternalHandle::get_opaque_semaphore_handle_type()); + VK_SEMAPHORE_TYPE_BINARY, ExternalHandle::get_opaque_semaphore_handle_type()); // Have to mark the semaphore is signalled since we assert on that being the case when exporting a semaphore. ext_semaphore->signal_external(); auto exported_semaphore = ext_semaphore->export_to_handle(); diff --git a/tests/triangle_mesh.cpp b/tests/triangle_mesh.cpp index 68d8b9480..799b130e4 100644 --- a/tests/triangle_mesh.cpp +++ b/tests/triangle_mesh.cpp @@ -47,13 +47,13 @@ struct TriangleMeshApplication : Granite::Application, Granite::EventHandler auto &device = wsi.get_device(); auto &features = device.get_device_features(); - if ((features.subgroup_properties.supportedStages & VK_SHADER_STAGE_MESH_BIT_EXT) == 0) + if ((features.vk11_props.subgroupSupportedStages & VK_SHADER_STAGE_MESH_BIT_EXT) == 0) { LOGE("Subgroups not supported in mesh.\n"); return; } - if ((features.subgroup_properties.supportedStages & VK_SHADER_STAGE_TASK_BIT_EXT) == 0) + if ((features.vk11_props.subgroupSupportedStages & VK_SHADER_STAGE_TASK_BIT_EXT) == 0) { LOGE("Subgroups not supported in task.\n"); return; diff --git a/tests/ycbcr_sampling.cpp b/tests/ycbcr_sampling.cpp index e08d233f8..0084fd614 100644 --- a/tests/ycbcr_sampling.cpp +++ b/tests/ycbcr_sampling.cpp @@ -53,7 +53,7 @@ struct YCbCrSamplingTest : Granite::Application, Granite::EventHandler void on_module_created(const DeviceShaderModuleReadyEvent &e) { - if (!e.get_device().get_device_features().sampler_ycbcr_conversion_features.samplerYcbcrConversion) + if (!e.get_device().get_device_features().vk11_features.samplerYcbcrConversion) { LOGE("YCbCr sampling not supported!\n"); std::terminate(); diff --git a/tests/z_binning_test.cpp b/tests/z_binning_test.cpp index a1e46c125..db655f0a9 100644 --- a/tests/z_binning_test.cpp +++ b/tests/z_binning_test.cpp @@ -35,7 +35,7 @@ static int main_inner() constexpr bool UseOptimized = true; bool support_optimized = UseOptimized && - (features.subgroup_properties.supportedOperations & required) == required && + (features.vk11_props.subgroupSupportedOperations & required) == required && device.supports_subgroup_size_log2(true, 5, 7); auto cmd = device.request_command_buffer(); diff --git a/third_party/fossilize b/third_party/fossilize index 0530d366f..692d3958d 160000 --- a/third_party/fossilize +++ b/third_party/fossilize @@ -1 +1 @@ -Subproject commit 0530d366fbb2cad2d20afd589460e257a1c8a8fb +Subproject commit 692d3958df8097051c73ecc4cd24a8fc9ba3ccb9 diff --git a/third_party/fsr2 b/third_party/fsr2 index e8b982465..916111c03 160000 --- a/third_party/fsr2 +++ b/third_party/fsr2 @@ -1 +1 @@ -Subproject commit e8b982465bdcb0b399229545ff66fd2b8308832d +Subproject commit 916111c03b1feff8b79456f9928817363f642dfa diff --git a/vulkan/command_buffer.cpp b/vulkan/command_buffer.cpp index 3123da017..dbd287031 100644 --- a/vulkan/command_buffer.cpp +++ b/vulkan/command_buffer.cpp @@ -56,8 +56,8 @@ CommandBuffer::CommandBuffer(Device *device_, VkCommandBuffer cmd_, VkPipelineCa // This needs to affect hashing to make Fossilize path behave as expected. auto &features = device->get_device_features(); pipeline_state.subgroup_size_tag = - (features.subgroup_size_control_properties.minSubgroupSize << 0) | - (features.subgroup_size_control_properties.maxSubgroupSize << 8); + (features.vk13_props.minSubgroupSize << 0) | + (features.vk13_props.maxSubgroupSize << 8); device->lock.read_only_cache.lock_read(); } @@ -394,7 +394,7 @@ void CommandBuffer::barrier(const VkDependencyInfo &dep) } #endif - if (device->get_device_features().sync2_features.synchronization2) + if (device->get_device_features().vk13_features.synchronization2) { Util::SmallVector tmp_buffer; Util::SmallVector tmp_image; @@ -458,7 +458,7 @@ void CommandBuffer::barrier(const VkDependencyInfo &dep) } } - table.vkCmdPipelineBarrier2KHR(cmd, final_dep); + table.vkCmdPipelineBarrier2(cmd, final_dep); } else { @@ -1128,7 +1128,7 @@ Pipeline CommandBuffer::build_compute_pipeline(Device *device, const DeferredPip // we must assume compilation can be synchronous. if (mode == CompileMode::FailOnCompileRequired && (device->get_workarounds().broken_pipeline_cache_control || - !device->get_device_features().pipeline_creation_cache_control_features.pipelineCreationCacheControl)) + !device->get_device_features().vk13_features.pipelineCreationCacheControl)) { return {}; } @@ -1166,7 +1166,7 @@ Pipeline CommandBuffer::build_compute_pipeline(Device *device, const DeferredPip spec_info.dataSize = spec_info.mapEntryCount * sizeof(uint32_t); } - VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_info; + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_size_info; if (compile.static_state.state.subgroup_control_size) { @@ -1189,7 +1189,7 @@ Pipeline CommandBuffer::build_compute_pipeline(Device *device, const DeferredPip auto &table = device->get_device_table(); if (mode == CompileMode::FailOnCompileRequired) - info.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT; + info.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; auto start_ts = Util::get_current_time_nsecs(); VkResult vr = table.vkCreateComputePipelines(device->get_device(), compile.cache, 1, &info, nullptr, &compute_pipeline); @@ -1227,7 +1227,7 @@ void CommandBuffer::extract_pipeline_state(DeferredPipelineCompile &compile) con bool CommandBuffer::setup_subgroup_size_control( Vulkan::Device &device, VkPipelineShaderStageCreateInfo &stage_info, - VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT &required_info, + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo &required_info, VkShaderStageFlagBits stage, bool full_group, unsigned min_size_log2, unsigned max_size_log2) { @@ -1237,22 +1237,22 @@ bool CommandBuffer::setup_subgroup_size_control( auto &features = device.get_device_features(); if (full_group) - stage_info.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT; + stage_info.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT; uint32_t min_subgroups = 1u << min_size_log2; uint32_t max_subgroups = 1u << max_size_log2; - if (min_subgroups <= features.subgroup_size_control_properties.minSubgroupSize && - max_subgroups >= features.subgroup_size_control_properties.maxSubgroupSize) + if (min_subgroups <= features.vk13_props.minSubgroupSize && + max_subgroups >= features.vk13_props.maxSubgroupSize) { - stage_info.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT; + stage_info.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT; } else { - required_info = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT }; + required_info = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO }; // Pick a fixed subgroup size. Prefer smallest subgroup size. - if (min_subgroups < features.subgroup_size_control_properties.minSubgroupSize) - required_info.requiredSubgroupSize = features.subgroup_size_control_properties.minSubgroupSize; + if (min_subgroups < features.vk13_props.minSubgroupSize) + required_info.requiredSubgroupSize = features.vk13_props.minSubgroupSize; else required_info.requiredSubgroupSize = min_subgroups; @@ -1273,7 +1273,7 @@ Pipeline CommandBuffer::build_graphics_pipeline(Device *device, const DeferredPi // we must assume compilation can be synchronous. if (mode == CompileMode::FailOnCompileRequired && (device->get_workarounds().broken_pipeline_cache_control || - !device->get_device_features().pipeline_creation_cache_control_features.pipelineCreationCacheControl)) + !device->get_device_features().vk13_features.pipelineCreationCacheControl)) { return {}; } @@ -1438,8 +1438,8 @@ Pipeline CommandBuffer::build_graphics_pipeline(Device *device, const DeferredPi VkSpecializationMapEntry spec_entries[ecast(ShaderStage::Count)][VULKAN_NUM_TOTAL_SPEC_CONSTANTS]; uint32_t spec_constants[Util::ecast(ShaderStage::Count)][VULKAN_NUM_TOTAL_SPEC_CONSTANTS]; - VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_info_task; - VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_info_mesh; + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_size_info_task; + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_size_info_mesh; for (unsigned i = 0; i < Util::ecast(ShaderStage::Count); i++) { @@ -1479,7 +1479,7 @@ Pipeline CommandBuffer::build_graphics_pipeline(Device *device, const DeferredPi if (stage == ShaderStage::Mesh || stage == ShaderStage::Task) { - VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT *required_info; + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *required_info; unsigned min_size_log2, max_size_log2; bool size_enabled, full_group; @@ -1589,7 +1589,7 @@ Pipeline CommandBuffer::build_graphics_pipeline(Device *device, const DeferredPi auto &table = device->get_device_table(); if (mode == CompileMode::FailOnCompileRequired) - pipe.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT; + pipe.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; auto start_ts = Util::get_current_time_nsecs(); VkResult res = table.vkCreateGraphicsPipelines(device->get_device(), compile.cache, 1, &pipe, nullptr, &pipeline); @@ -1928,9 +1928,9 @@ void CommandBuffer::wait_events(uint32_t count, const PipelineEvent *events, con for (uint32_t i = 0; i < count; i++) barrier(deps[i]); } - else if (device->get_device_features().sync2_features.synchronization2) + else if (device->get_device_features().vk13_features.synchronization2) { - table.vkCmdWaitEvents2KHR(cmd, count, vk_events.data(), deps); + table.vkCmdWaitEvents2(cmd, count, vk_events.data(), deps); } else { @@ -1953,9 +1953,9 @@ PipelineEvent CommandBuffer::signal_event(const VkDependencyInfo &dep) if (!device->get_workarounds().emulate_event_as_pipeline_barrier) { - if (device->get_device_features().sync2_features.synchronization2) + if (device->get_device_features().vk13_features.synchronization2) { - table.vkCmdSetEvent2KHR(cmd, event->get_event(), &dep); + table.vkCmdSetEvent2(cmd, event->get_event(), &dep); } else { @@ -2775,7 +2775,7 @@ void CommandBuffer::draw_multi_indirect(const Buffer &buffer, VkDeviceSize offse const Buffer &count, VkDeviceSize count_offset) { VK_ASSERT(!is_compute); - if (!get_device().get_device_features().supports_draw_indirect_count) + if (!get_device().get_device_features().vk12_features.drawIndirectCount) { LOGE("VK_KHR_draw_indirect_count not supported, dropping draw call.\n"); return; @@ -2784,9 +2784,9 @@ void CommandBuffer::draw_multi_indirect(const Buffer &buffer, VkDeviceSize offse if (flush_render_state(true) != VK_NULL_HANDLE) { VK_ASSERT(pipeline_state.program->get_shader(ShaderStage::Vertex) != nullptr); - table.vkCmdDrawIndirectCountKHR(cmd, buffer.get_buffer(), offset, - count.get_buffer(), count_offset, - draw_count, stride); + table.vkCmdDrawIndirectCount(cmd, buffer.get_buffer(), offset, + count.get_buffer(), count_offset, + draw_count, stride); } else LOGE("Failed to flush render state, draw call will be dropped.\n"); @@ -2796,7 +2796,7 @@ void CommandBuffer::draw_indexed_multi_indirect(const Buffer &buffer, VkDeviceSi const Buffer &count, VkDeviceSize count_offset) { VK_ASSERT(!is_compute); - if (!get_device().get_device_features().supports_draw_indirect_count) + if (!get_device().get_device_features().vk12_features.drawIndirectCount) { LOGE("VK_KHR_draw_indirect_count not supported, dropping draw call.\n"); return; @@ -2805,9 +2805,9 @@ void CommandBuffer::draw_indexed_multi_indirect(const Buffer &buffer, VkDeviceSi if (flush_render_state(true) != VK_NULL_HANDLE) { VK_ASSERT(pipeline_state.program->get_shader(ShaderStage::Vertex) != nullptr); - table.vkCmdDrawIndexedIndirectCountKHR(cmd, buffer.get_buffer(), offset, - count.get_buffer(), count_offset, - draw_count, stride); + table.vkCmdDrawIndexedIndirectCount(cmd, buffer.get_buffer(), offset, + count.get_buffer(), count_offset, + draw_count, stride); } else LOGE("Failed to flush render state, draw call will be dropped.\n"); diff --git a/vulkan/context.cpp b/vulkan/context.cpp index ccb0170c1..cd70601ed 100644 --- a/vulkan/context.cpp +++ b/vulkan/context.cpp @@ -20,6 +20,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define NOMINMAX #include "context.hpp" #include "small_vector.hpp" #include @@ -154,12 +155,13 @@ const VkApplicationInfo &CopiedApplicationInfo::get_application_info() const bool Context::init_instance(const char * const *instance_ext, uint32_t instance_ext_count, ContextCreationFlags flags) { - destroy(); + destroy_device(); + destroy_instance(); owned_instance = true; if (!create_instance(instance_ext, instance_ext_count, flags)) { - destroy(); + destroy_instance(); LOGE("Failed to create Vulkan instance.\n"); return false; } @@ -174,7 +176,7 @@ bool Context::init_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface_compat, co VkPhysicalDeviceFeatures features = {}; if (!create_device(gpu_, surface_compat, device_ext, device_ext_count, &features, flags)) { - destroy(); + destroy_device(); LOGE("Failed to create Vulkan device.\n"); return false; } @@ -265,7 +267,8 @@ bool Context::init_device_from_instance(VkInstance instance_, VkPhysicalDevice g const VkPhysicalDeviceFeatures *required_features, ContextCreationFlags flags) { - destroy(); + destroy_device(); + destroy_instance(); instance = instance_; owned_instance = false; @@ -276,7 +279,7 @@ bool Context::init_device_from_instance(VkInstance instance_, VkPhysicalDevice g if (!create_device(gpu_, surface, required_device_extensions, num_required_device_extensions, required_features, flags)) { - destroy(); + destroy_device(); LOGE("Failed to create Vulkan device.\n"); return false; } @@ -284,27 +287,38 @@ bool Context::init_device_from_instance(VkInstance instance_, VkPhysicalDevice g return true; } -void Context::destroy() +void Context::destroy_device() { if (device != VK_NULL_HANDLE) device_table.vkDeviceWaitIdle(device); -#ifdef VULKAN_DEBUG - if (debug_messenger) - vkDestroyDebugUtilsMessengerEXT(instance, debug_messenger, nullptr); - debug_messenger = VK_NULL_HANDLE; -#endif - #if defined(ANDROID) && defined(HAVE_SWAPPY) if (device != VK_NULL_HANDLE) SwappyVk_destroyDevice(device); #endif if (owned_device && device != VK_NULL_HANDLE) + { device_table.vkDestroyDevice(device, nullptr); + device = VK_NULL_HANDLE; + owned_device = false; + } +} + +void Context::destroy_instance() +{ +#ifdef VULKAN_DEBUG + if (debug_messenger) + vkDestroyDebugUtilsMessengerEXT(instance, debug_messenger, nullptr); + debug_messenger = VK_NULL_HANDLE; +#endif if (owned_instance && instance != VK_NULL_HANDLE) + { vkDestroyInstance(instance, nullptr); + instance = VK_NULL_HANDLE; + owned_instance = false; + } } Context::Context() @@ -313,7 +327,8 @@ Context::Context() Context::~Context() { - destroy(); + destroy_device(); + destroy_instance(); } const VkApplicationInfo &Context::get_application_info() const @@ -524,28 +539,30 @@ VkResult Context::create_device_from_profile(const VkDeviceCreateInfo &info, VkD #endif } -bool Context::create_instance(const char * const *instance_ext, uint32_t instance_ext_count, ContextCreationFlags flags) +VkApplicationInfo Context::get_promoted_application_info() const { - uint32_t target_instance_version = user_application_info.get_application_info().apiVersion; + auto app_info = get_application_info(); - // Target an instance version of at least 1.3 for FFmpeg decode. - if ((flags & video_context_flags) != 0) - if (target_instance_version < VK_API_VERSION_1_3) - target_instance_version = VK_API_VERSION_1_3; + // Granite min-req is 1.1. + app_info.apiVersion = std::max(VK_API_VERSION_1_1, app_info.apiVersion); - if (volkGetInstanceVersion() < target_instance_version && target_instance_version == VK_API_VERSION_1_3) - target_instance_version = user_application_info.get_application_info().apiVersion; + // Target Vulkan 1.3 if available. + app_info.apiVersion = std::max(app_info.apiVersion, std::min(VK_API_VERSION_1_3, volkGetInstanceVersion())); - if (volkGetInstanceVersion() < target_instance_version) + return app_info; +} + +bool Context::create_instance(const char * const *instance_ext, uint32_t instance_ext_count, ContextCreationFlags flags) +{ + VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; + auto app_info = get_promoted_application_info(); + + if (volkGetInstanceVersion() < app_info.apiVersion) { - LOGE("Vulkan loader does not support target Vulkan version.\n"); + LOGE("Vulkan loader does not support required Vulkan version.\n"); return false; } - VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; - auto app_info = get_application_info(); - if (app_info.apiVersion < target_instance_version) - app_info.apiVersion = target_instance_version; info.pApplicationInfo = &app_info; std::vector instance_exts; @@ -691,6 +708,9 @@ bool Context::create_instance(const char * const *instance_ext, uint32_t instanc } else if (vkCreateInstance(&info, nullptr, &instance) != VK_SUCCESS) return false; + + // If we have a pre-existing instance, we can only assume Vulkan 1.1 in legacy interface. + ext.instance_api_core_version = app_info.apiVersion; } enabled_instance_extensions = std::move(instance_exts); @@ -901,28 +921,22 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, if (!has_extension(required_device_extensions[i])) return false; - VkPhysicalDeviceProperties2 gpu_props2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; - if (has_extension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) - { - ext.supports_driver_properties = true; - ext.driver_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR }; - gpu_props2.pNext = &ext.driver_properties; - } + vkGetPhysicalDeviceProperties(gpu, &gpu_props); + // We can use core device functionality if enabled VkInstance apiVersion and physical device supports it. + ext.device_api_core_version = std::min(ext.instance_api_core_version, gpu_props.apiVersion); - vkGetPhysicalDeviceProperties2(gpu, &gpu_props2); - gpu_props = gpu_props2.properties; LOGI("Using Vulkan GPU: %s\n", gpu_props.deviceName); // FFmpeg integration requires Vulkan 1.3 core for physical device. uint32_t minimum_api_version = (flags & video_context_flags) ? VK_API_VERSION_1_3 : VK_API_VERSION_1_1; - if (gpu_props.apiVersion < minimum_api_version && (flags & video_context_flags) != 0) + if (ext.device_api_core_version < minimum_api_version && (flags & video_context_flags) != 0) { LOGW("Requested FFmpeg-enabled context, but Vulkan 1.3 was not supported. Falling back to 1.1 without support.\n"); minimum_api_version = VK_API_VERSION_1_1; flags &= ~video_context_flags; } - if (gpu_props.apiVersion < minimum_api_version) + if (ext.device_api_core_version < minimum_api_version) { LOGE("Found no Vulkan GPU which supports Vulkan 1.%u.\n", VK_API_VERSION_MINOR(minimum_api_version)); @@ -998,22 +1012,12 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, queue_info.timestamp_valid_bits = queue_props[queue_info.family_indices[QUEUE_INDEX_GRAPHICS]].queueFamilyProperties.timestampValidBits; - // Driver ends up interleaving GPU work in very bizarre ways, causing horrible GPU - // bubbles and completely broken pacing. Single queue works around it. - bool broken_async_queues = - ext.supports_driver_properties && - ext.driver_properties.driverID == VK_DRIVER_ID_SAMSUNG_PROPRIETARY; - - if (broken_async_queues) - LOGW("Working around broken scheduler for separate compute queues, forcing single GRAPHICS + COMPUTE queue.\n"); - // Prefer another graphics queue since we can do async graphics that way. // The compute queue is to be treated as high priority since we also do async graphics on it. - if (broken_async_queues || - (!find_vacant_queue(queue_info.family_indices[QUEUE_INDEX_COMPUTE], queue_indices[QUEUE_INDEX_COMPUTE], - VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 0, 1.0f) && - !find_vacant_queue(queue_info.family_indices[QUEUE_INDEX_COMPUTE], queue_indices[QUEUE_INDEX_COMPUTE], - VK_QUEUE_COMPUTE_BIT, 0, 1.0f))) + if (!find_vacant_queue(queue_info.family_indices[QUEUE_INDEX_COMPUTE], queue_indices[QUEUE_INDEX_COMPUTE], + VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 0, 1.0f) && + !find_vacant_queue(queue_info.family_indices[QUEUE_INDEX_COMPUTE], queue_indices[QUEUE_INDEX_COMPUTE], + VK_QUEUE_COMPUTE_BIT, 0, 1.0f)) { // Fallback to the graphics queue if we must. queue_info.family_indices[QUEUE_INDEX_COMPUTE] = queue_info.family_indices[QUEUE_INDEX_GRAPHICS]; @@ -1122,12 +1126,6 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, } #endif - if (has_extension(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME)) - { - ext.supports_mirror_clamp_to_edge = true; - enabled_extensions.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME); - } - #ifdef _WIN32 if (ext.supports_surface_capabilities2 && has_extension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) { @@ -1158,12 +1156,6 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, else ext.supports_external = false; - if (has_extension(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) - { - ext.supports_draw_indirect_count = true; - enabled_extensions.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); - } - if (has_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME)) { ext.supports_calibrated_timestamps = true; @@ -1176,28 +1168,28 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, ext.supports_conservative_rasterization = true; } - if (has_extension(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME)) + if (ext.device_api_core_version < VK_API_VERSION_1_2) { - enabled_extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); - ext.supports_image_format_list = true; - } - - if (has_extension(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); - ext.supports_shader_float_control = true; - } + if (!has_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) + { + LOGE("VK_KHR_create_renderpass2 is not supported.\n"); + return false; + } - if (has_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) - { - ext.supports_create_renderpass2 = true; enabled_extensions.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); + + if (has_extension(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME)) + { + ext.supports_image_format_list = true; + enabled_extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); + } } else - { - LOGE("VK_KHR_create_renderpass2 is not supported.\n"); - return false; - } + ext.supports_image_format_list = true; + + // Physical device functionality. + ext.supports_format_feature_flags2 = ext.device_api_core_version >= VK_API_VERSION_1_3 || + has_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME); if (has_extension(VK_EXT_TOOLING_INFO_EXTENSION_NAME)) ext.supports_tooling_info = true; @@ -1276,139 +1268,45 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, } pdf2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; - - ext.multiview_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES }; - ext.sampler_ycbcr_conversion_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES }; - ext.shader_draw_parameters_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES }; - - ext.storage_8bit_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR }; - ext.storage_16bit_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR }; - ext.float16_int8_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR }; - ext.ubo_std430_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR }; - ext.timeline_semaphore_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR }; - ext.sync2_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR }; - ext.present_id_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR }; - ext.present_wait_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR }; - ext.performance_query_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR }; - ext.swapchain_maintenance1_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT }; - - ext.subgroup_size_control_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT }; - ext.host_query_reset_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT }; - ext.demote_to_helper_invocation_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT }; - ext.scalar_block_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT }; - ext.descriptor_indexing_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT }; - ext.memory_priority_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT }; - ext.astc_decode_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT }; - ext.astc_hdr_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT }; - ext.pipeline_creation_cache_control_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT }; - ext.pageable_device_local_memory_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT }; - ext.mesh_shader_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT }; - ext.shader_subgroup_extended_types_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES }; - ext.index_type_uint8_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT }; - - ext.compute_shader_derivative_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV }; - ext.device_generated_commands_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV }; - ext.device_generated_commands_compute_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV }; - ext.buffer_device_address_features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR }; - void **ppNext = &pdf2.pNext; - *ppNext = &ext.multiview_features; - ppNext = &ext.multiview_features.pNext; - *ppNext = &ext.sampler_ycbcr_conversion_features; - ppNext = &ext.sampler_ycbcr_conversion_features.pNext; - *ppNext = &ext.shader_draw_parameters_features; - ppNext = &ext.shader_draw_parameters_features.pNext; +#define ADD_CHAIN(s, type) do { \ + s.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ ## type; \ + s.pNext = nullptr; \ + *ppNext = &(s); \ + ppNext = &((s).pNext); \ +} while(0) - if (has_extension(VK_KHR_8BIT_STORAGE_EXTENSION_NAME)) + if (ext.device_api_core_version >= VK_API_VERSION_1_2) { - enabled_extensions.push_back(VK_KHR_8BIT_STORAGE_EXTENSION_NAME); - *ppNext = &ext.storage_8bit_features; - ppNext = &ext.storage_8bit_features.pNext; + ADD_CHAIN(ext.vk11_features, VULKAN_1_1_FEATURES); + ADD_CHAIN(ext.vk12_features, VULKAN_1_2_FEATURES); } - - if (has_extension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_16BIT_STORAGE_EXTENSION_NAME); - *ppNext = &ext.storage_16bit_features; - ppNext = &ext.storage_16bit_features.pNext; - } - - if (has_extension(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) + else { - enabled_extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); - *ppNext = &ext.float16_int8_features; - ppNext = &ext.float16_int8_features.pNext; + if (has_extension(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) + ADD_CHAIN(ext.host_query_reset_features, HOST_QUERY_RESET_FEATURES); } - if (has_extension(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); - *ppNext = &ext.subgroup_size_control_features; - ppNext = &ext.subgroup_size_control_features.pNext; - } + if (ext.device_api_core_version >= VK_API_VERSION_1_3) + ADD_CHAIN(ext.vk13_features, VULKAN_1_3_FEATURES); if (has_extension(VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME)) { enabled_extensions.push_back(VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME); - *ppNext = &ext.compute_shader_derivative_features; - ppNext = &ext.compute_shader_derivative_features.pNext; - } - - if (has_extension(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME); - *ppNext = &ext.host_query_reset_features; - ppNext = &ext.host_query_reset_features.pNext; - } - - if (has_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); - *ppNext = &ext.demote_to_helper_invocation_features; - ppNext = &ext.demote_to_helper_invocation_features.pNext; - } - - if (has_extension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); - *ppNext = &ext.scalar_block_features; - ppNext = &ext.scalar_block_features.pNext; - } - - if (has_extension(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME); - *ppNext = &ext.ubo_std430_features; - ppNext = &ext.ubo_std430_features.pNext; - } - - if (has_extension(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME); - *ppNext = &ext.timeline_semaphore_features; - ppNext = &ext.timeline_semaphore_features.pNext; - } - - if (has_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - *ppNext = &ext.descriptor_indexing_features; - ppNext = &ext.descriptor_indexing_features.pNext; + ADD_CHAIN(ext.compute_shader_derivative_features, COMPUTE_SHADER_DERIVATIVES_FEATURES_NV); } if (has_extension(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) { enabled_extensions.push_back(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME); - *ppNext = &ext.performance_query_features; - ppNext = &ext.performance_query_features.pNext; + ADD_CHAIN(ext.performance_query_features, PERFORMANCE_QUERY_FEATURES_KHR); } if (has_extension(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME)) { enabled_extensions.push_back(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME); - *ppNext = &ext.memory_priority_features; - ppNext = &ext.memory_priority_features.pNext; + ADD_CHAIN(ext.memory_priority_features, MEMORY_PRIORITY_FEATURES_EXT); } if (has_extension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) @@ -1421,125 +1319,63 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, { ext.supports_astc_decode_mode = true; enabled_extensions.push_back(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME); - *ppNext = &ext.astc_decode_features; - ppNext = &ext.astc_decode_features.pNext; - } - - if (has_extension(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME); - *ppNext = &ext.astc_hdr_features; - ppNext = &ext.astc_hdr_features.pNext; - } - - if (has_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) - { - ext.supports_sync2 = true; - enabled_extensions.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); - *ppNext = &ext.sync2_features; - ppNext = &ext.sync2_features.pNext; - } - - if (has_extension(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) - { - ext.supports_pipeline_creation_cache_control = true; - enabled_extensions.push_back(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME); - *ppNext = &ext.pipeline_creation_cache_control_features; - ppNext = &ext.pipeline_creation_cache_control_features.pNext; + ADD_CHAIN(ext.astc_decode_features, ASTC_DECODE_FEATURES_EXT); } if (has_extension(VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME)) { enabled_extensions.push_back(VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME); - *ppNext = &ext.pageable_device_local_memory_features; - ppNext = &ext.pageable_device_local_memory_features.pNext; - } - - if (has_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME)) - { - ext.supports_format_feature_flags2 = true; - enabled_extensions.push_back(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME); + ADD_CHAIN(ext.pageable_device_local_memory_features, PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT); } if (has_extension(VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME)) { enabled_extensions.push_back(VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME); - *ppNext = &ext.device_generated_commands_features; - ppNext = &ext.device_generated_commands_features.pNext; + ADD_CHAIN(ext.device_generated_commands_features, DEVICE_GENERATED_COMMANDS_FEATURES_NV); } if (has_extension(VK_NV_DEVICE_GENERATED_COMMANDS_COMPUTE_EXTENSION_NAME)) { enabled_extensions.push_back(VK_NV_DEVICE_GENERATED_COMMANDS_COMPUTE_EXTENSION_NAME); - *ppNext = &ext.device_generated_commands_compute_features; - ppNext = &ext.device_generated_commands_compute_features.pNext; - } - - if (has_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); - *ppNext = &ext.buffer_device_address_features; - ppNext = &ext.buffer_device_address_features.pNext; + ADD_CHAIN(ext.device_generated_commands_compute_features, DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV); } if (has_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME)) { enabled_extensions.push_back(VK_EXT_MESH_SHADER_EXTENSION_NAME); - *ppNext = &ext.mesh_shader_features; - ppNext = &ext.mesh_shader_features.pNext; + ADD_CHAIN(ext.mesh_shader_features, MESH_SHADER_FEATURES_EXT); } - if (has_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); - ext.supports_spirv_1_4 = true; - } - - if (has_extension(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME)) + if (has_extension(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME)) { - enabled_extensions.push_back(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME); - *ppNext = &ext.shader_subgroup_extended_types_features; - ppNext = &ext.shader_subgroup_extended_types_features.pNext; + enabled_extensions.push_back(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME); + ADD_CHAIN(ext.index_type_uint8_features, INDEX_TYPE_UINT8_FEATURES_EXT); } - if (has_extension(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME)) + if (has_extension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME)) { - enabled_extensions.push_back(VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME); - *ppNext = &ext.index_type_uint8_features; - ppNext = &ext.index_type_uint8_features.pNext; + ext.supports_external_memory_host = true; + enabled_extensions.push_back(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME); } if ((flags & CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT) != 0 && requires_swapchain) { - bool broken_present_wait = ext.driver_properties.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY && - NV_DRIVER_VERSION_MAJOR(gpu_props.driverVersion) < 535; - - if (broken_present_wait) + if (has_extension(VK_KHR_PRESENT_ID_EXTENSION_NAME)) { - LOGW("Disabling present_wait due to broken driver.\n"); + enabled_extensions.push_back(VK_KHR_PRESENT_ID_EXTENSION_NAME); + ADD_CHAIN(ext.present_id_features, PRESENT_ID_FEATURES_KHR); } - else - { - if (has_extension(VK_KHR_PRESENT_ID_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_PRESENT_ID_EXTENSION_NAME); - *ppNext = &ext.present_id_features; - ppNext = &ext.present_id_features.pNext; - } - if (has_extension(VK_KHR_PRESENT_WAIT_EXTENSION_NAME)) - { - enabled_extensions.push_back(VK_KHR_PRESENT_WAIT_EXTENSION_NAME); - *ppNext = &ext.present_wait_features; - ppNext = &ext.present_wait_features.pNext; - } + if (has_extension(VK_KHR_PRESENT_WAIT_EXTENSION_NAME)) + { + enabled_extensions.push_back(VK_KHR_PRESENT_WAIT_EXTENSION_NAME); + ADD_CHAIN(ext.present_wait_features, PRESENT_WAIT_FEATURES_KHR); } if (ext.supports_surface_maintenance1 && has_extension(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME)) { enabled_extensions.push_back(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME); - *ppNext = &ext.swapchain_maintenance1_features; - ppNext = &ext.swapchain_maintenance1_features.pNext; + ADD_CHAIN(ext.swapchain_maintenance1_features, SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT); } if (ext.supports_swapchain_colorspace && has_extension(VK_EXT_HDR_METADATA_EXTENSION_NAME)) @@ -1561,8 +1397,24 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, vkGetPhysicalDeviceFeatures2(gpu, &pdf2); } - ext.buffer_device_address_features.bufferDeviceAddressCaptureReplay = VK_FALSE; - ext.buffer_device_address_features.bufferDeviceAddressMultiDevice = VK_FALSE; + if (ext.host_query_reset_features.hostQueryReset) + ext.vk12_features.hostQueryReset = VK_TRUE; + + ext.vk11_features.multiviewGeometryShader = VK_FALSE; + ext.vk11_features.multiviewTessellationShader = VK_FALSE; + ext.vk11_features.protectedMemory = VK_FALSE; + ext.vk11_features.variablePointers = VK_FALSE; + ext.vk11_features.variablePointersStorageBuffer = VK_FALSE; + + ext.vk12_features.bufferDeviceAddressCaptureReplay = VK_FALSE; + ext.vk12_features.bufferDeviceAddressMultiDevice = VK_FALSE; + ext.vk12_features.imagelessFramebuffer = VK_FALSE; + + ext.vk13_features.descriptorBindingInlineUniformBlockUpdateAfterBind = VK_FALSE; + ext.vk13_features.inlineUniformBlock = VK_FALSE; + ext.vk13_features.privateData = VK_FALSE; + ext.vk13_features.robustImageAccess = VK_FALSE; + ext.device_generated_commands_compute_features.deviceGeneratedComputeCaptureReplay = VK_FALSE; // TODO ext.device_generated_commands_compute_features.deviceGeneratedComputePipelines = VK_FALSE; @@ -1625,82 +1477,60 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, device_info.pNext = &pdf2; - if (has_extension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME)) - { - ext.supports_external_memory_host = true; - enabled_extensions.push_back(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME); - } - // Only need GetPhysicalDeviceProperties2 for Vulkan 1.1-only code, so don't bother getting KHR variant. VkPhysicalDeviceProperties2 props = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; - ext.subgroup_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES }; - ext.multiview_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES }; - - ext.host_memory_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT }; - ext.subgroup_size_control_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT }; - ext.descriptor_indexing_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT }; - ext.conservative_rasterization_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT }; - ext.float_control_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR }; - ext.id_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES }; - ext.device_generated_commands_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV }; - ext.mesh_shader_properties = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT }; - + // Fallback, query some important Vulkan 1.1 structs if we cannot use core 1.2 method. + VkPhysicalDeviceDriverProperties driver_properties = {}; + VkPhysicalDeviceIDProperties id_properties = {}; + VkPhysicalDeviceSubgroupProperties subgroup_properties = {}; ppNext = &props.pNext; - *ppNext = &ext.subgroup_properties; - ppNext = &ext.subgroup_properties.pNext; - *ppNext = &ext.multiview_properties; - ppNext = &ext.multiview_properties.pNext; - - if (ext.supports_external_memory_host) + if (ext.device_api_core_version >= VK_API_VERSION_1_2) { - *ppNext = &ext.host_memory_properties; - ppNext = &ext.host_memory_properties.pNext; + ADD_CHAIN(ext.vk11_props, VULKAN_1_1_PROPERTIES); + ADD_CHAIN(ext.vk12_props, VULKAN_1_2_PROPERTIES); } - - if (has_extension(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME)) + else { - *ppNext = &ext.subgroup_size_control_properties; - ppNext = &ext.subgroup_size_control_properties.pNext; + if (has_extension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) + ADD_CHAIN(driver_properties, DRIVER_PROPERTIES); + ADD_CHAIN(id_properties, ID_PROPERTIES); + ADD_CHAIN(subgroup_properties, SUBGROUP_PROPERTIES); } - if (has_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) - { - *ppNext = &ext.descriptor_indexing_properties; - ppNext = &ext.descriptor_indexing_properties.pNext; - } + if (ext.device_api_core_version >= VK_API_VERSION_1_3) + ADD_CHAIN(ext.vk13_props, VULKAN_1_3_PROPERTIES); + + if (ext.supports_external_memory_host) + ADD_CHAIN(ext.host_memory_properties, EXTERNAL_MEMORY_HOST_PROPERTIES_EXT); if (has_extension(VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME)) - { - *ppNext = &ext.device_generated_commands_properties; - ppNext = &ext.device_generated_commands_properties.pNext; - } + ADD_CHAIN(ext.device_generated_commands_properties, DEVICE_GENERATED_COMMANDS_PROPERTIES_NV); if (ext.supports_conservative_rasterization) - { - *ppNext = &ext.conservative_rasterization_properties; - ppNext = &ext.conservative_rasterization_properties.pNext; - } + ADD_CHAIN(ext.conservative_rasterization_properties, CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT); - if (ext.supports_shader_float_control) - { - *ppNext = &ext.float_control_properties; - ppNext = &ext.float_control_properties.pNext; - } + if (has_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME)) + ADD_CHAIN(ext.mesh_shader_properties, MESH_SHADER_PROPERTIES_EXT); - if (ext.supports_external) - { - *ppNext = &ext.id_properties; - ppNext = &ext.id_properties.pNext; - } + vkGetPhysicalDeviceProperties2(gpu, &props); - if (has_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME)) + if (ext.device_api_core_version < VK_API_VERSION_1_2) { - *ppNext = &ext.mesh_shader_properties; - ppNext = &ext.mesh_shader_properties.pNext; + ext.driver_id = driver_properties.driverID; + ext.vk12_props.driverID = ext.driver_id; + memcpy(ext.vk11_props.deviceUUID, id_properties.deviceUUID, sizeof(id_properties.deviceUUID)); + memcpy(ext.vk11_props.driverUUID, id_properties.driverUUID, sizeof(id_properties.driverUUID)); + memcpy(ext.vk11_props.deviceLUID, id_properties.deviceLUID, sizeof(id_properties.deviceLUID)); + ext.vk11_props.deviceNodeMask = id_properties.deviceNodeMask; + ext.vk11_props.deviceLUIDValid = id_properties.deviceLUIDValid; + ext.vk11_props.subgroupQuadOperationsInAllStages = subgroup_properties.quadOperationsInAllStages; + ext.vk11_props.subgroupSupportedOperations = subgroup_properties.supportedOperations; + ext.vk11_props.subgroupSupportedStages = subgroup_properties.supportedStages; + ext.vk11_props.subgroupSize = subgroup_properties.subgroupSize; } - - vkGetPhysicalDeviceProperties2(gpu, &props); + else + ext.driver_id = ext.vk12_props.driverID; #ifdef GRANITE_VULKAN_PROFILES // Override any properties in the profile in strict mode. @@ -1739,7 +1569,7 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, ext.pdf2 = &pdf2; #ifdef GRANITE_VULKAN_FOSSILIZE - feature_filter.init(user_application_info.get_application_info().apiVersion, + feature_filter.init(ext.device_api_core_version, enabled_device_extensions.data(), device_info.enabledExtensionCount, &pdf2, &props); @@ -1748,6 +1578,11 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, volkLoadDeviceTable(&device_table, device); + if (!device_table.vkCreateRenderPass2) + device_table.vkCreateRenderPass2 = device_table.vkCreateRenderPass2KHR; + if (!device_table.vkResetQueryPool) + device_table.vkResetQueryPool = device_table.vkResetQueryPoolEXT; + for (int i = 0; i < QUEUE_INDEX_COUNT; i++) { if (queue_info.family_indices[i] != VK_QUEUE_FAMILY_IGNORED) @@ -1780,24 +1615,9 @@ bool Context::create_device(VkPhysicalDevice gpu_, VkSurfaceKHR surface, LOGI("%s queue: family %u, index %u.\n", family_names[i], queue_info.family_indices[i], queue_indices[i]); #endif - check_descriptor_indexing_features(); - return true; } -void Context::check_descriptor_indexing_features() -{ - auto &f = ext.descriptor_indexing_features; - if (f.descriptorBindingSampledImageUpdateAfterBind && - f.descriptorBindingPartiallyBound && - f.descriptorBindingVariableDescriptorCount && - f.runtimeDescriptorArray && - f.shaderSampledImageArrayNonUniformIndexing) - { - ext.supports_descriptor_indexing = true; - } -} - #ifdef GRANITE_VULKAN_FOSSILIZE bool Context::format_is_supported(VkFormat format, VkFormatFeatureFlags features) { diff --git a/vulkan/context.hpp b/vulkan/context.hpp index ab9db29ad..1a4683b7b 100644 --- a/vulkan/context.hpp +++ b/vulkan/context.hpp @@ -49,82 +49,55 @@ namespace Vulkan struct DeviceFeatures { bool supports_debug_utils = false; - bool supports_mirror_clamp_to_edge = false; bool supports_external_memory_host = false; bool supports_surface_capabilities2 = false; bool supports_full_screen_exclusive = false; - bool supports_descriptor_indexing = false; bool supports_conservative_rasterization = false; - bool supports_draw_indirect_count = false; - bool supports_driver_properties = false; bool supports_calibrated_timestamps = false; bool supports_memory_budget = false; - bool supports_astc_decode_mode = false; - bool supports_sync2 = false; - bool supports_create_renderpass2 = false; bool supports_video_queue = false; + bool supports_driver_properties = false; bool supports_video_decode_queue = false; bool supports_video_decode_h264 = false; bool supports_video_decode_h265 = false; + bool supports_astc_decode_mode = false; + bool supports_image_format_list = false; + bool supports_format_feature_flags2 = false; #ifdef VK_ENABLE_BETA_EXTENSIONS bool supports_video_encode_queue = false; bool supports_video_encode_h264 = false; bool supports_video_encode_h265 = false; #endif - bool supports_pipeline_creation_cache_control = false; - bool supports_format_feature_flags2 = false; bool supports_external = false; - bool supports_image_format_list = false; - bool supports_shader_float_control = false; bool supports_tooling_info = false; bool supports_hdr_metadata = false; bool supports_swapchain_colorspace = false; bool supports_surface_maintenance1 = false; - bool supports_spirv_1_4 = false; - // Vulkan 1.1 core VkPhysicalDeviceFeatures enabled_features = {}; - VkPhysicalDeviceMultiviewFeatures multiview_features = {}; - VkPhysicalDeviceShaderDrawParametersFeatures shader_draw_parameters_features = {}; - VkPhysicalDeviceSamplerYcbcrConversionFeatures sampler_ycbcr_conversion_features = {}; - VkPhysicalDeviceMultiviewProperties multiview_properties = {}; - VkPhysicalDeviceSubgroupProperties subgroup_properties = {}; + + VkPhysicalDeviceVulkan11Features vk11_features = {}; + VkPhysicalDeviceVulkan12Features vk12_features = {}; + VkPhysicalDeviceVulkan13Features vk13_features = {}; + VkPhysicalDeviceVulkan11Properties vk11_props = {}; + VkPhysicalDeviceVulkan12Properties vk12_props = {}; + VkPhysicalDeviceVulkan13Properties vk13_props = {}; // KHR - VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features = {}; VkPhysicalDevicePerformanceQueryFeaturesKHR performance_query_features = {}; - VkPhysicalDeviceDriverPropertiesKHR driver_properties = {}; - VkPhysicalDeviceSynchronization2FeaturesKHR sync2_features = {}; VkPhysicalDevicePresentIdFeaturesKHR present_id_features = {}; VkPhysicalDevicePresentWaitFeaturesKHR present_wait_features = {}; - VkPhysicalDevice8BitStorageFeaturesKHR storage_8bit_features = {}; - VkPhysicalDevice16BitStorageFeaturesKHR storage_16bit_features = {}; - VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_features = {}; - VkPhysicalDeviceFloatControlsPropertiesKHR float_control_properties = {}; - VkPhysicalDeviceBufferDeviceAddressFeaturesKHR buffer_device_address_features = {}; - VkPhysicalDeviceIDProperties id_properties = {}; - VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR shader_subgroup_extended_types_features = {}; - VkPhysicalDeviceIndexTypeUint8FeaturesEXT index_type_uint8_features = {}; // EXT VkPhysicalDeviceExternalMemoryHostPropertiesEXT host_memory_properties = {}; - VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroup_size_control_features = {}; - VkPhysicalDeviceSubgroupSizeControlPropertiesEXT subgroup_size_control_properties = {}; - VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features = {}; - VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT demote_to_helper_invocation_features = {}; - VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalar_block_features = {}; - VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR ubo_std430_features = {}; - VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing_features = {}; - VkPhysicalDeviceDescriptorIndexingPropertiesEXT descriptor_indexing_properties = {}; VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservative_rasterization_properties = {}; VkPhysicalDeviceMemoryPriorityFeaturesEXT memory_priority_features = {}; VkPhysicalDeviceASTCDecodeFeaturesEXT astc_decode_features = {}; - VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT astc_hdr_features = {}; - VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT pipeline_creation_cache_control_features = {}; VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = {}; VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT pageable_device_local_memory_features = {}; VkPhysicalDeviceMeshShaderFeaturesEXT mesh_shader_features = {}; VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties = {}; + VkPhysicalDeviceIndexTypeUint8FeaturesEXT index_type_uint8_features = {}; // Vendor VkPhysicalDeviceComputeShaderDerivativesFeaturesNV compute_shader_derivative_features = {}; @@ -132,12 +105,20 @@ struct DeviceFeatures VkPhysicalDeviceDeviceGeneratedCommandsComputeFeaturesNV device_generated_commands_compute_features = {}; VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV device_generated_commands_properties = {}; + // Fallback feature structs (Vulkan 1.1) + VkPhysicalDeviceHostQueryResetFeatures host_query_reset_features = {}; + + VkDriverId driver_id = {}; + // References Vulkan::Context. const VkPhysicalDeviceFeatures2 *pdf2 = nullptr; const char * const * instance_extensions = nullptr; uint32_t num_instance_extensions = 0; const char * const * device_extensions = nullptr; uint32_t num_device_extensions = 0; + + uint32_t instance_api_core_version = VK_API_VERSION_1_1; + uint32_t device_api_core_version = VK_API_VERSION_1_1; }; enum VendorID @@ -360,7 +341,6 @@ class Context VkPhysicalDevice gpu = VK_NULL_HANDLE; VolkDeviceTable device_table = {}; SystemHandles handles; - VkPhysicalDeviceProperties gpu_props = {}; VkPhysicalDeviceMemoryProperties mem_props = {}; @@ -390,8 +370,8 @@ class Context #endif std::function message_callback; - void destroy(); - void check_descriptor_indexing_features(); + void destroy_instance(); + void destroy_device(); bool physical_device_supports_surface_and_profile(VkPhysicalDevice candidate_gpu, VkSurfaceKHR surface) const; @@ -404,6 +384,8 @@ class Context bool init_profile(); VkResult create_instance_from_profile(const VkInstanceCreateInfo &info, VkInstance *pInstance); VkResult create_device_from_profile(const VkDeviceCreateInfo &info, VkDevice *pDevice); + + VkApplicationInfo get_promoted_application_info() const; }; using ContextHandle = Util::IntrusivePtr; diff --git a/vulkan/descriptor_set.cpp b/vulkan/descriptor_set.cpp index 33984d012..c8b380fe9 100644 --- a/vulkan/descriptor_set.cpp +++ b/vulkan/descriptor_set.cpp @@ -45,7 +45,7 @@ DescriptorSetAllocator::DescriptorSetAllocator(Hash hash, Device *device_, const per_thread.emplace_back(new PerThread); } - if (bindless && !device->get_device_features().supports_descriptor_indexing) + if (bindless && !device->get_device_features().vk12_features.descriptorIndexing) { LOGE("Cannot support descriptor indexing on this device.\n"); return; diff --git a/vulkan/device.cpp b/vulkan/device.cpp index a20c36e6c..b28d186fa 100644 --- a/vulkan/device.cpp +++ b/vulkan/device.cpp @@ -97,9 +97,9 @@ Device::Device() cookie.store(0); } -Semaphore Device::request_semaphore(VkSemaphoreTypeKHR type, VkSemaphore vk_semaphore, bool transfer_ownership) +Semaphore Device::request_semaphore(VkSemaphoreType type, VkSemaphore vk_semaphore, bool transfer_ownership) { - if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR && !ext.timeline_semaphore_features.timelineSemaphore) + if (type == VK_SEMAPHORE_TYPE_TIMELINE && !ext.vk12_features.timelineSemaphore) { LOGE("Timeline semaphores not supported.\n"); return Semaphore{}; @@ -107,17 +107,17 @@ Semaphore Device::request_semaphore(VkSemaphoreTypeKHR type, VkSemaphore vk_sema if (vk_semaphore == VK_NULL_HANDLE) { - if (type == VK_SEMAPHORE_TYPE_BINARY_KHR) + if (type == VK_SEMAPHORE_TYPE_BINARY) { LOCK(); vk_semaphore = managers.semaphore.request_cleared_semaphore(); } else { - VkSemaphoreTypeCreateInfoKHR type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR }; + VkSemaphoreTypeCreateInfo type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; VkSemaphoreCreateInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; info.pNext = &type_info; - type_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR; + type_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; type_info.initialValue = 0; if (table->vkCreateSemaphore(device, &info, nullptr, &vk_semaphore) != VK_SUCCESS) { @@ -128,7 +128,7 @@ Semaphore Device::request_semaphore(VkSemaphoreTypeKHR type, VkSemaphore vk_sema transfer_ownership = true; } - if (type == VK_SEMAPHORE_TYPE_BINARY_KHR) + if (type == VK_SEMAPHORE_TYPE_BINARY) { Semaphore ptr(handle_pool.semaphores.allocate(this, vk_semaphore, false, transfer_ownership)); return ptr; @@ -143,16 +143,16 @@ Semaphore Device::request_semaphore(VkSemaphoreTypeKHR type, VkSemaphore vk_sema Semaphore Device::request_timeline_semaphore_as_binary(const SemaphoreHolder &holder, uint64_t value) { - VK_ASSERT(holder.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR); + VK_ASSERT(holder.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE); VK_ASSERT(holder.is_proxy_timeline()); Semaphore ptr(handle_pool.semaphores.allocate(this, value, holder.get_semaphore(), false)); return ptr; } -Semaphore Device::request_semaphore_external(VkSemaphoreTypeKHR type, +Semaphore Device::request_semaphore_external(VkSemaphoreType type, VkExternalSemaphoreHandleTypeFlagBits handle_type) { - if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR && !ext.timeline_semaphore_features.timelineSemaphore) + if (type == VK_SEMAPHORE_TYPE_TIMELINE && !ext.vk12_features.timelineSemaphore) { LOGE("Timeline semaphores not supported.\n"); return Semaphore{}; @@ -164,7 +164,7 @@ Semaphore Device::request_semaphore_external(VkSemaphoreTypeKHR type, return Semaphore{}; } - VkSemaphoreTypeCreateInfoKHR type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR }; + VkSemaphoreTypeCreateInfo type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; type_info.semaphoreType = type; VkExternalSemaphoreFeatureFlags features; @@ -175,7 +175,7 @@ Semaphore Device::request_semaphore_external(VkSemaphoreTypeKHR type, // Workaround AMD Windows bug where it reports TIMELINE as not supported. // D3D12_FENCE used to be BINARY type before timelines were introduced to Vulkan. - if (type != VK_SEMAPHORE_TYPE_BINARY_KHR && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT) + if (type != VK_SEMAPHORE_TYPE_BINARY && handle_type != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT) info.pNext = &type_info; vkGetPhysicalDeviceExternalSemaphoreProperties(gpu, &info, &props); @@ -198,7 +198,7 @@ Semaphore Device::request_semaphore_external(VkSemaphoreTypeKHR type, info.pNext = &export_info; } - if (type != VK_SEMAPHORE_TYPE_BINARY_KHR) + if (type != VK_SEMAPHORE_TYPE_BINARY) { type_info.pNext = info.pNext; info.pNext = &type_info; @@ -211,7 +211,7 @@ Semaphore Device::request_semaphore_external(VkSemaphoreTypeKHR type, return Semaphore{}; } - if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR) + if (type == VK_SEMAPHORE_TYPE_TIMELINE) { Semaphore ptr(handle_pool.semaphores.allocate(this, 0, semaphore, true)); ptr->set_external_object_compatible(handle_type, features); @@ -867,27 +867,19 @@ void Device::init_workarounds() if (gpu_props.vendorID == VENDOR_ID_ARM) { LOGW("Workaround applied: Emulating events as pipeline barriers.\n"); - - // Both are performance related workarounds. workarounds.emulate_event_as_pipeline_barrier = true; - - if (ext.timeline_semaphore_features.timelineSemaphore) - { - LOGW("Workaround applied: Split binary timeline semaphores.\n"); - workarounds.split_binary_timeline_semaphores = true; - } } - else if (ext.driver_properties.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) + else if (ext.driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { LOGW("Disabling pipeline cache control.\n"); workarounds.broken_pipeline_cache_control = true; } - else if (((ext.driver_properties.driverID == VK_DRIVER_ID_MESA_RADV || - ext.driver_properties.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA || - ext.driver_properties.driverID == VK_DRIVER_ID_MESA_TURNIP) && + else if (((ext.driver_id == VK_DRIVER_ID_MESA_RADV || + ext.driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA || + ext.driver_id == VK_DRIVER_ID_MESA_TURNIP) && gpu_props.driverVersion < VK_MAKE_VERSION(23, 1, 0)) || - ext.driver_properties.driverID == VK_DRIVER_ID_AMD_PROPRIETARY || - ext.driver_properties.driverID == VK_DRIVER_ID_AMD_OPEN_SOURCE) + ext.driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || + ext.driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE) { LOGW("Enabling workaround for sync2 access mask bugs.\n"); // https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21271 @@ -1028,13 +1020,13 @@ void Device::wait_shader_caches() void Device::init_timeline_semaphores() { - if (!ext.timeline_semaphore_features.timelineSemaphore) + if (!ext.vk12_features.timelineSemaphore) return; - VkSemaphoreTypeCreateInfoKHR type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR }; + VkSemaphoreTypeCreateInfo type_info = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; VkSemaphoreCreateInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; info.pNext = &type_info; - type_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR; + type_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; type_info.initialValue = 0; for (int i = 0; i < QUEUE_INDEX_COUNT; i++) @@ -1376,7 +1368,7 @@ void Device::submit_empty_inner(QueueIndices physical_type, InternalFence *fence // Add external wait semaphores. Helper::WaitSemaphores wait_semaphores; - Helper::BatchComposer composer(get_workarounds().split_binary_timeline_semaphores); + Helper::BatchComposer composer; collect_wait_semaphores(data, wait_semaphores); composer.add_wait_submissions(wait_semaphores); @@ -1391,7 +1383,7 @@ void Device::submit_empty_inner(QueueIndices physical_type, InternalFence *fence timeline_semaphore, timeline_value, fence, semaphore_count, semaphores); - VkFence cleared_fence = fence && !ext.timeline_semaphore_features.timelineSemaphore ? + VkFence cleared_fence = fence && !ext.vk12_features.timelineSemaphore ? managers.fence.request_cleared_fence() : VK_NULL_HANDLE; if (fence) @@ -1403,9 +1395,9 @@ void Device::submit_empty_inner(QueueIndices physical_type, InternalFence *fence register_time_interval_nolock("CPU", std::move(start_ts), std::move(end_ts), "submit"); if (result != VK_SUCCESS) - LOGE("vkQueueSubmit2KHR failed (code: %d).\n", int(result)); + LOGE("vkQueueSubmit2 failed (code: %d).\n", int(result)); - if (!ext.timeline_semaphore_features.timelineSemaphore) + if (!ext.vk12_features.timelineSemaphore) data.need_fence = true; } @@ -1433,7 +1425,7 @@ void Device::collect_wait_semaphores(QueueData &data, Helper::WaitSemaphores &se { auto &semaphore = data.wait_semaphores[i]; auto vk_semaphore = semaphore->consume(); - if (semaphore->get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR) + if (semaphore->get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE) { info.semaphore = vk_semaphore; info.stageMask = data.wait_stages[i]; @@ -1458,34 +1450,7 @@ void Device::collect_wait_semaphores(QueueData &data, Helper::WaitSemaphores &se data.wait_semaphores.clear(); } -static bool has_timeline_semaphore(const SmallVector &sems) -{ - return std::find_if(sems.begin(), sems.end(), [](const VkSemaphoreSubmitInfo &info) { - return info.value != 0; - }) != sems.end(); -} - -static bool has_binary_semaphore(const SmallVector &sems) -{ - return std::find_if(sems.begin(), sems.end(), [](const VkSemaphoreSubmitInfo &info) { - return info.value != 0; - }) != sems.end(); -} - -bool Helper::BatchComposer::has_timeline_semaphore_in_batch(unsigned index) const -{ - return has_timeline_semaphore(waits[index]) || - has_timeline_semaphore(signals[index]); -} - -bool Helper::BatchComposer::has_binary_semaphore_in_batch(unsigned index) const -{ - return has_binary_semaphore(waits[index]) || - has_binary_semaphore(signals[index]); -} - -Helper::BatchComposer::BatchComposer(bool split_binary_timeline_semaphores_) - : split_binary_timeline_semaphores(split_binary_timeline_semaphores_) +Helper::BatchComposer::BatchComposer() { submits.emplace_back(); } @@ -1505,20 +1470,10 @@ void Helper::BatchComposer::add_wait_submissions(WaitSemaphores &sem) auto &w = waits[submit_index]; if (!sem.binary_waits.empty()) - { - // Split binary semaphore waits from timeline semaphore waits to work around driver bugs if needed. - if (split_binary_timeline_semaphores && has_timeline_semaphore_in_batch(submit_index)) - begin_batch(); w.insert(w.end(), sem.binary_waits.begin(), sem.binary_waits.end()); - } if (!sem.timeline_waits.empty()) - { - // Split binary semaphore waits from timeline semaphore waits to work around driver bugs if needed. - if (split_binary_timeline_semaphores && has_binary_semaphore_in_batch(submit_index)) - begin_batch(); w.insert(w.end(), sem.timeline_waits.begin(), sem.timeline_waits.end()); - } } SmallVector & @@ -1573,13 +1528,6 @@ void Helper::BatchComposer::add_command_buffer(VkCommandBuffer cmd) void Helper::BatchComposer::add_signal_semaphore(VkSemaphore sem, VkPipelineStageFlags2 stages, uint64_t timeline) { - if (split_binary_timeline_semaphores) - { - if ((timeline == 0 && has_timeline_semaphore_in_batch(submit_index)) || - (timeline != 0 && has_binary_semaphore_in_batch(submit_index))) - begin_batch(); - } - VkSemaphoreSubmitInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; info.semaphore = sem; info.stageMask = stages; @@ -1592,14 +1540,7 @@ void Helper::BatchComposer::add_wait_semaphore(SemaphoreHolder &sem, VkPipelineS if (!cmds[submit_index].empty() || !signals[submit_index].empty()) begin_batch(); - bool is_timeline = sem.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR; - - if (split_binary_timeline_semaphores) - { - if ((!is_timeline && has_timeline_semaphore_in_batch(submit_index)) || - (is_timeline && has_binary_semaphore_in_batch(submit_index))) - begin_batch(); - } + bool is_timeline = sem.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE; VkSemaphoreSubmitInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; info.semaphore = sem.get_semaphore(); @@ -1613,9 +1554,6 @@ void Helper::BatchComposer::add_wait_semaphore(VkSemaphore sem, VkPipelineStageF if (!cmds[submit_index].empty() || !signals[submit_index].empty()) begin_batch(); - if (split_binary_timeline_semaphores && has_timeline_semaphore_in_batch(submit_index)) - begin_batch(); - VkSemaphoreSubmitInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; info.semaphore = sem; info.stageMask = stage; @@ -1636,7 +1574,7 @@ void Device::emit_queue_signals(Helper::BatchComposer &composer, external_semaphore->signal_external(); composer.add_signal_semaphore(external_semaphore->get_semaphore(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - external_semaphore->get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE_KHR ? + external_semaphore->get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE ? external_semaphore->get_timeline_value() : 0); // Make sure we observe that the external semaphore is signalled before fences are signalled. @@ -1644,7 +1582,7 @@ void Device::emit_queue_signals(Helper::BatchComposer &composer, } // Add external signal semaphores. - if (ext.timeline_semaphore_features.timelineSemaphore) + if (ext.vk12_features.timelineSemaphore) { // Signal once and distribute the timeline value to all. composer.add_signal_semaphore(sem, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, timeline); @@ -1683,15 +1621,15 @@ void Device::emit_queue_signals(Helper::BatchComposer &composer, VkResult Device::queue_submit(VkQueue queue, uint32_t count, const VkSubmitInfo2 *submits, VkFence fence) { - if (ext.sync2_features.synchronization2) + if (ext.vk13_features.synchronization2) { - return table->vkQueueSubmit2KHR(queue, count, submits, fence); + return table->vkQueueSubmit2(queue, count, submits, fence); } else { for (uint32_t submit_index = 0; submit_index < count; submit_index++) { - VkTimelineSemaphoreSubmitInfoKHR timeline = { VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR }; + VkTimelineSemaphoreSubmitInfo timeline = { VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO }; const auto &submit = submits[submit_index]; VkSubmitInfo sub = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; bool need_timeline = false; @@ -1765,19 +1703,7 @@ VkResult Device::submit_batches(Helper::BatchComposer &composer, VkQueue queue, if (queue_lock_callback) queue_lock_callback(); - VkResult result = VK_SUCCESS; - if (get_workarounds().split_binary_timeline_semaphores) - { - for (auto &submit : submits) - { - bool last_submit = &submit == &submits.back(); - result = queue_submit(queue, 1, &submit, last_submit ? fence : VK_NULL_HANDLE); - if (result != VK_SUCCESS) - break; - } - } - else - result = queue_submit(queue, uint32_t(submits.size()), submits.data(), fence); + VkResult result = queue_submit(queue, uint32_t(submits.size()), submits.data(), fence); if (ImplementationQuirks::get().queue_wait_on_submission) table->vkQueueWaitIdle(queue); @@ -1811,7 +1737,7 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence, VkQueue queue = queue_info.queues[physical_type]; frame().timeline_fences[physical_type] = data.current_timeline; - Helper::BatchComposer composer(workarounds.split_binary_timeline_semaphores); + Helper::BatchComposer composer; Helper::WaitSemaphores wait_semaphores; collect_wait_semaphores(data, wait_semaphores); @@ -1834,7 +1760,7 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence, { VK_ASSERT(wsi.acquire->is_signalled()); composer.add_wait_semaphore(*wsi.acquire, wsi_stages); - if (wsi.acquire->get_semaphore_type() == VK_SEMAPHORE_TYPE_BINARY_KHR) + if (wsi.acquire->get_semaphore_type() == VK_SEMAPHORE_TYPE_BINARY) { if (wsi.acquire->is_external_object_compatible()) frame().destroyed_semaphores.push_back(wsi.acquire->get_semaphore()); @@ -1864,7 +1790,7 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence, } } - VkFence cleared_fence = fence && !ext.timeline_semaphore_features.timelineSemaphore ? + VkFence cleared_fence = fence && !ext.vk12_features.timelineSemaphore ? managers.fence.request_cleared_fence() : VK_NULL_HANDLE; @@ -1887,10 +1813,10 @@ void Device::submit_queue(QueueIndices physical_type, InternalFence *fence, register_time_interval_nolock("CPU", std::move(start_ts), std::move(end_ts), "submit"); if (result != VK_SUCCESS) - LOGE("vkQueueSubmit2KHR failed (code: %d).\n", int(result)); + LOGE("vkQueueSubmit2 failed (code: %d).\n", int(result)); submissions.clear(); - if (!ext.timeline_semaphore_features.timelineSemaphore) + if (!ext.vk12_features.timelineSemaphore) data.need_fence = true; } @@ -2830,9 +2756,9 @@ void Device::PerFrame::begin() } } - if (device.get_device_features().timeline_semaphore_features.timelineSemaphore && has_timeline) + if (device.get_device_features().vk12_features.timelineSemaphore && has_timeline) { - VkSemaphoreWaitInfoKHR info = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR }; + VkSemaphoreWaitInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO }; VkSemaphore sems[QUEUE_INDEX_COUNT]; uint64_t values[QUEUE_INDEX_COUNT]; for (int i = 0; i < QUEUE_INDEX_COUNT; i++) @@ -2849,7 +2775,7 @@ void Device::PerFrame::begin() { info.pSemaphores = sems; info.pValues = values; - table.vkWaitSemaphoresKHR(vkdevice, &info, UINT64_MAX); + table.vkWaitSemaphores(vkdevice, &info, UINT64_MAX); } } @@ -3238,7 +3164,7 @@ class ImageResourceHolder { if (ycbcr_conversion) { - if (!device->get_device_features().sampler_ycbcr_conversion_features.samplerYcbcrConversion) + if (!device->get_device_features().vk11_features.samplerYcbcrConversion) return false; conversion = { VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO }; conversion.conversion = ycbcr_conversion->get_conversion(); @@ -3882,7 +3808,7 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea if (info.mipLevels == 0) info.mipLevels = image_num_miplevels(info.extent); - VkImageFormatListCreateInfoKHR format_info = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR }; + VkImageFormatListCreateInfo format_info = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO }; VkFormat view_formats[2]; format_info.pViewFormats = view_formats; format_info.viewFormatCount = 2; @@ -3896,7 +3822,7 @@ ImageHandle Device::create_image_from_staging_buffer(const ImageCreateInfo &crea create_unorm_srgb_views = true; const auto *input_format_list = static_cast(info.pNext); - while (input_format_list && input_format_list->sType != VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR) + while (input_format_list && input_format_list->sType != VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO) input_format_list = static_cast(input_format_list->pNext); if (ext.supports_image_format_list && !input_format_list) @@ -4359,7 +4285,7 @@ SamplerHandle Device::create_sampler(const SamplerCreateInfo &sampler_info) BindlessDescriptorPoolHandle Device::create_bindless_descriptor_pool(BindlessResourceType type, unsigned num_sets, unsigned num_descriptors) { - if (!ext.supports_descriptor_indexing) + if (!ext.vk12_features.descriptorIndexing) return BindlessDescriptorPoolHandle{nullptr}; DescriptorSetLayout layout; @@ -4445,8 +4371,8 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_ VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; info.size = create_info.size; info.usage = create_info.usage; - if (get_device_features().buffer_device_address_features.bufferDeviceAddress) - info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR; + if (get_device_features().vk12_features.bufferDeviceAddress) + info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.pNext = &external_info; @@ -4501,10 +4427,10 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_ alloc_info.memoryTypeIndex = memory_type; VkMemoryAllocateFlagsInfo flags_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO }; - if (get_device_features().buffer_device_address_features.bufferDeviceAddress) + if (get_device_features().vk12_features.bufferDeviceAddress) { alloc_info.pNext = &flags_info; - flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR; + flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT; } VkImportMemoryHostPointerInfoEXT import = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT }; @@ -4541,11 +4467,11 @@ BufferHandle Device::create_imported_host_buffer(const BufferCreateInfo &create_ } VkDeviceAddress bda = 0; - if (get_device_features().buffer_device_address_features.bufferDeviceAddress) + if (get_device_features().vk12_features.bufferDeviceAddress) { - VkBufferDeviceAddressInfoKHR bda_info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR }; + VkBufferDeviceAddressInfo bda_info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO }; bda_info.buffer = buffer; - bda = table->vkGetBufferDeviceAddressKHR(device, &bda_info); + bda = table->vkGetBufferDeviceAddress(device, &bda_info); } BufferHandle handle(handle_pool.buffers.allocate(this, buffer, allocation, create_info, bda)); @@ -4574,8 +4500,8 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; info.size = create_info.size; info.usage = create_info.usage | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - if (get_device_features().buffer_device_address_features.bufferDeviceAddress) - info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR; + if (get_device_features().vk12_features.bufferDeviceAddress) + info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; uint32_t sharing_indices[QUEUE_INDEX_COUNT]; @@ -4716,11 +4642,11 @@ BufferHandle Device::create_buffer(const BufferCreateInfo &create_info, const vo tmpinfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; VkDeviceAddress bda = 0; - if (get_device_features().buffer_device_address_features.bufferDeviceAddress) + if (get_device_features().vk12_features.bufferDeviceAddress) { - VkBufferDeviceAddressInfoKHR bda_info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR }; + VkBufferDeviceAddressInfo bda_info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO }; bda_info.buffer = buffer; - bda = table->vkGetBufferDeviceAddressKHR(device, &bda_info); + bda = table->vkGetBufferDeviceAddress(device, &bda_info); } BufferHandle handle(handle_pool.buffers.allocate(this, buffer, allocation, tmpinfo, bda)); @@ -4774,25 +4700,25 @@ bool Device::memory_type_is_host_visible(uint32_t type) const return (mem_props.memoryTypes[type].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0; } -static VkFormatFeatureFlags2KHR promote_storage_usage(const DeviceFeatures &features, VkFormat format, - VkFormatFeatureFlags2KHR supported) +static VkFormatFeatureFlags2 promote_storage_usage(const DeviceFeatures &features, VkFormat format, + VkFormatFeatureFlags2 supported) { - if ((supported & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR) != 0 && + if ((supported & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT) != 0 && format_supports_storage_image_read_write_without_format(format)) { if (features.enabled_features.shaderStorageImageReadWithoutFormat) - supported |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR; + supported |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT; if (features.enabled_features.shaderStorageImageWriteWithoutFormat) - supported |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR; + supported |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; } return supported; } -void Device::get_format_properties(VkFormat format, VkFormatProperties3KHR *properties3) const +void Device::get_format_properties(VkFormat format, VkFormatProperties3 *properties3) const { VkFormatProperties2 properties2 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 }; - VK_ASSERT(properties3->sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR); + VK_ASSERT(properties3->sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3); if (ext.supports_format_feature_flags2) { @@ -4835,9 +4761,9 @@ bool Device::get_image_format_properties(VkFormat format, VkImageType type, VkIm return res == VK_SUCCESS; } -bool Device::image_format_is_supported(VkFormat format, VkFormatFeatureFlags2KHR required, VkImageTiling tiling) const +bool Device::image_format_is_supported(VkFormat format, VkFormatFeatureFlags2 required, VkImageTiling tiling) const { - VkFormatProperties3KHR props3 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR }; + VkFormatProperties3 props3 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 }; get_format_properties(format, &props3); auto flags = tiling == VK_IMAGE_TILING_OPTIMAL ? props3.optimalTilingFeatures : props3.linearTilingFeatures; return (flags & required) == required; @@ -5280,30 +5206,30 @@ bool Device::supports_subgroup_size_log2(bool subgroup_full_group, uint8_t subgr return false; } - if (!ext.subgroup_size_control_features.subgroupSizeControl) + if (!ext.vk13_features.subgroupSizeControl) return false; - if (subgroup_full_group && !ext.subgroup_size_control_features.computeFullSubgroups) + if (subgroup_full_group && !ext.vk13_features.computeFullSubgroups) return false; uint32_t min_subgroups = 1u << subgroup_minimum_size_log2; uint32_t max_subgroups = 1u << subgroup_maximum_size_log2; - bool full_range = min_subgroups <= ext.subgroup_size_control_properties.minSubgroupSize && - max_subgroups >= ext.subgroup_size_control_properties.maxSubgroupSize; + bool full_range = min_subgroups <= ext.vk13_props.minSubgroupSize && + max_subgroups >= ext.vk13_props.maxSubgroupSize; // We can use VARYING size. if (full_range) return true; - if (min_subgroups > ext.subgroup_size_control_properties.maxSubgroupSize || - max_subgroups < ext.subgroup_size_control_properties.minSubgroupSize) + if (min_subgroups > ext.vk13_props.maxSubgroupSize || + max_subgroups < ext.vk13_props.minSubgroupSize) { // No overlap in requested subgroup size and available subgroup size. return false; } // We need requiredSubgroupSizeStages support here. - return (ext.subgroup_size_control_properties.requiredSubgroupSizeStages & stage) != 0; + return (ext.vk13_props.requiredSubgroupSizeStages & stage) != 0; } const QueueInfo &Device::get_queue_info() const diff --git a/vulkan/device.hpp b/vulkan/device.hpp index 09613ad76..f17c5c347 100644 --- a/vulkan/device.hpp +++ b/vulkan/device.hpp @@ -129,7 +129,7 @@ class BatchComposer public: enum { MaxSubmissions = 8 }; - explicit BatchComposer(bool split_binary_timeline_semaphores); + BatchComposer(); void add_wait_submissions(WaitSemaphores &sem); void add_wait_semaphore(SemaphoreHolder &sem, VkPipelineStageFlags2 stage); void add_wait_semaphore(VkSemaphore sem, VkPipelineStageFlags2 stage); @@ -148,10 +148,6 @@ class BatchComposer Util::SmallVector cmds[MaxSubmissions]; unsigned submit_index = 0; - bool split_binary_timeline_semaphores = false; - - bool has_timeline_semaphore_in_batch(unsigned index) const; - bool has_binary_semaphore_in_batch(unsigned index) const; }; } diff --git a/vulkan/managers/shader_manager.cpp b/vulkan/managers/shader_manager.cpp index 809569da3..b70262757 100644 --- a/vulkan/managers/shader_manager.cpp +++ b/vulkan/managers/shader_manager.cpp @@ -86,8 +86,8 @@ bool ShaderTemplate::init() GRANITE_SCOPED_TIMELINE_EVENT_FILE(device->get_system_handles().timeline_trace_file, "glsl-preprocess"); compiler = std::make_unique(*device->get_system_handles().filesystem); - compiler->set_target(device->get_device_features().supports_spirv_1_4 ? - Granite::Target::Vulkan11_Spirv14 : Granite::Target::Vulkan11); + compiler->set_target(device->get_device_features().device_api_core_version >= VK_API_VERSION_1_3 ? + Granite::Target::Vulkan13 : Granite::Target::Vulkan11); if (!compiler->set_source_from_file(path, Granite::Stage(force_stage))) return false; compiler->set_include_directories(&include_directories); @@ -287,8 +287,8 @@ void ShaderTemplate::recompile() if (!device->get_system_handles().filesystem) return; auto newcompiler = std::make_unique(*device->get_system_handles().filesystem); - newcompiler->set_target(device->get_device_features().supports_spirv_1_4 ? - Granite::Target::Vulkan11_Spirv14 : Granite::Target::Vulkan11); + newcompiler->set_target(device->get_device_features().device_api_core_version >= VK_API_VERSION_1_3 ? + Granite::Target::Vulkan13 : Granite::Target::Vulkan11); if (!newcompiler->set_source_from_file(path, Granite::Stage(force_stage))) return; newcompiler->set_include_directories(&include_directories); diff --git a/vulkan/memory_allocator.cpp b/vulkan/memory_allocator.cpp index bc1568639..c4fba5efb 100644 --- a/vulkan/memory_allocator.cpp +++ b/vulkan/memory_allocator.cpp @@ -717,10 +717,10 @@ bool DeviceAllocator::internal_allocate( info.pNext = &priority_info; } - if (device->get_device_features().buffer_device_address_features.bufferDeviceAddress && + if (device->get_device_features().vk12_features.bufferDeviceAddress && allocation_mode_supports_bda(mode)) { - flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR; + flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT; flags_info.pNext = info.pNext; info.pNext = &flags_info; } diff --git a/vulkan/query_pool.cpp b/vulkan/query_pool.cpp index cf6bfe37c..c6cc8b5fd 100644 --- a/vulkan/query_pool.cpp +++ b/vulkan/query_pool.cpp @@ -253,7 +253,7 @@ bool PerformanceQueryPool::init_counters(const std::vector &counter return false; } - if (!device->get_device_features().host_query_reset_features.hostQueryReset) + if (!device->get_device_features().vk12_features.hostQueryReset) { LOGE("Device does not support host query reset.\n"); return false; @@ -321,7 +321,8 @@ QueryPool::QueryPool(Device *device_) : device(device_) , table(device_->get_device_table()) { - supports_timestamp = device->get_gpu_properties().limits.timestampComputeAndGraphics; + supports_timestamp = device->get_gpu_properties().limits.timestampComputeAndGraphics && + device->get_device_features().vk12_features.hostQueryReset; // Ignore timestampValidBits and friends for now. if (supports_timestamp) @@ -355,8 +356,7 @@ void QueryPool::begin() for (unsigned j = 0; j < pool.index; j++) pool.cookies[j]->signal_timestamp_ticks(pool.query_results[j]); - if (device->get_device_features().host_query_reset_features.hostQueryReset) - table.vkResetQueryPoolEXT(device->get_device(), pool.pool, 0, pool.index); + table.vkResetQueryPool(device->get_device(), pool.pool, 0, pool.index); } pool_index = 0; @@ -377,8 +377,7 @@ void QueryPool::add_pool() pool.query_results.resize(pool.size); pool.cookies.resize(pool.size); - if (device->get_device_features().host_query_reset_features.hostQueryReset) - table.vkResetQueryPoolEXT(device->get_device(), pool.pool, 0, pool.size); + table.vkResetQueryPool(device->get_device(), pool.pool, 0, pool.size); pools.push_back(std::move(pool)); } @@ -404,11 +403,8 @@ QueryPoolHandle QueryPool::write_timestamp(VkCommandBuffer cmd, VkPipelineStageF auto cookie = QueryPoolHandle(device->handle_pool.query.allocate(device, true)); pool.cookies[pool.index] = cookie; - if (!device->get_device_features().host_query_reset_features.hostQueryReset) - table.vkCmdResetQueryPool(cmd, pool.pool, pool.index, 1); - - if (device->get_device_features().sync2_features.synchronization2) - table.vkCmdWriteTimestamp2KHR(cmd, stage, pool.pool, pool.index); + if (device->get_device_features().vk13_features.synchronization2) + table.vkCmdWriteTimestamp2(cmd, stage, pool.pool, pool.index); else { table.vkCmdWriteTimestamp(cmd, static_cast(convert_vk_src_stage2(stage)), diff --git a/vulkan/quirks.hpp b/vulkan/quirks.hpp index a1165c1dd..64489b550 100644 --- a/vulkan/quirks.hpp +++ b/vulkan/quirks.hpp @@ -44,7 +44,6 @@ struct ImplementationQuirks struct ImplementationWorkarounds { bool emulate_event_as_pipeline_barrier = false; - bool split_binary_timeline_semaphores = false; bool broken_pipeline_cache_control = false; bool force_host_cached = false; bool force_sync1_access = false; diff --git a/vulkan/render_pass.cpp b/vulkan/render_pass.cpp index 651ed08d6..e31c2e4a8 100644 --- a/vulkan/render_pass.cpp +++ b/vulkan/render_pass.cpp @@ -34,7 +34,7 @@ using namespace Util; namespace Vulkan { -void RenderPass::setup_subpasses(const VkRenderPassCreateInfo2KHR &create_info) +void RenderPass::setup_subpasses(const VkRenderPassCreateInfo2 &create_info) { auto *attachments = create_info.pAttachments; @@ -78,7 +78,7 @@ void RenderPass::setup_subpasses(const VkRenderPassCreateInfo2KHR &create_info) } } -RenderPass::RenderPass(Hash hash, Device *device_, const VkRenderPassCreateInfo2KHR &create_info) +RenderPass::RenderPass(Hash hash, Device *device_, const VkRenderPassCreateInfo2 &create_info) : IntrusiveHashMapEnabled(hash) , device(device_) { @@ -105,7 +105,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const VkRenderPassCreateInfo2 #ifdef VULKAN_DEBUG LOGI("Creating render pass.\n"); #endif - if (table.vkCreateRenderPass2KHR(device->get_device(), &create_info, nullptr, &render_pass) != VK_SUCCESS) + if (table.vkCreateRenderPass2(device->get_device(), &create_info, nullptr, &render_pass) != VK_SUCCESS) LOGE("Failed to create render pass."); #ifdef GRANITE_VULKAN_FOSSILIZE @@ -146,7 +146,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) // First, set up attachment descriptions. const unsigned num_attachments = info.num_color_attachments + (info.depth_stencil ? 1 : 0); - VkAttachmentDescription2KHR attachments[VULKAN_NUM_ATTACHMENTS + 1]; + VkAttachmentDescription2 attachments[VULKAN_NUM_ATTACHMENTS + 1]; uint32_t implicit_transitions = 0; uint32_t implicit_bottom_of_pipe = 0; @@ -195,7 +195,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) color_attachments[i] = info.color_attachments[i]->get_format(); auto &image = info.color_attachments[i]->get_image(); auto &att = attachments[i]; - att = { VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR }; + att = { VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 }; att.format = color_attachments[i]; att.samples = image.get_create_info().samples; att.loadOp = color_load_op(i); @@ -250,7 +250,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) { auto &image = info.depth_stencil->get_image(); auto &att = attachments[info.num_color_attachments]; - att = { VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR }; + att = { VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 }; att.format = depth_stencil; att.samples = image.get_create_info().samples; att.loadOp = ds_load_op; @@ -300,10 +300,10 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) att.initialLayout = depth_stencil_layout; } - Util::StackAllocator reference_allocator; + Util::StackAllocator reference_allocator; Util::StackAllocator preserve_allocator; - std::vector subpasses(num_subpasses); - std::vector external_dependencies; + std::vector subpasses(num_subpasses); + std::vector external_dependencies; for (unsigned i = 0; i < num_subpasses; i++) { @@ -313,7 +313,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) auto *depth = reference_allocator.allocate_cleared(1); auto &subpass = subpasses[i]; - subpass = { VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR }; + subpass = { VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 }; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = subpass_infos[i].num_color_attachments; subpass.pColorAttachments = colors; @@ -321,7 +321,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) subpass.pInputAttachments = inputs; subpass.pDepthStencilAttachment = depth; - if (multiview && device->get_device_features().multiview_features.multiview) + if (multiview && device->get_device_features().vk11_features.multiview) subpass.viewMask = ((1u << info.num_layers) - 1u) << info.base_layer; else if (multiview) LOGE("Multiview not supported. Pretending render pass is not multiview."); @@ -336,7 +336,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) { auto att = subpass_infos[i].color_attachments[j]; VK_ASSERT(att == VK_ATTACHMENT_UNUSED || (att < num_attachments)); - colors[j].sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; + colors[j].sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2; colors[j].attachment = att; // Fill in later. colors[j].layout = VK_IMAGE_LAYOUT_UNDEFINED; @@ -346,7 +346,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) { auto att = subpass_infos[i].input_attachments[j]; VK_ASSERT(att == VK_ATTACHMENT_UNUSED || (att < num_attachments)); - inputs[j].sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; + inputs[j].sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2; inputs[j].attachment = att; if (att != VK_ATTACHMENT_UNUSED) { @@ -365,14 +365,14 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) { auto att = subpass_infos[i].resolve_attachments[j]; VK_ASSERT(att == VK_ATTACHMENT_UNUSED || (att < num_attachments)); - resolves[j].sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; + resolves[j].sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2; resolves[j].attachment = att; // Fill in later. resolves[j].layout = VK_IMAGE_LAYOUT_UNDEFINED; } } - depth->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; + depth->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2; if (info.depth_stencil && subpass_infos[i].depth_stencil_mode != RenderPassInfo::DepthStencil::None) { @@ -387,36 +387,36 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) } } - const auto find_color = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2KHR * { + const auto find_color = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2 * { auto *colors = subpasses[subpass].pColorAttachments; for (unsigned i = 0; i < subpasses[subpass].colorAttachmentCount; i++) if (colors[i].attachment == attachment) - return const_cast(&colors[i]); + return const_cast(&colors[i]); return nullptr; }; - const auto find_resolve = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2KHR * { + const auto find_resolve = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2 * { if (!subpasses[subpass].pResolveAttachments) return nullptr; auto *resolves = subpasses[subpass].pResolveAttachments; for (unsigned i = 0; i < subpasses[subpass].colorAttachmentCount; i++) if (resolves[i].attachment == attachment) - return const_cast(&resolves[i]); + return const_cast(&resolves[i]); return nullptr; }; - const auto find_input = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2KHR * { + const auto find_input = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2 * { auto *inputs = subpasses[subpass].pInputAttachments; for (unsigned i = 0; i < subpasses[subpass].inputAttachmentCount; i++) if (inputs[i].attachment == attachment) - return const_cast(&inputs[i]); + return const_cast(&inputs[i]); return nullptr; }; - const auto find_depth_stencil = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2KHR * { + const auto find_depth_stencil = [&](unsigned subpass, unsigned attachment) -> VkAttachmentReference2 * { if (subpasses[subpass].pDepthStencilAttachment->attachment == attachment) - return const_cast(subpasses[subpass].pDepthStencilAttachment); + return const_cast(subpasses[subpass].pDepthStencilAttachment); else return nullptr; }; @@ -675,7 +675,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) } VK_ASSERT(num_subpasses > 0); - VkRenderPassCreateInfo2KHR rp_info = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR }; + VkRenderPassCreateInfo2 rp_info = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 }; rp_info.subpassCount = num_subpasses; rp_info.pSubpasses = subpasses.data(); rp_info.pAttachments = attachments; @@ -686,7 +686,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) [&](unsigned subpass) { external_dependencies.emplace_back(); auto &dep = external_dependencies.back(); - dep = { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR }; + dep = { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 }; dep.srcSubpass = VK_SUBPASS_EXTERNAL; dep.dstSubpass = subpass; @@ -725,7 +725,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) for_each_bit(color_self_dependencies | depth_self_dependencies, [&](unsigned subpass) { external_dependencies.emplace_back(); auto &dep = external_dependencies.back(); - dep = { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR }; + dep = { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 }; dep.srcSubpass = subpass; dep.dstSubpass = subpass; dep.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; @@ -753,7 +753,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) { external_dependencies.emplace_back(); auto &dep = external_dependencies.back(); - dep = { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR }; + dep = { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 }; dep.srcSubpass = subpass - 1; dep.dstSubpass = subpass; dep.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; @@ -810,7 +810,7 @@ RenderPass::RenderPass(Hash hash, Device *device_, const RenderPassInfo &info) LOGI("Creating render pass.\n"); #endif auto &table = device->get_device_table(); - if (table.vkCreateRenderPass2KHR(device->get_device(), &rp_info, nullptr, &render_pass) != VK_SUCCESS) + if (table.vkCreateRenderPass2(device->get_device(), &rp_info, nullptr, &render_pass) != VK_SUCCESS) LOGE("Failed to create render pass."); #ifdef GRANITE_VULKAN_FOSSILIZE diff --git a/vulkan/render_pass.hpp b/vulkan/render_pass.hpp index 6860e1343..167280358 100644 --- a/vulkan/render_pass.hpp +++ b/vulkan/render_pass.hpp @@ -90,17 +90,17 @@ class RenderPass : public HashedObject, public NoCopyNoMove public: struct SubpassInfo { - VkAttachmentReference2KHR color_attachments[VULKAN_NUM_ATTACHMENTS]; + VkAttachmentReference2 color_attachments[VULKAN_NUM_ATTACHMENTS]; unsigned num_color_attachments; - VkAttachmentReference2KHR input_attachments[VULKAN_NUM_ATTACHMENTS]; + VkAttachmentReference2 input_attachments[VULKAN_NUM_ATTACHMENTS]; unsigned num_input_attachments; - VkAttachmentReference2KHR depth_stencil_attachment; + VkAttachmentReference2 depth_stencil_attachment; unsigned samples; }; RenderPass(Util::Hash hash, Device *device, const RenderPassInfo &info); - RenderPass(Util::Hash hash, Device *device, const VkRenderPassCreateInfo2KHR &create_info); + RenderPass(Util::Hash hash, Device *device, const VkRenderPassCreateInfo2 &create_info); ~RenderPass(); unsigned get_num_subpasses() const @@ -131,14 +131,14 @@ class RenderPass : public HashedObject, public NoCopyNoMove return subpasses_info[subpass].num_input_attachments; } - const VkAttachmentReference2KHR &get_color_attachment(unsigned subpass, unsigned index) const + const VkAttachmentReference2 &get_color_attachment(unsigned subpass, unsigned index) const { VK_ASSERT(subpass < subpasses_info.size()); VK_ASSERT(index < subpasses_info[subpass].num_color_attachments); return subpasses_info[subpass].color_attachments[index]; } - const VkAttachmentReference2KHR &get_input_attachment(unsigned subpass, unsigned index) const + const VkAttachmentReference2 &get_input_attachment(unsigned subpass, unsigned index) const { VK_ASSERT(subpass < subpasses_info.size()); VK_ASSERT(index < subpasses_info[subpass].num_input_attachments); @@ -167,7 +167,7 @@ class RenderPass : public HashedObject, public NoCopyNoMove VkFormat depth_stencil = VK_FORMAT_UNDEFINED; std::vector subpasses_info; - void setup_subpasses(const VkRenderPassCreateInfo2KHR &create_info); + void setup_subpasses(const VkRenderPassCreateInfo2 &create_info); }; class Framebuffer : public Cookie, public NoCopyNoMove, public InternalSyncEnabled diff --git a/vulkan/sampler.cpp b/vulkan/sampler.cpp index 472aeafbe..2042e5c17 100644 --- a/vulkan/sampler.cpp +++ b/vulkan/sampler.cpp @@ -128,7 +128,7 @@ ImmutableYcbcrConversion::ImmutableYcbcrConversion(Util::Hash hash, Device *devi const VkSamplerYcbcrConversionCreateInfo &info) : HashedObject(hash), device(device_) { - if (device->get_device_features().sampler_ycbcr_conversion_features.samplerYcbcrConversion) + if (device->get_device_features().vk11_features.samplerYcbcrConversion) { if (device->get_device_table().vkCreateSamplerYcbcrConversion(device->get_device(), &info, nullptr, &conversion) != VK_SUCCESS) diff --git a/vulkan/semaphore.cpp b/vulkan/semaphore.cpp index 0da0aa968..c99ec1636 100644 --- a/vulkan/semaphore.cpp +++ b/vulkan/semaphore.cpp @@ -46,7 +46,7 @@ void SemaphoreHolder::recycle_semaphore() if (internal_sync) { - if (semaphore_type == VK_SEMAPHORE_TYPE_TIMELINE_KHR || external_compatible_features) + if (semaphore_type == VK_SEMAPHORE_TYPE_TIMELINE || external_compatible_features) { device->destroy_semaphore_nolock(semaphore); } @@ -64,7 +64,7 @@ void SemaphoreHolder::recycle_semaphore() } else { - if (semaphore_type == VK_SEMAPHORE_TYPE_TIMELINE_KHR || external_compatible_features) + if (semaphore_type == VK_SEMAPHORE_TYPE_TIMELINE || external_compatible_features) { device->destroy_semaphore(semaphore); } @@ -124,7 +124,7 @@ ExternalHandle SemaphoreHolder::export_to_handle() // Technically we can export early with reference transference, but it's a bit dubious. // We want to remain compatible with copy transference for later, e.g. SYNC_FD. - if (!signalled && semaphore_type == VK_SEMAPHORE_TYPE_BINARY_KHR) + if (!signalled && semaphore_type == VK_SEMAPHORE_TYPE_BINARY) { LOGE("Cannot export payload from a semaphore that is not queued up for signal.\n"); return h; diff --git a/vulkan/shader.cpp b/vulkan/shader.cpp index 68abe0258..dfa2124f9 100644 --- a/vulkan/shader.cpp +++ b/vulkan/shader.cpp @@ -565,7 +565,7 @@ Shader::Shader(Hash hash, Device *device_, const uint32_t *data, size_t size, LOGE("Failed to reflect resource layout.\n"); #endif - if (layout.bindless_set_mask != 0 && !device->get_device_features().supports_descriptor_indexing) + if (layout.bindless_set_mask != 0 && !device->get_device_features().vk12_features.descriptorIndexing) LOGE("Sufficient features for descriptor indexing is not supported on this device.\n"); } diff --git a/vulkan/wsi.cpp b/vulkan/wsi.cpp index bd4bd0289..cef1e0e5c 100644 --- a/vulkan/wsi.cpp +++ b/vulkan/wsi.cpp @@ -271,18 +271,20 @@ bool WSI::init_context_from_platform(unsigned num_thread_indices, const Context: VkSurfaceKHR tmp_surface = platform->create_surface(new_context->get_instance(), VK_NULL_HANDLE); - if (!new_context->init_device( + bool ret = new_context->init_device( VK_NULL_HANDLE, tmp_surface, device_ext.data(), device_ext.size(), - CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT | video_context_flags)) + CONTEXT_CREATION_ENABLE_ADVANCED_WSI_BIT | video_context_flags); + + if (tmp_surface) + platform->destroy_surface(new_context->get_instance(), tmp_surface); + + if (!ret) { LOGE("Failed to create Vulkan device.\n"); return false; } - if (tmp_surface) - platform->destroy_surface(new_context->get_instance(), tmp_surface); - return init_from_existing_context(std::move(new_context)); } @@ -1016,7 +1018,7 @@ static bool init_surface_info(Device &device, WSIPlatform &platform, const char *exclusive = getenv("GRANITE_EXCLUSIVE_FULL_SCREEN"); bool prefer_exclusive = (exclusive && strtoul(exclusive, nullptr, 0) != 0) || low_latency_mode_enable; - if (ext.driver_properties.driverID == VK_DRIVER_ID_AMD_PROPRIETARY_KHR && format == BackbufferFormat::HDR10) + if (ext.driver_id == VK_DRIVER_ID_AMD_PROPRIETARY && format == BackbufferFormat::HDR10) { LOGI("Win32: HDR requested on AMD Windows. Forcing exclusive fullscreen, or HDR will not work properly.\n"); prefer_exclusive = true;