diff options
39 files changed, 822 insertions, 221 deletions
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 8bb321e35..fea10d809 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -72,7 +72,6 @@ if (YUZU_USE_EXTERNAL_SDL2) endif() add_subdirectory(SDL EXCLUDE_FROM_ALL) - target_link_directories(SDL2-static INTERFACE "${SDL2_BINARY_DIR}") endif() # ENet diff --git a/externals/Vulkan-Headers b/externals/Vulkan-Headers -Subproject 33d4dd987fc8fc6475ff9ca2b4f0c3cc6e79333 +Subproject 2826791bed6a793f164bf534cd859968f13df8a diff --git a/src/common/settings_input.h b/src/common/settings_input.h index 485e4ad22..46f38c703 100644 --- a/src/common/settings_input.h +++ b/src/common/settings_input.h @@ -391,6 +391,7 @@ struct PlayerInput { u32 body_color_right; u32 button_color_left; u32 button_color_right; + std::string profile_name; }; struct TouchscreenInput { diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 9779378be..74c877728 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -110,10 +110,9 @@ void EmulatedController::ReloadFromSettings() { original_npad_type = npad_type; } + Disconnect(); if (player.connected) { Connect(); - } else { - Disconnect(); } ReloadInput(); diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index 0690f9a1c..e72c3d35d 100644 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp @@ -36,14 +36,14 @@ public: private: KernelCore& kernel; - - std::jthread m_host_thread; - std::mutex m_session_mutex; - std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions; - KEvent* m_wakeup_event; - KThread* m_thread; - std::atomic<bool> m_shutdown_requested; const std::string m_service_name; + + std::jthread m_host_thread{}; + std::mutex m_session_mutex{}; + std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{}; + KEvent* m_wakeup_event{}; + KThread* m_thread{}; + std::atomic<bool> m_shutdown_requested{}; }; void ServiceThread::Impl::WaitAndProcessImpl() { diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index 053e8f9dd..26dec7147 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -203,9 +203,8 @@ private: }; AudInU::AudInU(Core::System& system_) - : ServiceFramework{system_, "audin:u", ServiceThreadType::CreateNew}, - service_context{system_, "AudInU"}, impl{std::make_unique<AudioCore::AudioIn::Manager>( - system_)} { + : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, + impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} { // clang-format off static const FunctionInfo functions[] = { {0, &AudInU::ListAudioIns, "ListAudioIns"}, diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 29751f075..991e30ba1 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -26,9 +26,8 @@ public: explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, size_t session_id, const std::string& device_name, const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) - : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew}, - service_context{system_, "IAudioOut"}, event{service_context.CreateEvent( - "AudioOutEvent")}, + : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"}, + event{service_context.CreateEvent("AudioOutEvent")}, impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} { // clang-format off @@ -221,9 +220,8 @@ private: }; AudOutU::AudOutU(Core::System& system_) - : ServiceFramework{system_, "audout:u", ServiceThreadType::CreateNew}, - service_context{system_, "AudOutU"}, impl{std::make_unique<AudioCore::AudioOut::Manager>( - system_)} { + : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"}, + impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} { // clang-format off static const FunctionInfo functions[] = { {0, &AudOutU::ListAudioOuts, "ListAudioOuts"}, diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 3a1c231b6..ead16c321 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -35,10 +35,9 @@ public: AudioCore::AudioRendererParameterInternal& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, u32 process_handle, u64 applet_resource_user_id, s32 session_id) - : ServiceFramework{system_, "IAudioRenderer", ServiceThreadType::CreateNew}, - service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent( - "IAudioRendererEvent")}, - manager{manager_}, impl{std::make_unique<Renderer>(system_, manager, rendered_event)} { + : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, + rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, + impl{std::make_unique<Renderer>(system_, manager, rendered_event)} { // clang-format off static const FunctionInfo functions[] = { {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, @@ -243,10 +242,8 @@ class IAudioDevice final : public ServiceFramework<IAudioDevice> { public: explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, u32 device_num) - : ServiceFramework{system_, "IAudioDevice", ServiceThreadType::CreateNew}, - service_context{system_, "IAudioDevice"}, impl{std::make_unique<AudioDevice>( - system_, applet_resource_user_id, - revision)}, + : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"}, + impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)}, event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { static const FunctionInfo functions[] = { {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, @@ -421,7 +418,7 @@ private: }; AudRenU::AudRenU(Core::System& system_) - : ServiceFramework{system_, "audren:u", ServiceThreadType::CreateNew}, + : ServiceFramework{system_, "audren:u"}, service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} { // clang-format off static const FunctionInfo functions[] = { diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index f3f08b42c..5864e772b 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp @@ -93,6 +93,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0); conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0); smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0); + alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0); + alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0); for (size_t i = 0; i < regs.rt.size(); ++i) { color_formats[i] = static_cast<u8>(regs.rt[i].format); diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index 1afdef329..ab79fb8f3 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h @@ -195,6 +195,8 @@ struct FixedPipelineState { BitField<12, 1, u32> provoking_vertex_last; BitField<13, 1, u32> conservative_raster_enable; BitField<14, 1, u32> smooth_lines; + BitField<15, 1, u32> alpha_to_coverage_enabled; + BitField<16, 1, u32> alpha_to_one_enabled; }; std::array<u8, Maxwell::NumRenderTargets> color_formats; diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 430a84272..3e03c5cd6 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -58,7 +58,7 @@ VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wra case Tegra::Texture::WrapMode::Border: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; case Tegra::Texture::WrapMode::Clamp: - if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { + if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { // Nvidia's Vulkan driver defaults to GL_CLAMP on invalid enumerations, we can hack this // by sending an invalid enumeration. return static_cast<VkSamplerAddressMode>(0xcafe); diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index b7843e995..28b893e25 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -44,17 +44,17 @@ public: }); } - vk::DescriptorUpdateTemplateKHR CreateTemplate(VkDescriptorSetLayout descriptor_set_layout, - VkPipelineLayout pipeline_layout, - bool use_push_descriptor) const { + vk::DescriptorUpdateTemplate CreateTemplate(VkDescriptorSetLayout descriptor_set_layout, + VkPipelineLayout pipeline_layout, + bool use_push_descriptor) const { if (entries.empty()) { return nullptr; } const VkDescriptorUpdateTemplateType type = use_push_descriptor ? VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR - : VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; - return device->GetLogical().CreateDescriptorUpdateTemplateKHR({ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR, + : VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; + return device->GetLogical().CreateDescriptorUpdateTemplate({ + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, .pNext = nullptr, .flags = 0, .descriptorUpdateEntryCount = static_cast<u32>(entries.size()), @@ -129,7 +129,7 @@ private: const Device* device{}; bool is_compute{}; boost::container::small_vector<VkDescriptorSetLayoutBinding, 32> bindings; - boost::container::small_vector<VkDescriptorUpdateTemplateEntryKHR, 32> entries; + boost::container::small_vector<VkDescriptorUpdateTemplateEntry, 32> entries; u32 binding{}; u32 num_descriptors{}; size_t offset{}; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index c2a95200b..18be54729 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -45,14 +45,14 @@ std::string GetDriverVersion(const Device& device) { // https://github.com/SaschaWillems/vulkan.gpuinfo.org/blob/5dddea46ea1120b0df14eef8f15ff8e318e35462/functions.php#L308-L314 const u32 version = device.GetDriverVersion(); - if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { + if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { const u32 major = (version >> 22) & 0x3ff; const u32 minor = (version >> 14) & 0x0ff; const u32 secondary = (version >> 6) & 0x0ff; const u32 tertiary = version & 0x003f; return fmt::format("{}.{}.{}.{}", major, minor, secondary, tertiary); } - if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR) { + if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { const u32 major = version >> 14; const u32 minor = version & 0x3fff; return fmt::format("{}.{}", major, minor); diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 241d7573e..2c00979d7 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -93,7 +93,7 @@ constexpr DescriptorBankInfo ASTC_BANK_INFO{ .score = 2, }; -constexpr VkDescriptorUpdateTemplateEntryKHR INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE{ +constexpr VkDescriptorUpdateTemplateEntry INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE{ .dstBinding = 0, .dstArrayElement = 0, .descriptorCount = 2, @@ -102,7 +102,7 @@ constexpr VkDescriptorUpdateTemplateEntryKHR INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMP .stride = sizeof(DescriptorUpdateEntry), }; -constexpr std::array<VkDescriptorUpdateTemplateEntryKHR, ASTC_NUM_BINDINGS> +constexpr std::array<VkDescriptorUpdateTemplateEntry, ASTC_NUM_BINDINGS> ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{ { .dstBinding = ASTC_BINDING_INPUT_BUFFER, @@ -134,7 +134,7 @@ struct AstcPushConstants { ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool, vk::Span<VkDescriptorSetLayoutBinding> bindings, - vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates, + vk::Span<VkDescriptorUpdateTemplateEntry> templates, const DescriptorBankInfo& bank_info, vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code) : device{device_} { @@ -155,13 +155,13 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool, .pPushConstantRanges = push_constants.data(), }); if (!templates.empty()) { - descriptor_template = device.GetLogical().CreateDescriptorUpdateTemplateKHR({ - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR, + descriptor_template = device.GetLogical().CreateDescriptorUpdateTemplate({ + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, .pNext = nullptr, .flags = 0, .descriptorUpdateEntryCount = templates.size(), .pDescriptorUpdateEntries = templates.data(), - .templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR, + .templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, .descriptorSetLayout = *descriptor_set_layout, .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, .pipelineLayout = *layout, diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.h b/src/video_core/renderer_vulkan/vk_compute_pass.h index dcc691a8e..5d32e3caf 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.h +++ b/src/video_core/renderer_vulkan/vk_compute_pass.h @@ -29,14 +29,14 @@ class ComputePass { public: explicit ComputePass(const Device& device, DescriptorPool& descriptor_pool, vk::Span<VkDescriptorSetLayoutBinding> bindings, - vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates, + vk::Span<VkDescriptorUpdateTemplateEntry> templates, const DescriptorBankInfo& bank_info, vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code); ~ComputePass(); protected: const Device& device; - vk::DescriptorUpdateTemplateKHR descriptor_template; + vk::DescriptorUpdateTemplate descriptor_template; vk::PipelineLayout layout; vk::Pipeline pipeline; vk::DescriptorSetLayout descriptor_set_layout; diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 7906e11a8..04a3a861e 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -53,7 +53,7 @@ ComputePipeline::ComputePipeline(const Device& device_, DescriptorPool& descript .requiredSubgroupSize = GuestWarpSize, }; VkPipelineCreateFlags flags{}; - if (device.IsKhrPipelineEexecutablePropertiesEnabled()) { + if (device.IsKhrPipelineExecutablePropertiesEnabled()) { flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR; } pipeline = device.GetLogical().CreateComputePipeline({ diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.h b/src/video_core/renderer_vulkan/vk_compute_pipeline.h index 9879735fe..d70837fc5 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.h @@ -55,7 +55,7 @@ private: vk::DescriptorSetLayout descriptor_set_layout; DescriptorAllocator descriptor_allocator; vk::PipelineLayout pipeline_layout; - vk::DescriptorUpdateTemplateKHR descriptor_update_template; + vk::DescriptorUpdateTemplate descriptor_update_template; vk::Pipeline pipeline; std::condition_variable build_condvar; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index ef75c126c..006128638 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -714,8 +714,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .sampleShadingEnable = VK_FALSE, .minSampleShading = 0.0f, .pSampleMask = nullptr, - .alphaToCoverageEnable = VK_FALSE, - .alphaToOneEnable = VK_FALSE, + .alphaToCoverageEnable = key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE, + .alphaToOneEnable = key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE, }; const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, @@ -830,7 +830,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { */ } VkPipelineCreateFlags flags{}; - if (device.IsKhrPipelineEexecutablePropertiesEnabled()) { + if (device.IsKhrPipelineExecutablePropertiesEnabled()) { flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR; } pipeline = device.GetLogical().CreateGraphicsPipeline({ diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 6bf577d25..1ed2967be 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -151,7 +151,7 @@ private: vk::DescriptorSetLayout descriptor_set_layout; DescriptorAllocator descriptor_allocator; vk::PipelineLayout pipeline_layout; - vk::DescriptorUpdateTemplateKHR descriptor_update_template; + vk::DescriptorUpdateTemplate descriptor_update_template; vk::Pipeline pipeline; std::condition_variable build_condvar; diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp index 4e81d3d28..8aa07ef9d 100644 --- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp +++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp @@ -11,10 +11,10 @@ namespace Vulkan { MasterSemaphore::MasterSemaphore(const Device& device) { - static constexpr VkSemaphoreTypeCreateInfoKHR semaphore_type_ci{ - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR, + static constexpr VkSemaphoreTypeCreateInfo semaphore_type_ci{ + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, .pNext = nullptr, - .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR, + .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, .initialValue = 0, }; static constexpr VkSemaphoreCreateInfo semaphore_ci{ @@ -28,7 +28,7 @@ MasterSemaphore::MasterSemaphore(const Device& device) { return; } // Validation layers have a bug where they fail to track resource usage when using timeline - // semaphores and synchronizing with GetSemaphoreCounterValueKHR. To workaround this issue, have + // semaphores and synchronizing with GetSemaphoreCounterValue. To workaround this issue, have // a separate thread waiting for each timeline semaphore value. debug_thread = std::jthread([this](std::stop_token stop_token) { u64 counter = 0; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 29da442fa..38a6b7488 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -287,7 +287,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"), serialization_thread(1, "VkPipelineSerialization") { const auto& float_control{device.FloatControlProperties()}; - const VkDriverIdKHR driver_id{device.GetDriverID()}; + const VkDriverId driver_id{device.GetDriverID()}; profile = Shader::Profile{ .supported_spirv = device.SupportedSpirvVersion(), .unified_descriptor_binding = true, @@ -297,10 +297,10 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device .support_int64 = device.IsShaderInt64Supported(), .support_vertex_instance_id = false, .support_float_controls = true, - .support_separate_denorm_behavior = float_control.denormBehaviorIndependence == - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR, + .support_separate_denorm_behavior = + float_control.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, .support_separate_rounding_mode = - float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR, + float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, .support_fp16_denorm_preserve = float_control.shaderDenormPreserveFloat16 != VK_FALSE, .support_fp32_denorm_preserve = float_control.shaderDenormPreserveFloat32 != VK_FALSE, .support_fp16_denorm_flush = float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE, @@ -327,17 +327,17 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device .lower_left_origin_mode = false, .need_declared_frag_colors = false, - .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, + .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, .has_broken_unsigned_image_offsets = false, .has_broken_signed_operations = false, - .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, + .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY, .ignore_nan_fp_comparisons = false, }; host_info = Shader::HostTranslateInfo{ .support_float16 = device.IsFloat16Supported(), .support_int64 = device.IsShaderInt64Supported(), - .needs_demote_reorder = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR || - driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, + .needs_demote_reorder = + driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE, .support_snorm_render_buffer = true, .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(), }; @@ -408,7 +408,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading std::unique_ptr<PipelineStatistics> statistics; } state; - if (device.IsKhrPipelineEexecutablePropertiesEnabled()) { + if (device.IsKhrPipelineExecutablePropertiesEnabled()) { state.statistics = std::make_unique<PipelineStatistics>(device); } const auto load_compute{[&](std::ifstream& file, FileEnvironment env) { diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 4b15c0f85..929c8ece6 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp @@ -98,7 +98,7 @@ HostCounter::HostCounter(QueryCache& cache_, std::shared_ptr<HostCounter> depend query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} { const vk::Device* logical = &cache.GetDevice().GetLogical(); cache.GetScheduler().Record([logical, query = query](vk::CommandBuffer cmdbuf) { - logical->ResetQueryPoolEXT(query.first, query.second, 1); + logical->ResetQueryPool(query.first, query.second, 1); cmdbuf.BeginQuery(query.first, query.second, VK_QUERY_CONTROL_PRECISE_BIT); }); } diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index c09fb3e98..c2e53a5d5 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -194,8 +194,8 @@ void Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_s VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, }; - const VkTimelineSemaphoreSubmitInfoKHR timeline_si{ - .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, + const VkTimelineSemaphoreSubmitInfo timeline_si{ + .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, .pNext = nullptr, .waitSemaphoreValueCount = num_wait_semaphores, .pWaitSemaphoreValues = wait_values.data(), diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 652329c38..33856fe59 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -77,12 +77,6 @@ enum class NvidiaArchitecture { constexpr std::array REQUIRED_EXTENSIONS{ VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, - - // Core in 1.2, but required due to use of extension methods, - // and well-supported by drivers - VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, - VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, - VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, #ifdef _WIN32 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, #endif @@ -311,10 +305,10 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical, VkPhysicalDeviceFragmentShadingRatePropertiesKHR shading_rate_props{}; shading_rate_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR; - VkPhysicalDeviceProperties2KHR physical_properties{}; - physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; + VkPhysicalDeviceProperties2 physical_properties{}; + physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; physical_properties.pNext = &shading_rate_props; - physical.GetProperties2KHR(physical_properties); + physical.GetProperties2(physical_properties); if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) { // Only Ampere and newer support this feature return NvidiaArchitecture::AmpereOrNewer; @@ -405,15 +399,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const void* first_next = &features2; void** next = &features2.pNext; - VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR, + VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, .pNext = nullptr, .timelineSemaphore = true, }; SetNext(next, timeline_semaphore); - VkPhysicalDevice16BitStorageFeaturesKHR bit16_storage{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR, + VkPhysicalDevice16BitStorageFeatures bit16_storage{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, .pNext = nullptr, .storageBuffer16BitAccess = true, .uniformAndStorageBuffer16BitAccess = true, @@ -422,8 +416,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR }; SetNext(next, bit16_storage); - VkPhysicalDevice8BitStorageFeaturesKHR bit8_storage{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, + VkPhysicalDevice8BitStorageFeatures bit8_storage{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, .pNext = nullptr, .storageBuffer8BitAccess = false, .uniformAndStorageBuffer8BitAccess = true, @@ -440,15 +434,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR }; SetNext(next, robustness2); - VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, + VkPhysicalDeviceHostQueryResetFeatures host_query_reset{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, .pNext = nullptr, .hostQueryReset = true, }; SetNext(next, host_query_reset); - VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, + VkPhysicalDeviceVariablePointerFeatures variable_pointers{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, .pNext = nullptr, .variablePointersStorageBuffer = VK_TRUE, .variablePointers = VK_TRUE, @@ -462,10 +456,17 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR }; SetNext(next, demote); - VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8; + VkPhysicalDeviceShaderDrawParametersFeatures draw_parameters{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES, + .pNext = nullptr, + .shaderDrawParameters = true, + }; + SetNext(next, draw_parameters); + + VkPhysicalDeviceShaderFloat16Int8Features float16_int8; if (is_int8_supported || is_float16_supported) { float16_int8 = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, .pNext = nullptr, .shaderFloat16 = is_float16_supported, .shaderInt8 = is_int8_supported, @@ -491,10 +492,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_INFO(Render_Vulkan, "Device doesn't support passthrough geometry shaders"); } - VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout; + VkPhysicalDeviceUniformBufferStandardLayoutFeatures std430_layout; if (khr_uniform_buffer_standard_layout) { std430_layout = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR, + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, .pNext = nullptr, .uniformBufferStandardLayout = true, }; @@ -612,10 +613,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_INFO(Render_Vulkan, "Device doesn't support vertex input dynamic state"); } - VkPhysicalDeviceShaderAtomicInt64FeaturesKHR atomic_int64; + VkPhysicalDeviceShaderAtomicInt64Features atomic_int64; if (ext_shader_atomic_int64) { atomic_int64 = { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR, + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, .pNext = nullptr, .shaderBufferInt64Atomics = VK_TRUE, .shaderSharedInt64Atomics = VK_TRUE, @@ -971,22 +972,42 @@ void Device::CheckSuitability(bool requires_swapchain) const { demote.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES; demote.pNext = nullptr; - VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers{}; - variable_pointers.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR; + VkPhysicalDeviceVariablePointerFeatures variable_pointers{}; + variable_pointers.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES; variable_pointers.pNext = &demote; VkPhysicalDeviceRobustness2FeaturesEXT robustness2{}; robustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; robustness2.pNext = &variable_pointers; - VkPhysicalDeviceFeatures2KHR features2{}; + VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore{}; + timeline_semaphore.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES; + timeline_semaphore.pNext = &robustness2; + + VkPhysicalDevice16BitStorageFeatures bit16_storage{}; + bit16_storage.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; + bit16_storage.pNext = &timeline_semaphore; + + VkPhysicalDevice8BitStorageFeatures bit8_storage{}; + bit8_storage.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES; + bit8_storage.pNext = &bit16_storage; + + VkPhysicalDeviceHostQueryResetFeatures host_query_reset{}; + host_query_reset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES; + host_query_reset.pNext = &bit8_storage; + + VkPhysicalDeviceShaderDrawParametersFeatures draw_parameters{}; + draw_parameters.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES; + draw_parameters.pNext = &host_query_reset; + + VkPhysicalDeviceFeatures2 features2{}; features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - features2.pNext = &robustness2; + features2.pNext = &draw_parameters; - physical.GetFeatures2KHR(features2); + physical.GetFeatures2(features2); const VkPhysicalDeviceFeatures& features{features2.features}; - std::vector feature_report{ + std::array feature_report{ std::make_pair(features.robustBufferAccess, "robustBufferAccess"), std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"), std::make_pair(features.imageCubeArray, "imageCubeArray"), @@ -1002,6 +1023,7 @@ void Device::CheckSuitability(bool requires_swapchain) const { std::make_pair(features.tessellationShader, "tessellationShader"), std::make_pair(features.sampleRateShading, "sampleRateShading"), std::make_pair(features.dualSrcBlend, "dualSrcBlend"), + std::make_pair(features.logicOp, "logicOp"), std::make_pair(features.occlusionQueryPrecise, "occlusionQueryPrecise"), std::make_pair(features.fragmentStoresAndAtomics, "fragmentStoresAndAtomics"), std::make_pair(features.shaderImageGatherExtended, "shaderImageGatherExtended"), @@ -1016,6 +1038,14 @@ void Device::CheckSuitability(bool requires_swapchain) const { std::make_pair(robustness2.robustImageAccess2, "robustImageAccess2"), std::make_pair(robustness2.nullDescriptor, "nullDescriptor"), std::make_pair(demote.shaderDemoteToHelperInvocation, "shaderDemoteToHelperInvocation"), + std::make_pair(timeline_semaphore.timelineSemaphore, "timelineSemaphore"), + std::make_pair(bit16_storage.storageBuffer16BitAccess, "storageBuffer16BitAccess"), + std::make_pair(bit16_storage.uniformAndStorageBuffer16BitAccess, + "uniformAndStorageBuffer16BitAccess"), + std::make_pair(bit8_storage.uniformAndStorageBuffer8BitAccess, + "uniformAndStorageBuffer8BitAccess"), + std::make_pair(host_query_reset.hostQueryReset, "hostQueryReset"), + std::make_pair(draw_parameters.shaderDrawParameters, "shaderDrawParameters"), }; bool has_all_required_features = true; @@ -1108,37 +1138,37 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME, false); } } - VkPhysicalDeviceFeatures2KHR features{}; - features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; + VkPhysicalDeviceFeatures2 features{}; + features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - VkPhysicalDeviceProperties2KHR physical_properties{}; - physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; + VkPhysicalDeviceProperties2 physical_properties{}; + physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; if (has_khr_shader_float16_int8) { - VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_features; - float16_int8_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; + VkPhysicalDeviceShaderFloat16Int8Features float16_int8_features; + float16_int8_features.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES; float16_int8_features.pNext = nullptr; features.pNext = &float16_int8_features; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); is_float16_supported = float16_int8_features.shaderFloat16; is_int8_supported = float16_int8_features.shaderInt8; extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); } if (has_ext_subgroup_size_control) { - VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroup_features; - subgroup_features.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT; + VkPhysicalDeviceSubgroupSizeControlFeatures subgroup_features; + subgroup_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES; subgroup_features.pNext = nullptr; features.pNext = &subgroup_features; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); - VkPhysicalDeviceSubgroupSizeControlPropertiesEXT subgroup_properties; + VkPhysicalDeviceSubgroupSizeControlProperties subgroup_properties; subgroup_properties.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT; + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES; subgroup_properties.pNext = nullptr; physical_properties.pNext = &subgroup_properties; - physical.GetProperties2KHR(physical_properties); + physical.GetProperties2(physical_properties); is_warp_potentially_bigger = subgroup_properties.maxSubgroupSize > GuestWarpSize; @@ -1157,7 +1187,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { provoking_vertex.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT; provoking_vertex.pNext = nullptr; features.pNext = &provoking_vertex; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (provoking_vertex.provokingVertexLast && provoking_vertex.transformFeedbackPreservesProvokingVertex) { @@ -1171,7 +1201,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT; vertex_input.pNext = nullptr; features.pNext = &vertex_input; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (vertex_input.vertexInputDynamicState) { extensions.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); @@ -1183,7 +1213,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { atomic_int64.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES; atomic_int64.pNext = nullptr; features.pNext = &atomic_int64; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (atomic_int64.shaderBufferInt64Atomics && atomic_int64.shaderSharedInt64Atomics) { extensions.push_back(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); @@ -1195,13 +1225,13 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { tfb_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; tfb_features.pNext = nullptr; features.pNext = &tfb_features; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); VkPhysicalDeviceTransformFeedbackPropertiesEXT tfb_properties; tfb_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; tfb_properties.pNext = nullptr; physical_properties.pNext = &tfb_properties; - physical.GetProperties2KHR(physical_properties); + physical.GetProperties2(physical_properties); if (tfb_features.transformFeedback && tfb_features.geometryStreams && tfb_properties.maxTransformFeedbackStreams >= 4 && @@ -1216,7 +1246,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { border_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; border_features.pNext = nullptr; features.pNext = &border_features; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (border_features.customBorderColors && border_features.customBorderColorWithoutFormat) { extensions.push_back(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); @@ -1229,7 +1259,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; extended_dynamic_state.pNext = nullptr; features.pNext = &extended_dynamic_state; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (extended_dynamic_state.extendedDynamicState) { extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); @@ -1241,7 +1271,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { line_raster.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT; line_raster.pNext = nullptr; features.pNext = &line_raster; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (line_raster.rectangularLines && line_raster.smoothLines) { extensions.push_back(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); ext_line_rasterization = true; @@ -1253,7 +1283,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR; layout.pNext = nullptr; features.pNext = &layout; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (layout.workgroupMemoryExplicitLayout && layout.workgroupMemoryExplicitLayout8BitAccess && @@ -1269,7 +1299,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR; executable_properties.pNext = nullptr; features.pNext = &executable_properties; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); if (executable_properties.pipelineExecutableInfo) { extensions.push_back(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); @@ -1282,7 +1312,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; primitive_topology_list_restart.pNext = nullptr; features.pNext = &primitive_topology_list_restart; - physical.GetFeatures2KHR(features); + physical.GetFeatures2(features); is_topology_list_restart_supported = primitive_topology_list_restart.primitiveTopologyListRestart; @@ -1300,7 +1330,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { push_descriptor.pNext = nullptr; physical_properties.pNext = &push_descriptor; - physical.GetProperties2KHR(physical_properties); + physical.GetProperties2(physical_properties); max_push_descriptors = push_descriptor.maxPushDescriptors; } @@ -1351,18 +1381,18 @@ void Device::SetupFeatures() { } void Device::SetupProperties() { - float_controls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR; + float_controls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES; VkPhysicalDeviceProperties2KHR properties2{}; - properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; + properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; properties2.pNext = &float_controls; - physical.GetProperties2KHR(properties2); + physical.GetProperties2(properties2); } void Device::CollectTelemetryParameters() { - VkPhysicalDeviceDriverPropertiesKHR driver{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR, + VkPhysicalDeviceDriverProperties driver{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, .pNext = nullptr, .driverID = {}, .driverName = {}, @@ -1370,12 +1400,12 @@ void Device::CollectTelemetryParameters() { .conformanceVersion = {}, }; - VkPhysicalDeviceProperties2KHR device_properties{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR, + VkPhysicalDeviceProperties2 device_properties{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &driver, .properties = {}, }; - physical.GetProperties2KHR(device_properties); + physical.GetProperties2(device_properties); driver_id = driver.driverID; vendor_name = driver.driverName; @@ -1431,23 +1461,10 @@ void Device::CollectToolingInfo() { if (!ext_tooling_info) { return; } - const auto vkGetPhysicalDeviceToolPropertiesEXT = - reinterpret_cast<PFN_vkGetPhysicalDeviceToolPropertiesEXT>( - dld.vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceToolPropertiesEXT")); - if (!vkGetPhysicalDeviceToolPropertiesEXT) { - return; - } - u32 tool_count = 0; - if (vkGetPhysicalDeviceToolPropertiesEXT(physical, &tool_count, nullptr) != VK_SUCCESS) { - return; - } - std::vector<VkPhysicalDeviceToolPropertiesEXT> tools(tool_count); - if (vkGetPhysicalDeviceToolPropertiesEXT(physical, &tool_count, tools.data()) != VK_SUCCESS) { - return; - } - for (const VkPhysicalDeviceToolPropertiesEXT& tool : tools) { + auto tools{physical.GetPhysicalDeviceToolProperties()}; + for (const VkPhysicalDeviceToolProperties& tool : tools) { const std::string_view name = tool.name; - LOG_INFO(Render_Vulkan, "{}", name); + LOG_INFO(Render_Vulkan, "Attached debugging tool: {}", name); has_renderdoc = has_renderdoc || name == "RenderDoc"; has_nsight_graphics = has_nsight_graphics || name == "NVIDIA Nsight Graphics"; } diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index c85fbba77..db802437c 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -217,7 +217,7 @@ public: } /// Returns true if VK_KHR_pipeline_executable_properties is enabled. - bool IsKhrPipelineEexecutablePropertiesEnabled() const { + bool IsKhrPipelineExecutablePropertiesEnabled() const { return khr_pipeline_executable_properties; } diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 2ad98dcfe..e4a07813f 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -130,7 +130,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { X(vkCreateComputePipelines); X(vkCreateDescriptorPool); X(vkCreateDescriptorSetLayout); - X(vkCreateDescriptorUpdateTemplateKHR); + X(vkCreateDescriptorUpdateTemplate); X(vkCreateEvent); X(vkCreateFence); X(vkCreateFramebuffer); @@ -149,7 +149,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { X(vkDestroyCommandPool); X(vkDestroyDescriptorPool); X(vkDestroyDescriptorSetLayout); - X(vkDestroyDescriptorUpdateTemplateKHR); + X(vkDestroyDescriptorUpdateTemplate); X(vkDestroyEvent); X(vkDestroyFence); X(vkDestroyFramebuffer); @@ -180,18 +180,29 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { X(vkGetQueryPoolResults); X(vkGetPipelineExecutablePropertiesKHR); X(vkGetPipelineExecutableStatisticsKHR); - X(vkGetSemaphoreCounterValueKHR); + X(vkGetSemaphoreCounterValue); X(vkMapMemory); X(vkQueueSubmit); X(vkResetFences); - X(vkResetQueryPoolEXT); + X(vkResetQueryPool); X(vkSetDebugUtilsObjectNameEXT); X(vkSetDebugUtilsObjectTagEXT); X(vkUnmapMemory); - X(vkUpdateDescriptorSetWithTemplateKHR); + X(vkUpdateDescriptorSetWithTemplate); X(vkUpdateDescriptorSets); X(vkWaitForFences); - X(vkWaitSemaphoresKHR); + X(vkWaitSemaphores); + + // Support for timeline semaphores is mandatory in Vulkan 1.2 + if (!dld.vkGetSemaphoreCounterValue) { + Proc(dld.vkGetSemaphoreCounterValue, dld, "vkGetSemaphoreCounterValueKHR", device); + Proc(dld.vkWaitSemaphores, dld, "vkWaitSemaphoresKHR", device); + } + + // Support for host query reset is mandatory in Vulkan 1.2 + if (!dld.vkResetQueryPool) { + Proc(dld.vkResetQueryPool, dld, "vkResetQueryPoolEXT", device); + } #undef X } @@ -224,12 +235,13 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept { X(vkCreateDebugUtilsMessengerEXT); X(vkDestroyDebugUtilsMessengerEXT); X(vkDestroySurfaceKHR); - X(vkGetPhysicalDeviceFeatures2KHR); - X(vkGetPhysicalDeviceProperties2KHR); + X(vkGetPhysicalDeviceFeatures2); + X(vkGetPhysicalDeviceProperties2); X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); X(vkGetPhysicalDeviceSurfaceFormatsKHR); X(vkGetPhysicalDeviceSurfacePresentModesKHR); X(vkGetPhysicalDeviceSurfaceSupportKHR); + X(vkGetPhysicalDeviceToolProperties); X(vkGetSwapchainImagesKHR); X(vkQueuePresentKHR); @@ -359,9 +371,9 @@ void Destroy(VkDevice device, VkDescriptorSetLayout handle, const DeviceDispatch dld.vkDestroyDescriptorSetLayout(device, handle, nullptr); } -void Destroy(VkDevice device, VkDescriptorUpdateTemplateKHR handle, +void Destroy(VkDevice device, VkDescriptorUpdateTemplate handle, const DeviceDispatch& dld) noexcept { - dld.vkDestroyDescriptorUpdateTemplateKHR(device, handle, nullptr); + dld.vkDestroyDescriptorUpdateTemplate(device, handle, nullptr); } void Destroy(VkDevice device, VkDeviceMemory handle, const DeviceDispatch& dld) noexcept { @@ -737,11 +749,11 @@ CommandPool Device::CreateCommandPool(const VkCommandPoolCreateInfo& ci) const { return CommandPool(object, handle, *dld); } -DescriptorUpdateTemplateKHR Device::CreateDescriptorUpdateTemplateKHR( - const VkDescriptorUpdateTemplateCreateInfoKHR& ci) const { - VkDescriptorUpdateTemplateKHR object; - Check(dld->vkCreateDescriptorUpdateTemplateKHR(handle, &ci, nullptr, &object)); - return DescriptorUpdateTemplateKHR(object, handle, *dld); +DescriptorUpdateTemplate Device::CreateDescriptorUpdateTemplate( + const VkDescriptorUpdateTemplateCreateInfo& ci) const { + VkDescriptorUpdateTemplate object; + Check(dld->vkCreateDescriptorUpdateTemplate(handle, &ci, nullptr, &object)); + return DescriptorUpdateTemplate(object, handle, *dld); } QueryPool Device::CreateQueryPool(const VkQueryPoolCreateInfo& ci) const { @@ -857,20 +869,20 @@ VkPhysicalDeviceProperties PhysicalDevice::GetProperties() const noexcept { return properties; } -void PhysicalDevice::GetProperties2KHR(VkPhysicalDeviceProperties2KHR& properties) const noexcept { - dld->vkGetPhysicalDeviceProperties2KHR(physical_device, &properties); +void PhysicalDevice::GetProperties2(VkPhysicalDeviceProperties2& properties) const noexcept { + dld->vkGetPhysicalDeviceProperties2(physical_device, &properties); } VkPhysicalDeviceFeatures PhysicalDevice::GetFeatures() const noexcept { - VkPhysicalDeviceFeatures2KHR features2; - features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; + VkPhysicalDeviceFeatures2 features2; + features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; features2.pNext = nullptr; - dld->vkGetPhysicalDeviceFeatures2KHR(physical_device, &features2); + dld->vkGetPhysicalDeviceFeatures2(physical_device, &features2); return features2.features; } -void PhysicalDevice::GetFeatures2KHR(VkPhysicalDeviceFeatures2KHR& features) const noexcept { - dld->vkGetPhysicalDeviceFeatures2KHR(physical_device, &features); +void PhysicalDevice::GetFeatures2(VkPhysicalDeviceFeatures2& features) const noexcept { + dld->vkGetPhysicalDeviceFeatures2(physical_device, &features); } VkFormatProperties PhysicalDevice::GetFormatProperties(VkFormat format) const noexcept { @@ -895,6 +907,18 @@ std::vector<VkQueueFamilyProperties> PhysicalDevice::GetQueueFamilyProperties() return properties; } +std::vector<VkPhysicalDeviceToolProperties> PhysicalDevice::GetPhysicalDeviceToolProperties() + const { + u32 num = 0; + if (!dld->vkGetPhysicalDeviceToolProperties) { + return {}; + } + dld->vkGetPhysicalDeviceToolProperties(physical_device, &num, nullptr); + std::vector<VkPhysicalDeviceToolProperties> properties(num); + dld->vkGetPhysicalDeviceToolProperties(physical_device, &num, properties.data()); + return properties; +} + bool PhysicalDevice::GetSurfaceSupportKHR(u32 queue_family_index, VkSurfaceKHR surface) const { VkBool32 supported; Check(dld->vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_index, surface, diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 1b3f493bd..8395ff2cb 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -168,12 +168,13 @@ struct InstanceDispatch { PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties{}; PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices{}; PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr{}; - PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR{}; + PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2{}; PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties{}; PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties{}; PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2{}; PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties{}; - PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR{}; + PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2{}; + PFN_vkGetPhysicalDeviceToolProperties vkGetPhysicalDeviceToolProperties{}; PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties{}; PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR{}; PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR{}; @@ -247,7 +248,7 @@ struct DeviceDispatch : InstanceDispatch { PFN_vkCreateComputePipelines vkCreateComputePipelines{}; PFN_vkCreateDescriptorPool vkCreateDescriptorPool{}; PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout{}; - PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR{}; + PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate{}; PFN_vkCreateEvent vkCreateEvent{}; PFN_vkCreateFence vkCreateFence{}; PFN_vkCreateFramebuffer vkCreateFramebuffer{}; @@ -266,7 +267,7 @@ struct DeviceDispatch : InstanceDispatch { PFN_vkDestroyCommandPool vkDestroyCommandPool{}; PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool{}; PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout{}; - PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR{}; + PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate{}; PFN_vkDestroyEvent vkDestroyEvent{}; PFN_vkDestroyFence vkDestroyFence{}; PFN_vkDestroyFramebuffer vkDestroyFramebuffer{}; @@ -297,18 +298,18 @@ struct DeviceDispatch : InstanceDispatch { PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR{}; PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR{}; PFN_vkGetQueryPoolResults vkGetQueryPoolResults{}; - PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR{}; + PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue{}; PFN_vkMapMemory vkMapMemory{}; PFN_vkQueueSubmit vkQueueSubmit{}; PFN_vkResetFences vkResetFences{}; - PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT{}; + PFN_vkResetQueryPool vkResetQueryPool{}; PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{}; PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT{}; PFN_vkUnmapMemory vkUnmapMemory{}; - PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR{}; + PFN_vkUpdateDescriptorSetWithTemplate vkUpdateDescriptorSetWithTemplate{}; PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets{}; PFN_vkWaitForFences vkWaitForFences{}; - PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR{}; + PFN_vkWaitSemaphores vkWaitSemaphores{}; }; /// Loads instance agnostic function pointers. @@ -327,7 +328,7 @@ void Destroy(VkDevice, VkBufferView, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkCommandPool, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkDescriptorPool, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept; -void Destroy(VkDevice, VkDescriptorUpdateTemplateKHR, const DeviceDispatch&) noexcept; +void Destroy(VkDevice, VkDescriptorUpdateTemplate, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkDeviceMemory, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkEvent, const DeviceDispatch&) noexcept; void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept; @@ -559,7 +560,7 @@ private: using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>; using DescriptorSetLayout = Handle<VkDescriptorSetLayout, VkDevice, DeviceDispatch>; -using DescriptorUpdateTemplateKHR = Handle<VkDescriptorUpdateTemplateKHR, VkDevice, DeviceDispatch>; +using DescriptorUpdateTemplate = Handle<VkDescriptorUpdateTemplate, VkDevice, DeviceDispatch>; using Pipeline = Handle<VkPipeline, VkDevice, DeviceDispatch>; using PipelineLayout = Handle<VkPipelineLayout, VkDevice, DeviceDispatch>; using QueryPool = Handle<VkQueryPool, VkDevice, DeviceDispatch>; @@ -766,7 +767,7 @@ public: [[nodiscard]] u64 GetCounter() const { u64 value; - Check(dld->vkGetSemaphoreCounterValueKHR(owner, handle, &value)); + Check(dld->vkGetSemaphoreCounterValue(owner, handle, &value)); return value; } @@ -778,15 +779,15 @@ public: * @return True on successful wait, false on timeout */ bool Wait(u64 value, u64 timeout = std::numeric_limits<u64>::max()) const { - const VkSemaphoreWaitInfoKHR wait_info{ - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR, + const VkSemaphoreWaitInfo wait_info{ + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, .pNext = nullptr, .flags = 0, .semaphoreCount = 1, .pSemaphores = &handle, .pValues = &value, }; - const VkResult result = dld->vkWaitSemaphoresKHR(owner, &wait_info, timeout); + const VkResult result = dld->vkWaitSemaphores(owner, &wait_info, timeout); switch (result) { case VK_SUCCESS: return true; @@ -840,8 +841,8 @@ public: CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const; - DescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplateKHR( - const VkDescriptorUpdateTemplateCreateInfoKHR& ci) const; + DescriptorUpdateTemplate CreateDescriptorUpdateTemplate( + const VkDescriptorUpdateTemplateCreateInfo& ci) const; QueryPool CreateQueryPool(const VkQueryPoolCreateInfo& ci) const; @@ -869,9 +870,9 @@ public: void UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes, Span<VkCopyDescriptorSet> copies) const noexcept; - void UpdateDescriptorSet(VkDescriptorSet set, VkDescriptorUpdateTemplateKHR update_template, + void UpdateDescriptorSet(VkDescriptorSet set, VkDescriptorUpdateTemplate update_template, const void* data) const noexcept { - dld->vkUpdateDescriptorSetWithTemplateKHR(handle, set, update_template, data); + dld->vkUpdateDescriptorSetWithTemplate(handle, set, update_template, data); } VkResult AcquireNextImageKHR(VkSwapchainKHR swapchain, u64 timeout, VkSemaphore semaphore, @@ -884,8 +885,8 @@ public: return dld->vkDeviceWaitIdle(handle); } - void ResetQueryPoolEXT(VkQueryPool query_pool, u32 first, u32 count) const noexcept { - dld->vkResetQueryPoolEXT(handle, query_pool, first, count); + void ResetQueryPool(VkQueryPool query_pool, u32 first, u32 count) const noexcept { + dld->vkResetQueryPool(handle, query_pool, first, count); } VkResult GetQueryResults(VkQueryPool query_pool, u32 first, u32 count, std::size_t data_size, @@ -910,11 +911,11 @@ public: VkPhysicalDeviceProperties GetProperties() const noexcept; - void GetProperties2KHR(VkPhysicalDeviceProperties2KHR&) const noexcept; + void GetProperties2(VkPhysicalDeviceProperties2&) const noexcept; VkPhysicalDeviceFeatures GetFeatures() const noexcept; - void GetFeatures2KHR(VkPhysicalDeviceFeatures2KHR&) const noexcept; + void GetFeatures2(VkPhysicalDeviceFeatures2&) const noexcept; VkFormatProperties GetFormatProperties(VkFormat) const noexcept; @@ -922,6 +923,8 @@ public: std::vector<VkQueueFamilyProperties> GetQueueFamilyProperties() const; + std::vector<VkPhysicalDeviceToolProperties> GetPhysicalDeviceToolProperties() const; + bool GetSurfaceSupportKHR(u32 queue_family_index, VkSurfaceKHR) const; VkSurfaceCapabilitiesKHR GetSurfaceCapabilitiesKHR(VkSurfaceKHR) const; @@ -980,7 +983,7 @@ public: dynamic_offsets.size(), dynamic_offsets.data()); } - void PushDescriptorSetWithTemplateKHR(VkDescriptorUpdateTemplateKHR update_template, + void PushDescriptorSetWithTemplateKHR(VkDescriptorUpdateTemplate update_template, VkPipelineLayout layout, u32 set, const void* data) const noexcept { dld->vkCmdPushDescriptorSetWithTemplateKHR(handle, update_template, layout, set, data); diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 65c144921..9971bdfab 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -88,6 +88,9 @@ add_executable(yuzu configuration/configure_input_advanced.cpp configuration/configure_input_advanced.h configuration/configure_input_advanced.ui + configuration/configure_input_per_game.cpp + configuration/configure_input_per_game.h + configuration/configure_input_per_game.ui configuration/configure_input_player.cpp configuration/configure_input_player.h configuration/configure_input_player.ui diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 0c93df428..c11d1c8b3 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -124,6 +124,10 @@ void Config::Initialize(const std::string& config_name) { } } +bool Config::IsCustomConfig() { + return type == ConfigType::PerGameConfig; +} + /* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their * usages later in this file. This allows explicit definition of some types that don't work * nicely with the general version. @@ -194,8 +198,20 @@ void Config::ReadPlayerValue(std::size_t player_index) { }(); auto& player = Settings::values.players.GetValue()[player_index]; + if (IsCustomConfig()) { + const auto profile_name = + qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{}) + .toString() + .toStdString(); + if (profile_name.empty()) { + // Use the global input config + player = Settings::values.players.GetValue(true)[player_index]; + return; + } + player.profile_name = profile_name; + } - if (player_prefix.isEmpty()) { + if (player_prefix.isEmpty() && Settings::IsConfiguringGlobal()) { const auto controller = static_cast<Settings::ControllerType>( qt_config ->value(QStringLiteral("%1type").arg(player_prefix), @@ -388,9 +404,26 @@ void Config::ReadAudioValues() { void Config::ReadControlValues() { qt_config->beginGroup(QStringLiteral("Controls")); + Settings::values.players.SetGlobal(!IsCustomConfig()); for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { ReadPlayerValue(p); } + ReadGlobalSetting(Settings::values.use_docked_mode); + + // Disable docked mode if handheld is selected + const auto controller_type = Settings::values.players.GetValue()[0].controller_type; + if (controller_type == Settings::ControllerType::Handheld) { + Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig()); + Settings::values.use_docked_mode.SetValue(false); + } + + ReadGlobalSetting(Settings::values.vibration_enabled); + ReadGlobalSetting(Settings::values.enable_accurate_vibrations); + ReadGlobalSetting(Settings::values.motion_enabled); + if (IsCustomConfig()) { + qt_config->endGroup(); + return; + } ReadDebugValues(); ReadKeyboardValues(); ReadMouseValues(); @@ -412,18 +445,6 @@ void Config::ReadControlValues() { ReadBasicSetting(Settings::values.tas_loop); ReadBasicSetting(Settings::values.pause_tas_on_load); - ReadGlobalSetting(Settings::values.use_docked_mode); - - // Disable docked mode if handheld is selected - const auto controller_type = Settings::values.players.GetValue()[0].controller_type; - if (controller_type == Settings::ControllerType::Handheld) { - Settings::values.use_docked_mode.SetValue(false); - } - - ReadGlobalSetting(Settings::values.vibration_enabled); - ReadGlobalSetting(Settings::values.enable_accurate_vibrations); - ReadGlobalSetting(Settings::values.motion_enabled); - ReadBasicSetting(Settings::values.controller_navigation); qt_config->endGroup(); @@ -905,7 +926,6 @@ void Config::ReadMultiplayerValues() { void Config::ReadValues() { if (global) { - ReadControlValues(); ReadDataStorageValues(); ReadDebuggingValues(); ReadDisabledAddOnValues(); @@ -914,6 +934,7 @@ void Config::ReadValues() { ReadWebServiceValues(); ReadMiscellaneousValues(); } + ReadControlValues(); ReadCoreValues(); ReadCpuValues(); ReadRendererValues(); @@ -932,12 +953,20 @@ void Config::SavePlayerValue(std::size_t player_index) { }(); const auto& player = Settings::values.players.GetValue()[player_index]; + if (IsCustomConfig()) { + if (player.profile_name.empty()) { + // No custom profile selected + return; + } + WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix), + QString::fromStdString(player.profile_name), QString{}); + } WriteSetting(QStringLiteral("%1type").arg(player_prefix), static_cast<u8>(player.controller_type), static_cast<u8>(Settings::ControllerType::ProController)); - if (!player_prefix.isEmpty()) { + if (!player_prefix.isEmpty() || !Settings::IsConfiguringGlobal()) { WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, player_index == 0); WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix), @@ -1055,7 +1084,6 @@ void Config::SaveIrCameraValues() { void Config::SaveValues() { if (global) { - SaveControlValues(); SaveDataStorageValues(); SaveDebuggingValues(); SaveDisabledAddOnValues(); @@ -1064,6 +1092,7 @@ void Config::SaveValues() { SaveWebServiceValues(); SaveMiscellaneousValues(); } + SaveControlValues(); SaveCoreValues(); SaveCpuValues(); SaveRendererValues(); @@ -1088,9 +1117,14 @@ void Config::SaveAudioValues() { void Config::SaveControlValues() { qt_config->beginGroup(QStringLiteral("Controls")); + Settings::values.players.SetGlobal(!IsCustomConfig()); for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { SavePlayerValue(p); } + if (IsCustomConfig()) { + qt_config->endGroup(); + return; + } SaveDebugValues(); SaveMouseValues(); SaveTouchscreenValues(); @@ -1579,6 +1613,13 @@ void Config::SaveControlPlayerValue(std::size_t player_index) { qt_config->endGroup(); } +void Config::ClearControlPlayerValues() { + qt_config->beginGroup(QStringLiteral("Controls")); + // If key is an empty string, all keys in the current group() are removed. + qt_config->remove(QString{}); + qt_config->endGroup(); +} + const std::string& Config::GetConfigFilePath() const { return qt_config_loc; } diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 06fa7d2d0..7d26e9ab6 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -34,6 +34,7 @@ public: void ReadControlPlayerValue(std::size_t player_index); void SaveControlPlayerValue(std::size_t player_index); + void ClearControlPlayerValues(); const std::string& GetConfigFilePath() const; @@ -58,6 +59,7 @@ public: private: void Initialize(const std::string& config_name); + bool IsCustomConfig(); void ReadValues(); void ReadPlayerValue(std::size_t player_index); diff --git a/src/yuzu/configuration/configure_input_per_game.cpp b/src/yuzu/configuration/configure_input_per_game.cpp new file mode 100644 index 000000000..78e65d468 --- /dev/null +++ b/src/yuzu/configuration/configure_input_per_game.cpp @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/settings.h" +#include "core/core.h" +#include "core/hid/emulated_controller.h" +#include "core/hid/hid_core.h" +#include "ui_configure_input_per_game.h" +#include "yuzu/configuration/config.h" +#include "yuzu/configuration/configure_input_per_game.h" +#include "yuzu/configuration/input_profiles.h" + +ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, Config* config_, + QWidget* parent) + : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPerGame>()), + profiles(std::make_unique<InputProfiles>()), system{system_}, config{config_} { + ui->setupUi(this); + const std::array labels = { + ui->label_player_1, ui->label_player_2, ui->label_player_3, ui->label_player_4, + ui->label_player_5, ui->label_player_6, ui->label_player_7, ui->label_player_8, + }; + profile_comboboxes = { + ui->profile_player_1, ui->profile_player_2, ui->profile_player_3, ui->profile_player_4, + ui->profile_player_5, ui->profile_player_6, ui->profile_player_7, ui->profile_player_8, + }; + + Settings::values.players.SetGlobal(false); + + const auto& profile_names = profiles->GetInputProfileNames(); + const auto populate_profiles = [this, &profile_names](size_t player_index) { + const auto previous_profile = + Settings::values.players.GetValue()[player_index].profile_name; + + auto* const player_combobox = profile_comboboxes[player_index]; + player_combobox->addItem(tr("Use global input configuration")); + + for (size_t index = 0; index < profile_names.size(); ++index) { + const auto& profile_name = profile_names[index]; + player_combobox->addItem(QString::fromStdString(profile_name)); + if (profile_name == previous_profile) { + // offset by 1 since the first element is the global config + player_combobox->setCurrentIndex(static_cast<int>(index + 1)); + } + } + }; + for (size_t index = 0; index < profile_comboboxes.size(); ++index) { + labels[index]->setText(tr("Player %1 profile").arg(index + 1)); + populate_profiles(index); + } + + LoadConfiguration(); +} + +void ConfigureInputPerGame::ApplyConfiguration() { + LoadConfiguration(); + SaveConfiguration(); +} + +void ConfigureInputPerGame::LoadConfiguration() { + static constexpr size_t HANDHELD_INDEX = 8; + + auto& hid_core = system.HIDCore(); + for (size_t player_index = 0; player_index < profile_comboboxes.size(); ++player_index) { + Settings::values.players.SetGlobal(false); + + auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(player_index); + auto* const player_combobox = profile_comboboxes[player_index]; + + const auto selection_index = player_combobox->currentIndex(); + if (selection_index == 0) { + Settings::values.players.GetValue()[player_index].profile_name = ""; + if (player_index == 0) { + Settings::values.players.GetValue()[HANDHELD_INDEX] = {}; + } + Settings::values.players.SetGlobal(true); + emulated_controller->ReloadFromSettings(); + continue; + } + const auto profile_name = player_combobox->itemText(selection_index).toStdString(); + if (profile_name.empty()) { + continue; + } + auto& player = Settings::values.players.GetValue()[player_index]; + player.profile_name = profile_name; + // Read from the profile into the custom player settings + profiles->LoadProfile(profile_name, player_index); + // Make sure the controller is connected + player.connected = true; + + emulated_controller->ReloadFromSettings(); + + if (player_index > 0) { + continue; + } + // Handle Handheld cases + auto& handheld_player = Settings::values.players.GetValue()[HANDHELD_INDEX]; + auto* handheld_controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); + if (player.controller_type == Settings::ControllerType::Handheld) { + handheld_player = player; + } else { + handheld_player = {}; + } + handheld_controller->ReloadFromSettings(); + } +} + +void ConfigureInputPerGame::SaveConfiguration() { + Settings::values.players.SetGlobal(false); + + // Clear all controls from the config in case the user reverted back to globals + config->ClearControlPlayerValues(); + for (size_t index = 0; index < Settings::values.players.GetValue().size(); ++index) { + config->SaveControlPlayerValue(index); + } +} diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h new file mode 100644 index 000000000..660faf574 --- /dev/null +++ b/src/yuzu/configuration/configure_input_per_game.h @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <memory> + +#include <QWidget> + +#include "ui_configure_input_per_game.h" +#include "yuzu/configuration/input_profiles.h" + +class QComboBox; + +namespace Core { +class System; +} // namespace Core + +class Config; + +class ConfigureInputPerGame : public QWidget { + Q_OBJECT + +public: + explicit ConfigureInputPerGame(Core::System& system_, Config* config_, + QWidget* parent = nullptr); + + /// Load and Save configurations to settings file. + void ApplyConfiguration(); + +private: + /// Load configuration from settings file. + void LoadConfiguration(); + + /// Save configuration to settings file. + void SaveConfiguration(); + + std::unique_ptr<Ui::ConfigureInputPerGame> ui; + std::unique_ptr<InputProfiles> profiles; + + std::array<QComboBox*, 8> profile_comboboxes; + + Core::System& system; + Config* config; +}; diff --git a/src/yuzu/configuration/configure_input_per_game.ui b/src/yuzu/configuration/configure_input_per_game.ui new file mode 100644 index 000000000..fbd8eab1c --- /dev/null +++ b/src/yuzu/configuration/configure_input_per_game.ui @@ -0,0 +1,333 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ConfigureInputPerGame</class> + <widget class="QWidget" name="PerGameInput"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>541</width> + <height>759</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="accessibleName"> + <string>Graphics</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_1"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Input Profiles</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QWidget" name="player_1" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_1"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_1"> + <property name="text"> + <string>Player 1 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_1"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_2" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_2"> + <property name="text"> + <string>Player 2 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_3" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_3"> + <property name="text"> + <string>Player 3 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_4" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_4"> + <property name="text"> + <string>Player 4 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_5" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_5"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_5"> + <property name="text"> + <string>Player 5 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_5"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_6" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_6"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_6"> + <property name="text"> + <string>Player 6 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_6"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_7" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_7"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_7"> + <property name="text"> + <string>Player 7 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_7"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="player_8" native="true"> + <layout class="QHBoxLayout" name="input_profile_layout_8"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QLabel" name="label_player_8"> + <property name="text"> + <string>Player 8 Profile</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="profile_player_8"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 9e5a40fe7..ed21f4b92 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -1553,6 +1553,7 @@ void ConfigureInputPlayer::LoadProfile() { } void ConfigureInputPlayer::SaveProfile() { + static constexpr size_t HANDHELD_INDEX = 8; const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex()); if (profile_name.isEmpty()) { @@ -1561,7 +1562,12 @@ void ConfigureInputPlayer::SaveProfile() { ApplyConfiguration(); - if (!profiles->SaveProfile(profile_name.toStdString(), player_index)) { + // When we're in handheld mode, only the handheld emulated controller bindings are updated + const bool is_handheld = player_index == 0 && emulated_controller->GetNpadIdType() == + Core::HID::NpadIdType::Handheld; + const auto profile_player_index = is_handheld ? HANDHELD_INDEX : player_index; + + if (!profiles->SaveProfile(profile_name.toStdString(), profile_player_index)) { QMessageBox::critical(this, tr("Save Input Profile"), tr("Failed to save the input profile \"%1\"").arg(profile_name)); UpdateInputProfiles(); diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index 79434fdd8..26f60d121 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h @@ -38,7 +38,7 @@ enum class InputType; namespace Ui { class ConfigureInputPlayer; -} +} // namespace Ui namespace Core::HID { class HIDCore; diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index c3cb8f61d..93db47cfd 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -28,7 +28,7 @@ #include "yuzu/configuration/configure_general.h" #include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/configure_graphics_advanced.h" -#include "yuzu/configuration/configure_input.h" +#include "yuzu/configuration/configure_input_per_game.h" #include "yuzu/configuration/configure_per_game.h" #include "yuzu/configuration/configure_per_game_addons.h" #include "yuzu/configuration/configure_system.h" @@ -50,6 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st general_tab = std::make_unique<ConfigureGeneral>(system_, this); graphics_tab = std::make_unique<ConfigureGraphics>(system_, this); graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); + input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); system_tab = std::make_unique<ConfigureSystem>(system_, this); ui->setupUi(this); @@ -61,6 +62,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); + ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); setFocusPolicy(Qt::ClickFocus); setWindowTitle(tr("Properties")); @@ -91,6 +93,7 @@ void ConfigurePerGame::ApplyConfiguration() { graphics_tab->ApplyConfiguration(); graphics_advanced_tab->ApplyConfiguration(); audio_tab->ApplyConfiguration(); + input_tab->ApplyConfiguration(); system.ApplySettings(); Settings::LogSettings(); diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index 17a98a0f3..4ecc43541 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h @@ -16,12 +16,17 @@ namespace Core { class System; } +namespace InputCommon { +class InputSubsystem; +} + class ConfigurePerGameAddons; class ConfigureAudio; class ConfigureCpu; class ConfigureGeneral; class ConfigureGraphics; class ConfigureGraphicsAdvanced; +class ConfigureInputPerGame; class ConfigureSystem; class QGraphicsScene; @@ -72,5 +77,6 @@ private: std::unique_ptr<ConfigureGeneral> general_tab; std::unique_ptr<ConfigureGraphics> graphics_tab; std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; + std::unique_ptr<ConfigureInputPerGame> input_tab; std::unique_ptr<ConfigureSystem> system_tab; }; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e06ee7570..c0afb2e5f 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -126,6 +126,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "yuzu/compatibility_list.h" #include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_dialog.h" +#include "yuzu/configuration/configure_input_per_game.h" #include "yuzu/debugger/console.h" #include "yuzu/debugger/controller.h" #include "yuzu/debugger/profiler.h" @@ -1658,6 +1659,11 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t LOG_INFO(Frontend, "yuzu starting..."); StoreRecentFile(filename); // Put the filename on top of the list + // Save configurations + UpdateUISettings(); + game_list->SaveInterfaceLayout(); + config->Save(); + u64 title_id{0}; last_filename_booted = filename; @@ -1674,14 +1680,10 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t ? Common::FS::PathToUTF8String(file_path.filename()) : fmt::format("{:016X}", title_id); Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig); + system->HIDCore().ReloadInputDevices(); system->ApplySettings(); } - // Save configurations - UpdateUISettings(); - game_list->SaveInterfaceLayout(); - config->Save(); - Settings::LogSettings(); if (UISettings::values.select_user_on_boot) { @@ -2802,6 +2804,7 @@ void GMainWindow::OnStopGame() { ShutdownGame(); Settings::RestoreGlobalState(system->IsPoweredOn()); + system->HIDCore().ReloadInputDevices(); UpdateStatusButtons(); } @@ -3281,6 +3284,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file // Do not cause the global config to write local settings into the config file const bool is_powered_on = system->IsPoweredOn(); Settings::RestoreGlobalState(is_powered_on); + system->HIDCore().ReloadInputDevices(); UISettings::values.configuration_applied = false; @@ -3764,6 +3768,7 @@ void GMainWindow::OnCoreError(Core::SystemResultStatus result, std::string detai ShutdownGame(); Settings::RestoreGlobalState(system->IsPoweredOn()); + system->HIDCore().ReloadInputDevices(); UpdateStatusButtons(); } } else { @@ -3915,18 +3920,19 @@ void GMainWindow::closeEvent(QCloseEvent* event) { // Unload controllers early controller_dialog->UnloadController(); game_list->UnloadController(); - system->HIDCore().UnloadInputDevices(); // Shutdown session if the emu thread is active... if (emu_thread != nullptr) { ShutdownGame(); Settings::RestoreGlobalState(system->IsPoweredOn()); + system->HIDCore().ReloadInputDevices(); UpdateStatusButtons(); } render_window->close(); multiplayer_state->Close(); + system->HIDCore().UnloadInputDevices(); system->GetRoomNetwork().Shutdown(); QWidget::closeEvent(event); diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index cbf04a939..19b1d258c 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -38,7 +38,7 @@ target_link_libraries(yuzu-cmd PRIVATE inih::INIReader glad) if (MSVC) target_link_libraries(yuzu-cmd PRIVATE getopt) endif() -target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} SDL2 Threads::Threads) +target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) create_resource("../../dist/yuzu.bmp" "yuzu_cmd/yuzu_icon.h" "yuzu_icon") target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR}) |