diff options
Diffstat (limited to 'src')
37 files changed, 822 insertions, 220 deletions
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 { | |||
| 391 | u32 body_color_right; | 391 | u32 body_color_right; |
| 392 | u32 button_color_left; | 392 | u32 button_color_left; |
| 393 | u32 button_color_right; | 393 | u32 button_color_right; |
| 394 | std::string profile_name; | ||
| 394 | }; | 395 | }; |
| 395 | 396 | ||
| 396 | struct TouchscreenInput { | 397 | 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() { | |||
| 110 | original_npad_type = npad_type; | 110 | original_npad_type = npad_type; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | Disconnect(); | ||
| 113 | if (player.connected) { | 114 | if (player.connected) { |
| 114 | Connect(); | 115 | Connect(); |
| 115 | } else { | ||
| 116 | Disconnect(); | ||
| 117 | } | 116 | } |
| 118 | 117 | ||
| 119 | ReloadInput(); | 118 | 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: | |||
| 36 | 36 | ||
| 37 | private: | 37 | private: |
| 38 | KernelCore& kernel; | 38 | KernelCore& kernel; |
| 39 | |||
| 40 | std::jthread m_host_thread; | ||
| 41 | std::mutex m_session_mutex; | ||
| 42 | std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions; | ||
| 43 | KEvent* m_wakeup_event; | ||
| 44 | KThread* m_thread; | ||
| 45 | std::atomic<bool> m_shutdown_requested; | ||
| 46 | const std::string m_service_name; | 39 | const std::string m_service_name; |
| 40 | |||
| 41 | std::jthread m_host_thread{}; | ||
| 42 | std::mutex m_session_mutex{}; | ||
| 43 | std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{}; | ||
| 44 | KEvent* m_wakeup_event{}; | ||
| 45 | KThread* m_thread{}; | ||
| 46 | std::atomic<bool> m_shutdown_requested{}; | ||
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | void ServiceThread::Impl::WaitAndProcessImpl() { | 49 | 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: | |||
| 203 | }; | 203 | }; |
| 204 | 204 | ||
| 205 | AudInU::AudInU(Core::System& system_) | 205 | AudInU::AudInU(Core::System& system_) |
| 206 | : ServiceFramework{system_, "audin:u", ServiceThreadType::CreateNew}, | 206 | : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, |
| 207 | service_context{system_, "AudInU"}, impl{std::make_unique<AudioCore::AudioIn::Manager>( | 207 | impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} { |
| 208 | system_)} { | ||
| 209 | // clang-format off | 208 | // clang-format off |
| 210 | static const FunctionInfo functions[] = { | 209 | static const FunctionInfo functions[] = { |
| 211 | {0, &AudInU::ListAudioIns, "ListAudioIns"}, | 210 | {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: | |||
| 26 | explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, | 26 | explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, |
| 27 | size_t session_id, const std::string& device_name, | 27 | size_t session_id, const std::string& device_name, |
| 28 | const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) | 28 | const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) |
| 29 | : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew}, | 29 | : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"}, |
| 30 | service_context{system_, "IAudioOut"}, event{service_context.CreateEvent( | 30 | event{service_context.CreateEvent("AudioOutEvent")}, |
| 31 | "AudioOutEvent")}, | ||
| 32 | impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} { | 31 | impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} { |
| 33 | 32 | ||
| 34 | // clang-format off | 33 | // clang-format off |
| @@ -221,9 +220,8 @@ private: | |||
| 221 | }; | 220 | }; |
| 222 | 221 | ||
| 223 | AudOutU::AudOutU(Core::System& system_) | 222 | AudOutU::AudOutU(Core::System& system_) |
| 224 | : ServiceFramework{system_, "audout:u", ServiceThreadType::CreateNew}, | 223 | : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"}, |
| 225 | service_context{system_, "AudOutU"}, impl{std::make_unique<AudioCore::AudioOut::Manager>( | 224 | impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} { |
| 226 | system_)} { | ||
| 227 | // clang-format off | 225 | // clang-format off |
| 228 | static const FunctionInfo functions[] = { | 226 | static const FunctionInfo functions[] = { |
| 229 | {0, &AudOutU::ListAudioOuts, "ListAudioOuts"}, | 227 | {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: | |||
| 35 | AudioCore::AudioRendererParameterInternal& params, | 35 | AudioCore::AudioRendererParameterInternal& params, |
| 36 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, | 36 | Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, |
| 37 | u32 process_handle, u64 applet_resource_user_id, s32 session_id) | 37 | u32 process_handle, u64 applet_resource_user_id, s32 session_id) |
| 38 | : ServiceFramework{system_, "IAudioRenderer", ServiceThreadType::CreateNew}, | 38 | : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, |
| 39 | service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent( | 39 | rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, |
| 40 | "IAudioRendererEvent")}, | 40 | impl{std::make_unique<Renderer>(system_, manager, rendered_event)} { |
| 41 | manager{manager_}, impl{std::make_unique<Renderer>(system_, manager, rendered_event)} { | ||
| 42 | // clang-format off | 41 | // clang-format off |
| 43 | static const FunctionInfo functions[] = { | 42 | static const FunctionInfo functions[] = { |
| 44 | {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, | 43 | {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, |
| @@ -243,10 +242,8 @@ class IAudioDevice final : public ServiceFramework<IAudioDevice> { | |||
| 243 | public: | 242 | public: |
| 244 | explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, | 243 | explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, |
| 245 | u32 device_num) | 244 | u32 device_num) |
| 246 | : ServiceFramework{system_, "IAudioDevice", ServiceThreadType::CreateNew}, | 245 | : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"}, |
| 247 | service_context{system_, "IAudioDevice"}, impl{std::make_unique<AudioDevice>( | 246 | impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)}, |
| 248 | system_, applet_resource_user_id, | ||
| 249 | revision)}, | ||
| 250 | event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { | 247 | event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { |
| 251 | static const FunctionInfo functions[] = { | 248 | static const FunctionInfo functions[] = { |
| 252 | {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, | 249 | {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, |
| @@ -421,7 +418,7 @@ private: | |||
| 421 | }; | 418 | }; |
| 422 | 419 | ||
| 423 | AudRenU::AudRenU(Core::System& system_) | 420 | AudRenU::AudRenU(Core::System& system_) |
| 424 | : ServiceFramework{system_, "audren:u", ServiceThreadType::CreateNew}, | 421 | : ServiceFramework{system_, "audren:u"}, |
| 425 | service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} { | 422 | service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} { |
| 426 | // clang-format off | 423 | // clang-format off |
| 427 | static const FunctionInfo functions[] = { | 424 | 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, | |||
| 93 | provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0); | 93 | provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0); |
| 94 | conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0); | 94 | conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0); |
| 95 | smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0); | 95 | smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0); |
| 96 | alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0); | ||
| 97 | alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0); | ||
| 96 | 98 | ||
| 97 | for (size_t i = 0; i < regs.rt.size(); ++i) { | 99 | for (size_t i = 0; i < regs.rt.size(); ++i) { |
| 98 | color_formats[i] = static_cast<u8>(regs.rt[i].format); | 100 | 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 { | |||
| 195 | BitField<12, 1, u32> provoking_vertex_last; | 195 | BitField<12, 1, u32> provoking_vertex_last; |
| 196 | BitField<13, 1, u32> conservative_raster_enable; | 196 | BitField<13, 1, u32> conservative_raster_enable; |
| 197 | BitField<14, 1, u32> smooth_lines; | 197 | BitField<14, 1, u32> smooth_lines; |
| 198 | BitField<15, 1, u32> alpha_to_coverage_enabled; | ||
| 199 | BitField<16, 1, u32> alpha_to_one_enabled; | ||
| 198 | }; | 200 | }; |
| 199 | std::array<u8, Maxwell::NumRenderTargets> color_formats; | 201 | std::array<u8, Maxwell::NumRenderTargets> color_formats; |
| 200 | 202 | ||
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 | |||
| 58 | case Tegra::Texture::WrapMode::Border: | 58 | case Tegra::Texture::WrapMode::Border: |
| 59 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; | 59 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; |
| 60 | case Tegra::Texture::WrapMode::Clamp: | 60 | case Tegra::Texture::WrapMode::Clamp: |
| 61 | if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { | 61 | if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { |
| 62 | // Nvidia's Vulkan driver defaults to GL_CLAMP on invalid enumerations, we can hack this | 62 | // Nvidia's Vulkan driver defaults to GL_CLAMP on invalid enumerations, we can hack this |
| 63 | // by sending an invalid enumeration. | 63 | // by sending an invalid enumeration. |
| 64 | return static_cast<VkSamplerAddressMode>(0xcafe); | 64 | 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: | |||
| 44 | }); | 44 | }); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | vk::DescriptorUpdateTemplateKHR CreateTemplate(VkDescriptorSetLayout descriptor_set_layout, | 47 | vk::DescriptorUpdateTemplate CreateTemplate(VkDescriptorSetLayout descriptor_set_layout, |
| 48 | VkPipelineLayout pipeline_layout, | 48 | VkPipelineLayout pipeline_layout, |
| 49 | bool use_push_descriptor) const { | 49 | bool use_push_descriptor) const { |
| 50 | if (entries.empty()) { | 50 | if (entries.empty()) { |
| 51 | return nullptr; | 51 | return nullptr; |
| 52 | } | 52 | } |
| 53 | const VkDescriptorUpdateTemplateType type = | 53 | const VkDescriptorUpdateTemplateType type = |
| 54 | use_push_descriptor ? VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR | 54 | use_push_descriptor ? VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR |
| 55 | : VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; | 55 | : VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; |
| 56 | return device->GetLogical().CreateDescriptorUpdateTemplateKHR({ | 56 | return device->GetLogical().CreateDescriptorUpdateTemplate({ |
| 57 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR, | 57 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, |
| 58 | .pNext = nullptr, | 58 | .pNext = nullptr, |
| 59 | .flags = 0, | 59 | .flags = 0, |
| 60 | .descriptorUpdateEntryCount = static_cast<u32>(entries.size()), | 60 | .descriptorUpdateEntryCount = static_cast<u32>(entries.size()), |
| @@ -129,7 +129,7 @@ private: | |||
| 129 | const Device* device{}; | 129 | const Device* device{}; |
| 130 | bool is_compute{}; | 130 | bool is_compute{}; |
| 131 | boost::container::small_vector<VkDescriptorSetLayoutBinding, 32> bindings; | 131 | boost::container::small_vector<VkDescriptorSetLayoutBinding, 32> bindings; |
| 132 | boost::container::small_vector<VkDescriptorUpdateTemplateEntryKHR, 32> entries; | 132 | boost::container::small_vector<VkDescriptorUpdateTemplateEntry, 32> entries; |
| 133 | u32 binding{}; | 133 | u32 binding{}; |
| 134 | u32 num_descriptors{}; | 134 | u32 num_descriptors{}; |
| 135 | size_t offset{}; | 135 | 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) { | |||
| 45 | // https://github.com/SaschaWillems/vulkan.gpuinfo.org/blob/5dddea46ea1120b0df14eef8f15ff8e318e35462/functions.php#L308-L314 | 45 | // https://github.com/SaschaWillems/vulkan.gpuinfo.org/blob/5dddea46ea1120b0df14eef8f15ff8e318e35462/functions.php#L308-L314 |
| 46 | const u32 version = device.GetDriverVersion(); | 46 | const u32 version = device.GetDriverVersion(); |
| 47 | 47 | ||
| 48 | if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { | 48 | if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY) { |
| 49 | const u32 major = (version >> 22) & 0x3ff; | 49 | const u32 major = (version >> 22) & 0x3ff; |
| 50 | const u32 minor = (version >> 14) & 0x0ff; | 50 | const u32 minor = (version >> 14) & 0x0ff; |
| 51 | const u32 secondary = (version >> 6) & 0x0ff; | 51 | const u32 secondary = (version >> 6) & 0x0ff; |
| 52 | const u32 tertiary = version & 0x003f; | 52 | const u32 tertiary = version & 0x003f; |
| 53 | return fmt::format("{}.{}.{}.{}", major, minor, secondary, tertiary); | 53 | return fmt::format("{}.{}.{}.{}", major, minor, secondary, tertiary); |
| 54 | } | 54 | } |
| 55 | if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR) { | 55 | if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { |
| 56 | const u32 major = version >> 14; | 56 | const u32 major = version >> 14; |
| 57 | const u32 minor = version & 0x3fff; | 57 | const u32 minor = version & 0x3fff; |
| 58 | return fmt::format("{}.{}", major, minor); | 58 | 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{ | |||
| 93 | .score = 2, | 93 | .score = 2, |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | constexpr VkDescriptorUpdateTemplateEntryKHR INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE{ | 96 | constexpr VkDescriptorUpdateTemplateEntry INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE{ |
| 97 | .dstBinding = 0, | 97 | .dstBinding = 0, |
| 98 | .dstArrayElement = 0, | 98 | .dstArrayElement = 0, |
| 99 | .descriptorCount = 2, | 99 | .descriptorCount = 2, |
| @@ -102,7 +102,7 @@ constexpr VkDescriptorUpdateTemplateEntryKHR INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMP | |||
| 102 | .stride = sizeof(DescriptorUpdateEntry), | 102 | .stride = sizeof(DescriptorUpdateEntry), |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | constexpr std::array<VkDescriptorUpdateTemplateEntryKHR, ASTC_NUM_BINDINGS> | 105 | constexpr std::array<VkDescriptorUpdateTemplateEntry, ASTC_NUM_BINDINGS> |
| 106 | ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{ | 106 | ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{ |
| 107 | { | 107 | { |
| 108 | .dstBinding = ASTC_BINDING_INPUT_BUFFER, | 108 | .dstBinding = ASTC_BINDING_INPUT_BUFFER, |
| @@ -134,7 +134,7 @@ struct AstcPushConstants { | |||
| 134 | 134 | ||
| 135 | ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool, | 135 | ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool, |
| 136 | vk::Span<VkDescriptorSetLayoutBinding> bindings, | 136 | vk::Span<VkDescriptorSetLayoutBinding> bindings, |
| 137 | vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates, | 137 | vk::Span<VkDescriptorUpdateTemplateEntry> templates, |
| 138 | const DescriptorBankInfo& bank_info, | 138 | const DescriptorBankInfo& bank_info, |
| 139 | vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code) | 139 | vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code) |
| 140 | : device{device_} { | 140 | : device{device_} { |
| @@ -155,13 +155,13 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool, | |||
| 155 | .pPushConstantRanges = push_constants.data(), | 155 | .pPushConstantRanges = push_constants.data(), |
| 156 | }); | 156 | }); |
| 157 | if (!templates.empty()) { | 157 | if (!templates.empty()) { |
| 158 | descriptor_template = device.GetLogical().CreateDescriptorUpdateTemplateKHR({ | 158 | descriptor_template = device.GetLogical().CreateDescriptorUpdateTemplate({ |
| 159 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR, | 159 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, |
| 160 | .pNext = nullptr, | 160 | .pNext = nullptr, |
| 161 | .flags = 0, | 161 | .flags = 0, |
| 162 | .descriptorUpdateEntryCount = templates.size(), | 162 | .descriptorUpdateEntryCount = templates.size(), |
| 163 | .pDescriptorUpdateEntries = templates.data(), | 163 | .pDescriptorUpdateEntries = templates.data(), |
| 164 | .templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR, | 164 | .templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, |
| 165 | .descriptorSetLayout = *descriptor_set_layout, | 165 | .descriptorSetLayout = *descriptor_set_layout, |
| 166 | .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, | 166 | .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, |
| 167 | .pipelineLayout = *layout, | 167 | .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 { | |||
| 29 | public: | 29 | public: |
| 30 | explicit ComputePass(const Device& device, DescriptorPool& descriptor_pool, | 30 | explicit ComputePass(const Device& device, DescriptorPool& descriptor_pool, |
| 31 | vk::Span<VkDescriptorSetLayoutBinding> bindings, | 31 | vk::Span<VkDescriptorSetLayoutBinding> bindings, |
| 32 | vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates, | 32 | vk::Span<VkDescriptorUpdateTemplateEntry> templates, |
| 33 | const DescriptorBankInfo& bank_info, | 33 | const DescriptorBankInfo& bank_info, |
| 34 | vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code); | 34 | vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code); |
| 35 | ~ComputePass(); | 35 | ~ComputePass(); |
| 36 | 36 | ||
| 37 | protected: | 37 | protected: |
| 38 | const Device& device; | 38 | const Device& device; |
| 39 | vk::DescriptorUpdateTemplateKHR descriptor_template; | 39 | vk::DescriptorUpdateTemplate descriptor_template; |
| 40 | vk::PipelineLayout layout; | 40 | vk::PipelineLayout layout; |
| 41 | vk::Pipeline pipeline; | 41 | vk::Pipeline pipeline; |
| 42 | vk::DescriptorSetLayout descriptor_set_layout; | 42 | 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 | |||
| 53 | .requiredSubgroupSize = GuestWarpSize, | 53 | .requiredSubgroupSize = GuestWarpSize, |
| 54 | }; | 54 | }; |
| 55 | VkPipelineCreateFlags flags{}; | 55 | VkPipelineCreateFlags flags{}; |
| 56 | if (device.IsKhrPipelineEexecutablePropertiesEnabled()) { | 56 | if (device.IsKhrPipelineExecutablePropertiesEnabled()) { |
| 57 | flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR; | 57 | flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR; |
| 58 | } | 58 | } |
| 59 | pipeline = device.GetLogical().CreateComputePipeline({ | 59 | 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: | |||
| 55 | vk::DescriptorSetLayout descriptor_set_layout; | 55 | vk::DescriptorSetLayout descriptor_set_layout; |
| 56 | DescriptorAllocator descriptor_allocator; | 56 | DescriptorAllocator descriptor_allocator; |
| 57 | vk::PipelineLayout pipeline_layout; | 57 | vk::PipelineLayout pipeline_layout; |
| 58 | vk::DescriptorUpdateTemplateKHR descriptor_update_template; | 58 | vk::DescriptorUpdateTemplate descriptor_update_template; |
| 59 | vk::Pipeline pipeline; | 59 | vk::Pipeline pipeline; |
| 60 | 60 | ||
| 61 | std::condition_variable build_condvar; | 61 | 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) { | |||
| 714 | .sampleShadingEnable = VK_FALSE, | 714 | .sampleShadingEnable = VK_FALSE, |
| 715 | .minSampleShading = 0.0f, | 715 | .minSampleShading = 0.0f, |
| 716 | .pSampleMask = nullptr, | 716 | .pSampleMask = nullptr, |
| 717 | .alphaToCoverageEnable = VK_FALSE, | 717 | .alphaToCoverageEnable = key.state.alpha_to_coverage_enabled != 0 ? VK_TRUE : VK_FALSE, |
| 718 | .alphaToOneEnable = VK_FALSE, | 718 | .alphaToOneEnable = key.state.alpha_to_one_enabled != 0 ? VK_TRUE : VK_FALSE, |
| 719 | }; | 719 | }; |
| 720 | const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{ | 720 | const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{ |
| 721 | .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, | 721 | .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, |
| @@ -830,7 +830,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 830 | */ | 830 | */ |
| 831 | } | 831 | } |
| 832 | VkPipelineCreateFlags flags{}; | 832 | VkPipelineCreateFlags flags{}; |
| 833 | if (device.IsKhrPipelineEexecutablePropertiesEnabled()) { | 833 | if (device.IsKhrPipelineExecutablePropertiesEnabled()) { |
| 834 | flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR; | 834 | flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR; |
| 835 | } | 835 | } |
| 836 | pipeline = device.GetLogical().CreateGraphicsPipeline({ | 836 | 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: | |||
| 151 | vk::DescriptorSetLayout descriptor_set_layout; | 151 | vk::DescriptorSetLayout descriptor_set_layout; |
| 152 | DescriptorAllocator descriptor_allocator; | 152 | DescriptorAllocator descriptor_allocator; |
| 153 | vk::PipelineLayout pipeline_layout; | 153 | vk::PipelineLayout pipeline_layout; |
| 154 | vk::DescriptorUpdateTemplateKHR descriptor_update_template; | 154 | vk::DescriptorUpdateTemplate descriptor_update_template; |
| 155 | vk::Pipeline pipeline; | 155 | vk::Pipeline pipeline; |
| 156 | 156 | ||
| 157 | std::condition_variable build_condvar; | 157 | 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 @@ | |||
| 11 | namespace Vulkan { | 11 | namespace Vulkan { |
| 12 | 12 | ||
| 13 | MasterSemaphore::MasterSemaphore(const Device& device) { | 13 | MasterSemaphore::MasterSemaphore(const Device& device) { |
| 14 | static constexpr VkSemaphoreTypeCreateInfoKHR semaphore_type_ci{ | 14 | static constexpr VkSemaphoreTypeCreateInfo semaphore_type_ci{ |
| 15 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR, | 15 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, |
| 16 | .pNext = nullptr, | 16 | .pNext = nullptr, |
| 17 | .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR, | 17 | .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, |
| 18 | .initialValue = 0, | 18 | .initialValue = 0, |
| 19 | }; | 19 | }; |
| 20 | static constexpr VkSemaphoreCreateInfo semaphore_ci{ | 20 | static constexpr VkSemaphoreCreateInfo semaphore_ci{ |
| @@ -28,7 +28,7 @@ MasterSemaphore::MasterSemaphore(const Device& device) { | |||
| 28 | return; | 28 | return; |
| 29 | } | 29 | } |
| 30 | // Validation layers have a bug where they fail to track resource usage when using timeline | 30 | // Validation layers have a bug where they fail to track resource usage when using timeline |
| 31 | // semaphores and synchronizing with GetSemaphoreCounterValueKHR. To workaround this issue, have | 31 | // semaphores and synchronizing with GetSemaphoreCounterValue. To workaround this issue, have |
| 32 | // a separate thread waiting for each timeline semaphore value. | 32 | // a separate thread waiting for each timeline semaphore value. |
| 33 | debug_thread = std::jthread([this](std::stop_token stop_token) { | 33 | debug_thread = std::jthread([this](std::stop_token stop_token) { |
| 34 | u64 counter = 0; | 34 | 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 | |||
| 287 | workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"), | 287 | workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"), |
| 288 | serialization_thread(1, "VkPipelineSerialization") { | 288 | serialization_thread(1, "VkPipelineSerialization") { |
| 289 | const auto& float_control{device.FloatControlProperties()}; | 289 | const auto& float_control{device.FloatControlProperties()}; |
| 290 | const VkDriverIdKHR driver_id{device.GetDriverID()}; | 290 | const VkDriverId driver_id{device.GetDriverID()}; |
| 291 | profile = Shader::Profile{ | 291 | profile = Shader::Profile{ |
| 292 | .supported_spirv = device.SupportedSpirvVersion(), | 292 | .supported_spirv = device.SupportedSpirvVersion(), |
| 293 | .unified_descriptor_binding = true, | 293 | .unified_descriptor_binding = true, |
| @@ -297,10 +297,10 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device | |||
| 297 | .support_int64 = device.IsShaderInt64Supported(), | 297 | .support_int64 = device.IsShaderInt64Supported(), |
| 298 | .support_vertex_instance_id = false, | 298 | .support_vertex_instance_id = false, |
| 299 | .support_float_controls = true, | 299 | .support_float_controls = true, |
| 300 | .support_separate_denorm_behavior = float_control.denormBehaviorIndependence == | 300 | .support_separate_denorm_behavior = |
| 301 | VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR, | 301 | float_control.denormBehaviorIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, |
| 302 | .support_separate_rounding_mode = | 302 | .support_separate_rounding_mode = |
| 303 | float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR, | 303 | float_control.roundingModeIndependence == VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, |
| 304 | .support_fp16_denorm_preserve = float_control.shaderDenormPreserveFloat16 != VK_FALSE, | 304 | .support_fp16_denorm_preserve = float_control.shaderDenormPreserveFloat16 != VK_FALSE, |
| 305 | .support_fp32_denorm_preserve = float_control.shaderDenormPreserveFloat32 != VK_FALSE, | 305 | .support_fp32_denorm_preserve = float_control.shaderDenormPreserveFloat32 != VK_FALSE, |
| 306 | .support_fp16_denorm_flush = float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE, | 306 | .support_fp16_denorm_flush = float_control.shaderDenormFlushToZeroFloat16 != VK_FALSE, |
| @@ -327,17 +327,17 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device | |||
| 327 | .lower_left_origin_mode = false, | 327 | .lower_left_origin_mode = false, |
| 328 | .need_declared_frag_colors = false, | 328 | .need_declared_frag_colors = false, |
| 329 | 329 | ||
| 330 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, | 330 | .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, |
| 331 | .has_broken_unsigned_image_offsets = false, | 331 | .has_broken_unsigned_image_offsets = false, |
| 332 | .has_broken_signed_operations = false, | 332 | .has_broken_signed_operations = false, |
| 333 | .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, | 333 | .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY, |
| 334 | .ignore_nan_fp_comparisons = false, | 334 | .ignore_nan_fp_comparisons = false, |
| 335 | }; | 335 | }; |
| 336 | host_info = Shader::HostTranslateInfo{ | 336 | host_info = Shader::HostTranslateInfo{ |
| 337 | .support_float16 = device.IsFloat16Supported(), | 337 | .support_float16 = device.IsFloat16Supported(), |
| 338 | .support_int64 = device.IsShaderInt64Supported(), | 338 | .support_int64 = device.IsShaderInt64Supported(), |
| 339 | .needs_demote_reorder = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR || | 339 | .needs_demote_reorder = |
| 340 | driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, | 340 | driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE, |
| 341 | .support_snorm_render_buffer = true, | 341 | .support_snorm_render_buffer = true, |
| 342 | .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(), | 342 | .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(), |
| 343 | }; | 343 | }; |
| @@ -408,7 +408,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading | |||
| 408 | std::unique_ptr<PipelineStatistics> statistics; | 408 | std::unique_ptr<PipelineStatistics> statistics; |
| 409 | } state; | 409 | } state; |
| 410 | 410 | ||
| 411 | if (device.IsKhrPipelineEexecutablePropertiesEnabled()) { | 411 | if (device.IsKhrPipelineExecutablePropertiesEnabled()) { |
| 412 | state.statistics = std::make_unique<PipelineStatistics>(device); | 412 | state.statistics = std::make_unique<PipelineStatistics>(device); |
| 413 | } | 413 | } |
| 414 | const auto load_compute{[&](std::ifstream& file, FileEnvironment env) { | 414 | 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 | |||
| 98 | query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} { | 98 | query{cache_.AllocateQuery(type_)}, tick{cache_.GetScheduler().CurrentTick()} { |
| 99 | const vk::Device* logical = &cache.GetDevice().GetLogical(); | 99 | const vk::Device* logical = &cache.GetDevice().GetLogical(); |
| 100 | cache.GetScheduler().Record([logical, query = query](vk::CommandBuffer cmdbuf) { | 100 | cache.GetScheduler().Record([logical, query = query](vk::CommandBuffer cmdbuf) { |
| 101 | logical->ResetQueryPoolEXT(query.first, query.second, 1); | 101 | logical->ResetQueryPool(query.first, query.second, 1); |
| 102 | cmdbuf.BeginQuery(query.first, query.second, VK_QUERY_CONTROL_PRECISE_BIT); | 102 | cmdbuf.BeginQuery(query.first, query.second, VK_QUERY_CONTROL_PRECISE_BIT); |
| 103 | }); | 103 | }); |
| 104 | } | 104 | } |
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 | |||
| 194 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, | 194 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| 195 | }; | 195 | }; |
| 196 | 196 | ||
| 197 | const VkTimelineSemaphoreSubmitInfoKHR timeline_si{ | 197 | const VkTimelineSemaphoreSubmitInfo timeline_si{ |
| 198 | .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, | 198 | .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, |
| 199 | .pNext = nullptr, | 199 | .pNext = nullptr, |
| 200 | .waitSemaphoreValueCount = num_wait_semaphores, | 200 | .waitSemaphoreValueCount = num_wait_semaphores, |
| 201 | .pWaitSemaphoreValues = wait_values.data(), | 201 | .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 { | |||
| 77 | constexpr std::array REQUIRED_EXTENSIONS{ | 77 | constexpr std::array REQUIRED_EXTENSIONS{ |
| 78 | VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, | 78 | VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, |
| 79 | VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, | 79 | VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, |
| 80 | |||
| 81 | // Core in 1.2, but required due to use of extension methods, | ||
| 82 | // and well-supported by drivers | ||
| 83 | VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, | ||
| 84 | VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, | ||
| 85 | VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, | ||
| 86 | #ifdef _WIN32 | 80 | #ifdef _WIN32 |
| 87 | VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, | 81 | VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, |
| 88 | #endif | 82 | #endif |
| @@ -311,10 +305,10 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical, | |||
| 311 | VkPhysicalDeviceFragmentShadingRatePropertiesKHR shading_rate_props{}; | 305 | VkPhysicalDeviceFragmentShadingRatePropertiesKHR shading_rate_props{}; |
| 312 | shading_rate_props.sType = | 306 | shading_rate_props.sType = |
| 313 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR; | 307 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR; |
| 314 | VkPhysicalDeviceProperties2KHR physical_properties{}; | 308 | VkPhysicalDeviceProperties2 physical_properties{}; |
| 315 | physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; | 309 | physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; |
| 316 | physical_properties.pNext = &shading_rate_props; | 310 | physical_properties.pNext = &shading_rate_props; |
| 317 | physical.GetProperties2KHR(physical_properties); | 311 | physical.GetProperties2(physical_properties); |
| 318 | if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) { | 312 | if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) { |
| 319 | // Only Ampere and newer support this feature | 313 | // Only Ampere and newer support this feature |
| 320 | return NvidiaArchitecture::AmpereOrNewer; | 314 | return NvidiaArchitecture::AmpereOrNewer; |
| @@ -405,15 +399,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 405 | const void* first_next = &features2; | 399 | const void* first_next = &features2; |
| 406 | void** next = &features2.pNext; | 400 | void** next = &features2.pNext; |
| 407 | 401 | ||
| 408 | VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore{ | 402 | VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore{ |
| 409 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR, | 403 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, |
| 410 | .pNext = nullptr, | 404 | .pNext = nullptr, |
| 411 | .timelineSemaphore = true, | 405 | .timelineSemaphore = true, |
| 412 | }; | 406 | }; |
| 413 | SetNext(next, timeline_semaphore); | 407 | SetNext(next, timeline_semaphore); |
| 414 | 408 | ||
| 415 | VkPhysicalDevice16BitStorageFeaturesKHR bit16_storage{ | 409 | VkPhysicalDevice16BitStorageFeatures bit16_storage{ |
| 416 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR, | 410 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, |
| 417 | .pNext = nullptr, | 411 | .pNext = nullptr, |
| 418 | .storageBuffer16BitAccess = true, | 412 | .storageBuffer16BitAccess = true, |
| 419 | .uniformAndStorageBuffer16BitAccess = true, | 413 | .uniformAndStorageBuffer16BitAccess = true, |
| @@ -422,8 +416,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 422 | }; | 416 | }; |
| 423 | SetNext(next, bit16_storage); | 417 | SetNext(next, bit16_storage); |
| 424 | 418 | ||
| 425 | VkPhysicalDevice8BitStorageFeaturesKHR bit8_storage{ | 419 | VkPhysicalDevice8BitStorageFeatures bit8_storage{ |
| 426 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, | 420 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, |
| 427 | .pNext = nullptr, | 421 | .pNext = nullptr, |
| 428 | .storageBuffer8BitAccess = false, | 422 | .storageBuffer8BitAccess = false, |
| 429 | .uniformAndStorageBuffer8BitAccess = true, | 423 | .uniformAndStorageBuffer8BitAccess = true, |
| @@ -440,15 +434,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 440 | }; | 434 | }; |
| 441 | SetNext(next, robustness2); | 435 | SetNext(next, robustness2); |
| 442 | 436 | ||
| 443 | VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset{ | 437 | VkPhysicalDeviceHostQueryResetFeatures host_query_reset{ |
| 444 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT, | 438 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, |
| 445 | .pNext = nullptr, | 439 | .pNext = nullptr, |
| 446 | .hostQueryReset = true, | 440 | .hostQueryReset = true, |
| 447 | }; | 441 | }; |
| 448 | SetNext(next, host_query_reset); | 442 | SetNext(next, host_query_reset); |
| 449 | 443 | ||
| 450 | VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers{ | 444 | VkPhysicalDeviceVariablePointerFeatures variable_pointers{ |
| 451 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, | 445 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, |
| 452 | .pNext = nullptr, | 446 | .pNext = nullptr, |
| 453 | .variablePointersStorageBuffer = VK_TRUE, | 447 | .variablePointersStorageBuffer = VK_TRUE, |
| 454 | .variablePointers = VK_TRUE, | 448 | .variablePointers = VK_TRUE, |
| @@ -462,10 +456,17 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 462 | }; | 456 | }; |
| 463 | SetNext(next, demote); | 457 | SetNext(next, demote); |
| 464 | 458 | ||
| 465 | VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8; | 459 | VkPhysicalDeviceShaderDrawParametersFeatures draw_parameters{ |
| 460 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES, | ||
| 461 | .pNext = nullptr, | ||
| 462 | .shaderDrawParameters = true, | ||
| 463 | }; | ||
| 464 | SetNext(next, draw_parameters); | ||
| 465 | |||
| 466 | VkPhysicalDeviceShaderFloat16Int8Features float16_int8; | ||
| 466 | if (is_int8_supported || is_float16_supported) { | 467 | if (is_int8_supported || is_float16_supported) { |
| 467 | float16_int8 = { | 468 | float16_int8 = { |
| 468 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, | 469 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, |
| 469 | .pNext = nullptr, | 470 | .pNext = nullptr, |
| 470 | .shaderFloat16 = is_float16_supported, | 471 | .shaderFloat16 = is_float16_supported, |
| 471 | .shaderInt8 = is_int8_supported, | 472 | .shaderInt8 = is_int8_supported, |
| @@ -491,10 +492,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 491 | LOG_INFO(Render_Vulkan, "Device doesn't support passthrough geometry shaders"); | 492 | LOG_INFO(Render_Vulkan, "Device doesn't support passthrough geometry shaders"); |
| 492 | } | 493 | } |
| 493 | 494 | ||
| 494 | VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout; | 495 | VkPhysicalDeviceUniformBufferStandardLayoutFeatures std430_layout; |
| 495 | if (khr_uniform_buffer_standard_layout) { | 496 | if (khr_uniform_buffer_standard_layout) { |
| 496 | std430_layout = { | 497 | std430_layout = { |
| 497 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR, | 498 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, |
| 498 | .pNext = nullptr, | 499 | .pNext = nullptr, |
| 499 | .uniformBufferStandardLayout = true, | 500 | .uniformBufferStandardLayout = true, |
| 500 | }; | 501 | }; |
| @@ -612,10 +613,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 612 | LOG_INFO(Render_Vulkan, "Device doesn't support vertex input dynamic state"); | 613 | LOG_INFO(Render_Vulkan, "Device doesn't support vertex input dynamic state"); |
| 613 | } | 614 | } |
| 614 | 615 | ||
| 615 | VkPhysicalDeviceShaderAtomicInt64FeaturesKHR atomic_int64; | 616 | VkPhysicalDeviceShaderAtomicInt64Features atomic_int64; |
| 616 | if (ext_shader_atomic_int64) { | 617 | if (ext_shader_atomic_int64) { |
| 617 | atomic_int64 = { | 618 | atomic_int64 = { |
| 618 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR, | 619 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, |
| 619 | .pNext = nullptr, | 620 | .pNext = nullptr, |
| 620 | .shaderBufferInt64Atomics = VK_TRUE, | 621 | .shaderBufferInt64Atomics = VK_TRUE, |
| 621 | .shaderSharedInt64Atomics = VK_TRUE, | 622 | .shaderSharedInt64Atomics = VK_TRUE, |
| @@ -971,22 +972,42 @@ void Device::CheckSuitability(bool requires_swapchain) const { | |||
| 971 | demote.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES; | 972 | demote.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES; |
| 972 | demote.pNext = nullptr; | 973 | demote.pNext = nullptr; |
| 973 | 974 | ||
| 974 | VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers{}; | 975 | VkPhysicalDeviceVariablePointerFeatures variable_pointers{}; |
| 975 | variable_pointers.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR; | 976 | variable_pointers.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES; |
| 976 | variable_pointers.pNext = &demote; | 977 | variable_pointers.pNext = &demote; |
| 977 | 978 | ||
| 978 | VkPhysicalDeviceRobustness2FeaturesEXT robustness2{}; | 979 | VkPhysicalDeviceRobustness2FeaturesEXT robustness2{}; |
| 979 | robustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; | 980 | robustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; |
| 980 | robustness2.pNext = &variable_pointers; | 981 | robustness2.pNext = &variable_pointers; |
| 981 | 982 | ||
| 982 | VkPhysicalDeviceFeatures2KHR features2{}; | 983 | VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore{}; |
| 984 | timeline_semaphore.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES; | ||
| 985 | timeline_semaphore.pNext = &robustness2; | ||
| 986 | |||
| 987 | VkPhysicalDevice16BitStorageFeatures bit16_storage{}; | ||
| 988 | bit16_storage.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; | ||
| 989 | bit16_storage.pNext = &timeline_semaphore; | ||
| 990 | |||
| 991 | VkPhysicalDevice8BitStorageFeatures bit8_storage{}; | ||
| 992 | bit8_storage.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES; | ||
| 993 | bit8_storage.pNext = &bit16_storage; | ||
| 994 | |||
| 995 | VkPhysicalDeviceHostQueryResetFeatures host_query_reset{}; | ||
| 996 | host_query_reset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES; | ||
| 997 | host_query_reset.pNext = &bit8_storage; | ||
| 998 | |||
| 999 | VkPhysicalDeviceShaderDrawParametersFeatures draw_parameters{}; | ||
| 1000 | draw_parameters.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES; | ||
| 1001 | draw_parameters.pNext = &host_query_reset; | ||
| 1002 | |||
| 1003 | VkPhysicalDeviceFeatures2 features2{}; | ||
| 983 | features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; | 1004 | features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; |
| 984 | features2.pNext = &robustness2; | 1005 | features2.pNext = &draw_parameters; |
| 985 | 1006 | ||
| 986 | physical.GetFeatures2KHR(features2); | 1007 | physical.GetFeatures2(features2); |
| 987 | 1008 | ||
| 988 | const VkPhysicalDeviceFeatures& features{features2.features}; | 1009 | const VkPhysicalDeviceFeatures& features{features2.features}; |
| 989 | std::vector feature_report{ | 1010 | std::array feature_report{ |
| 990 | std::make_pair(features.robustBufferAccess, "robustBufferAccess"), | 1011 | std::make_pair(features.robustBufferAccess, "robustBufferAccess"), |
| 991 | std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"), | 1012 | std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"), |
| 992 | std::make_pair(features.imageCubeArray, "imageCubeArray"), | 1013 | std::make_pair(features.imageCubeArray, "imageCubeArray"), |
| @@ -1002,6 +1023,7 @@ void Device::CheckSuitability(bool requires_swapchain) const { | |||
| 1002 | std::make_pair(features.tessellationShader, "tessellationShader"), | 1023 | std::make_pair(features.tessellationShader, "tessellationShader"), |
| 1003 | std::make_pair(features.sampleRateShading, "sampleRateShading"), | 1024 | std::make_pair(features.sampleRateShading, "sampleRateShading"), |
| 1004 | std::make_pair(features.dualSrcBlend, "dualSrcBlend"), | 1025 | std::make_pair(features.dualSrcBlend, "dualSrcBlend"), |
| 1026 | std::make_pair(features.logicOp, "logicOp"), | ||
| 1005 | std::make_pair(features.occlusionQueryPrecise, "occlusionQueryPrecise"), | 1027 | std::make_pair(features.occlusionQueryPrecise, "occlusionQueryPrecise"), |
| 1006 | std::make_pair(features.fragmentStoresAndAtomics, "fragmentStoresAndAtomics"), | 1028 | std::make_pair(features.fragmentStoresAndAtomics, "fragmentStoresAndAtomics"), |
| 1007 | std::make_pair(features.shaderImageGatherExtended, "shaderImageGatherExtended"), | 1029 | std::make_pair(features.shaderImageGatherExtended, "shaderImageGatherExtended"), |
| @@ -1016,6 +1038,14 @@ void Device::CheckSuitability(bool requires_swapchain) const { | |||
| 1016 | std::make_pair(robustness2.robustImageAccess2, "robustImageAccess2"), | 1038 | std::make_pair(robustness2.robustImageAccess2, "robustImageAccess2"), |
| 1017 | std::make_pair(robustness2.nullDescriptor, "nullDescriptor"), | 1039 | std::make_pair(robustness2.nullDescriptor, "nullDescriptor"), |
| 1018 | std::make_pair(demote.shaderDemoteToHelperInvocation, "shaderDemoteToHelperInvocation"), | 1040 | std::make_pair(demote.shaderDemoteToHelperInvocation, "shaderDemoteToHelperInvocation"), |
| 1041 | std::make_pair(timeline_semaphore.timelineSemaphore, "timelineSemaphore"), | ||
| 1042 | std::make_pair(bit16_storage.storageBuffer16BitAccess, "storageBuffer16BitAccess"), | ||
| 1043 | std::make_pair(bit16_storage.uniformAndStorageBuffer16BitAccess, | ||
| 1044 | "uniformAndStorageBuffer16BitAccess"), | ||
| 1045 | std::make_pair(bit8_storage.uniformAndStorageBuffer8BitAccess, | ||
| 1046 | "uniformAndStorageBuffer8BitAccess"), | ||
| 1047 | std::make_pair(host_query_reset.hostQueryReset, "hostQueryReset"), | ||
| 1048 | std::make_pair(draw_parameters.shaderDrawParameters, "shaderDrawParameters"), | ||
| 1019 | }; | 1049 | }; |
| 1020 | 1050 | ||
| 1021 | bool has_all_required_features = true; | 1051 | bool has_all_required_features = true; |
| @@ -1108,37 +1138,37 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1108 | VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME, false); | 1138 | VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME, false); |
| 1109 | } | 1139 | } |
| 1110 | } | 1140 | } |
| 1111 | VkPhysicalDeviceFeatures2KHR features{}; | 1141 | VkPhysicalDeviceFeatures2 features{}; |
| 1112 | features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; | 1142 | features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; |
| 1113 | 1143 | ||
| 1114 | VkPhysicalDeviceProperties2KHR physical_properties{}; | 1144 | VkPhysicalDeviceProperties2 physical_properties{}; |
| 1115 | physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; | 1145 | physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; |
| 1116 | 1146 | ||
| 1117 | if (has_khr_shader_float16_int8) { | 1147 | if (has_khr_shader_float16_int8) { |
| 1118 | VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_features; | 1148 | VkPhysicalDeviceShaderFloat16Int8Features float16_int8_features; |
| 1119 | float16_int8_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; | 1149 | float16_int8_features.sType = |
| 1150 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES; | ||
| 1120 | float16_int8_features.pNext = nullptr; | 1151 | float16_int8_features.pNext = nullptr; |
| 1121 | features.pNext = &float16_int8_features; | 1152 | features.pNext = &float16_int8_features; |
| 1122 | 1153 | ||
| 1123 | physical.GetFeatures2KHR(features); | 1154 | physical.GetFeatures2(features); |
| 1124 | is_float16_supported = float16_int8_features.shaderFloat16; | 1155 | is_float16_supported = float16_int8_features.shaderFloat16; |
| 1125 | is_int8_supported = float16_int8_features.shaderInt8; | 1156 | is_int8_supported = float16_int8_features.shaderInt8; |
| 1126 | extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); | 1157 | extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); |
| 1127 | } | 1158 | } |
| 1128 | if (has_ext_subgroup_size_control) { | 1159 | if (has_ext_subgroup_size_control) { |
| 1129 | VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroup_features; | 1160 | VkPhysicalDeviceSubgroupSizeControlFeatures subgroup_features; |
| 1130 | subgroup_features.sType = | 1161 | subgroup_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES; |
| 1131 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT; | ||
| 1132 | subgroup_features.pNext = nullptr; | 1162 | subgroup_features.pNext = nullptr; |
| 1133 | features.pNext = &subgroup_features; | 1163 | features.pNext = &subgroup_features; |
| 1134 | physical.GetFeatures2KHR(features); | 1164 | physical.GetFeatures2(features); |
| 1135 | 1165 | ||
| 1136 | VkPhysicalDeviceSubgroupSizeControlPropertiesEXT subgroup_properties; | 1166 | VkPhysicalDeviceSubgroupSizeControlProperties subgroup_properties; |
| 1137 | subgroup_properties.sType = | 1167 | subgroup_properties.sType = |
| 1138 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT; | 1168 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES; |
| 1139 | subgroup_properties.pNext = nullptr; | 1169 | subgroup_properties.pNext = nullptr; |
| 1140 | physical_properties.pNext = &subgroup_properties; | 1170 | physical_properties.pNext = &subgroup_properties; |
| 1141 | physical.GetProperties2KHR(physical_properties); | 1171 | physical.GetProperties2(physical_properties); |
| 1142 | 1172 | ||
| 1143 | is_warp_potentially_bigger = subgroup_properties.maxSubgroupSize > GuestWarpSize; | 1173 | is_warp_potentially_bigger = subgroup_properties.maxSubgroupSize > GuestWarpSize; |
| 1144 | 1174 | ||
| @@ -1157,7 +1187,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1157 | provoking_vertex.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT; | 1187 | provoking_vertex.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT; |
| 1158 | provoking_vertex.pNext = nullptr; | 1188 | provoking_vertex.pNext = nullptr; |
| 1159 | features.pNext = &provoking_vertex; | 1189 | features.pNext = &provoking_vertex; |
| 1160 | physical.GetFeatures2KHR(features); | 1190 | physical.GetFeatures2(features); |
| 1161 | 1191 | ||
| 1162 | if (provoking_vertex.provokingVertexLast && | 1192 | if (provoking_vertex.provokingVertexLast && |
| 1163 | provoking_vertex.transformFeedbackPreservesProvokingVertex) { | 1193 | provoking_vertex.transformFeedbackPreservesProvokingVertex) { |
| @@ -1171,7 +1201,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1171 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT; | 1201 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT; |
| 1172 | vertex_input.pNext = nullptr; | 1202 | vertex_input.pNext = nullptr; |
| 1173 | features.pNext = &vertex_input; | 1203 | features.pNext = &vertex_input; |
| 1174 | physical.GetFeatures2KHR(features); | 1204 | physical.GetFeatures2(features); |
| 1175 | 1205 | ||
| 1176 | if (vertex_input.vertexInputDynamicState) { | 1206 | if (vertex_input.vertexInputDynamicState) { |
| 1177 | extensions.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); | 1207 | extensions.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); |
| @@ -1183,7 +1213,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1183 | atomic_int64.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES; | 1213 | atomic_int64.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES; |
| 1184 | atomic_int64.pNext = nullptr; | 1214 | atomic_int64.pNext = nullptr; |
| 1185 | features.pNext = &atomic_int64; | 1215 | features.pNext = &atomic_int64; |
| 1186 | physical.GetFeatures2KHR(features); | 1216 | physical.GetFeatures2(features); |
| 1187 | 1217 | ||
| 1188 | if (atomic_int64.shaderBufferInt64Atomics && atomic_int64.shaderSharedInt64Atomics) { | 1218 | if (atomic_int64.shaderBufferInt64Atomics && atomic_int64.shaderSharedInt64Atomics) { |
| 1189 | extensions.push_back(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); | 1219 | extensions.push_back(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); |
| @@ -1195,13 +1225,13 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1195 | tfb_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; | 1225 | tfb_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; |
| 1196 | tfb_features.pNext = nullptr; | 1226 | tfb_features.pNext = nullptr; |
| 1197 | features.pNext = &tfb_features; | 1227 | features.pNext = &tfb_features; |
| 1198 | physical.GetFeatures2KHR(features); | 1228 | physical.GetFeatures2(features); |
| 1199 | 1229 | ||
| 1200 | VkPhysicalDeviceTransformFeedbackPropertiesEXT tfb_properties; | 1230 | VkPhysicalDeviceTransformFeedbackPropertiesEXT tfb_properties; |
| 1201 | tfb_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; | 1231 | tfb_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; |
| 1202 | tfb_properties.pNext = nullptr; | 1232 | tfb_properties.pNext = nullptr; |
| 1203 | physical_properties.pNext = &tfb_properties; | 1233 | physical_properties.pNext = &tfb_properties; |
| 1204 | physical.GetProperties2KHR(physical_properties); | 1234 | physical.GetProperties2(physical_properties); |
| 1205 | 1235 | ||
| 1206 | if (tfb_features.transformFeedback && tfb_features.geometryStreams && | 1236 | if (tfb_features.transformFeedback && tfb_features.geometryStreams && |
| 1207 | tfb_properties.maxTransformFeedbackStreams >= 4 && | 1237 | tfb_properties.maxTransformFeedbackStreams >= 4 && |
| @@ -1216,7 +1246,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1216 | border_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; | 1246 | border_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; |
| 1217 | border_features.pNext = nullptr; | 1247 | border_features.pNext = nullptr; |
| 1218 | features.pNext = &border_features; | 1248 | features.pNext = &border_features; |
| 1219 | physical.GetFeatures2KHR(features); | 1249 | physical.GetFeatures2(features); |
| 1220 | 1250 | ||
| 1221 | if (border_features.customBorderColors && border_features.customBorderColorWithoutFormat) { | 1251 | if (border_features.customBorderColors && border_features.customBorderColorWithoutFormat) { |
| 1222 | extensions.push_back(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); | 1252 | extensions.push_back(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); |
| @@ -1229,7 +1259,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1229 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; | 1259 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; |
| 1230 | extended_dynamic_state.pNext = nullptr; | 1260 | extended_dynamic_state.pNext = nullptr; |
| 1231 | features.pNext = &extended_dynamic_state; | 1261 | features.pNext = &extended_dynamic_state; |
| 1232 | physical.GetFeatures2KHR(features); | 1262 | physical.GetFeatures2(features); |
| 1233 | 1263 | ||
| 1234 | if (extended_dynamic_state.extendedDynamicState) { | 1264 | if (extended_dynamic_state.extendedDynamicState) { |
| 1235 | extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); | 1265 | extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); |
| @@ -1241,7 +1271,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1241 | line_raster.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT; | 1271 | line_raster.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT; |
| 1242 | line_raster.pNext = nullptr; | 1272 | line_raster.pNext = nullptr; |
| 1243 | features.pNext = &line_raster; | 1273 | features.pNext = &line_raster; |
| 1244 | physical.GetFeatures2KHR(features); | 1274 | physical.GetFeatures2(features); |
| 1245 | if (line_raster.rectangularLines && line_raster.smoothLines) { | 1275 | if (line_raster.rectangularLines && line_raster.smoothLines) { |
| 1246 | extensions.push_back(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); | 1276 | extensions.push_back(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME); |
| 1247 | ext_line_rasterization = true; | 1277 | ext_line_rasterization = true; |
| @@ -1253,7 +1283,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1253 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR; | 1283 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR; |
| 1254 | layout.pNext = nullptr; | 1284 | layout.pNext = nullptr; |
| 1255 | features.pNext = &layout; | 1285 | features.pNext = &layout; |
| 1256 | physical.GetFeatures2KHR(features); | 1286 | physical.GetFeatures2(features); |
| 1257 | 1287 | ||
| 1258 | if (layout.workgroupMemoryExplicitLayout && | 1288 | if (layout.workgroupMemoryExplicitLayout && |
| 1259 | layout.workgroupMemoryExplicitLayout8BitAccess && | 1289 | layout.workgroupMemoryExplicitLayout8BitAccess && |
| @@ -1269,7 +1299,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1269 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR; | 1299 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR; |
| 1270 | executable_properties.pNext = nullptr; | 1300 | executable_properties.pNext = nullptr; |
| 1271 | features.pNext = &executable_properties; | 1301 | features.pNext = &executable_properties; |
| 1272 | physical.GetFeatures2KHR(features); | 1302 | physical.GetFeatures2(features); |
| 1273 | 1303 | ||
| 1274 | if (executable_properties.pipelineExecutableInfo) { | 1304 | if (executable_properties.pipelineExecutableInfo) { |
| 1275 | extensions.push_back(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); | 1305 | extensions.push_back(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); |
| @@ -1282,7 +1312,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1282 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; | 1312 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; |
| 1283 | primitive_topology_list_restart.pNext = nullptr; | 1313 | primitive_topology_list_restart.pNext = nullptr; |
| 1284 | features.pNext = &primitive_topology_list_restart; | 1314 | features.pNext = &primitive_topology_list_restart; |
| 1285 | physical.GetFeatures2KHR(features); | 1315 | physical.GetFeatures2(features); |
| 1286 | 1316 | ||
| 1287 | is_topology_list_restart_supported = | 1317 | is_topology_list_restart_supported = |
| 1288 | primitive_topology_list_restart.primitiveTopologyListRestart; | 1318 | primitive_topology_list_restart.primitiveTopologyListRestart; |
| @@ -1300,7 +1330,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1300 | push_descriptor.pNext = nullptr; | 1330 | push_descriptor.pNext = nullptr; |
| 1301 | 1331 | ||
| 1302 | physical_properties.pNext = &push_descriptor; | 1332 | physical_properties.pNext = &push_descriptor; |
| 1303 | physical.GetProperties2KHR(physical_properties); | 1333 | physical.GetProperties2(physical_properties); |
| 1304 | 1334 | ||
| 1305 | max_push_descriptors = push_descriptor.maxPushDescriptors; | 1335 | max_push_descriptors = push_descriptor.maxPushDescriptors; |
| 1306 | } | 1336 | } |
| @@ -1351,18 +1381,18 @@ void Device::SetupFeatures() { | |||
| 1351 | } | 1381 | } |
| 1352 | 1382 | ||
| 1353 | void Device::SetupProperties() { | 1383 | void Device::SetupProperties() { |
| 1354 | float_controls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR; | 1384 | float_controls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES; |
| 1355 | 1385 | ||
| 1356 | VkPhysicalDeviceProperties2KHR properties2{}; | 1386 | VkPhysicalDeviceProperties2KHR properties2{}; |
| 1357 | properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; | 1387 | properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; |
| 1358 | properties2.pNext = &float_controls; | 1388 | properties2.pNext = &float_controls; |
| 1359 | 1389 | ||
| 1360 | physical.GetProperties2KHR(properties2); | 1390 | physical.GetProperties2(properties2); |
| 1361 | } | 1391 | } |
| 1362 | 1392 | ||
| 1363 | void Device::CollectTelemetryParameters() { | 1393 | void Device::CollectTelemetryParameters() { |
| 1364 | VkPhysicalDeviceDriverPropertiesKHR driver{ | 1394 | VkPhysicalDeviceDriverProperties driver{ |
| 1365 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR, | 1395 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, |
| 1366 | .pNext = nullptr, | 1396 | .pNext = nullptr, |
| 1367 | .driverID = {}, | 1397 | .driverID = {}, |
| 1368 | .driverName = {}, | 1398 | .driverName = {}, |
| @@ -1370,12 +1400,12 @@ void Device::CollectTelemetryParameters() { | |||
| 1370 | .conformanceVersion = {}, | 1400 | .conformanceVersion = {}, |
| 1371 | }; | 1401 | }; |
| 1372 | 1402 | ||
| 1373 | VkPhysicalDeviceProperties2KHR device_properties{ | 1403 | VkPhysicalDeviceProperties2 device_properties{ |
| 1374 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR, | 1404 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, |
| 1375 | .pNext = &driver, | 1405 | .pNext = &driver, |
| 1376 | .properties = {}, | 1406 | .properties = {}, |
| 1377 | }; | 1407 | }; |
| 1378 | physical.GetProperties2KHR(device_properties); | 1408 | physical.GetProperties2(device_properties); |
| 1379 | 1409 | ||
| 1380 | driver_id = driver.driverID; | 1410 | driver_id = driver.driverID; |
| 1381 | vendor_name = driver.driverName; | 1411 | vendor_name = driver.driverName; |
| @@ -1431,23 +1461,10 @@ void Device::CollectToolingInfo() { | |||
| 1431 | if (!ext_tooling_info) { | 1461 | if (!ext_tooling_info) { |
| 1432 | return; | 1462 | return; |
| 1433 | } | 1463 | } |
| 1434 | const auto vkGetPhysicalDeviceToolPropertiesEXT = | 1464 | auto tools{physical.GetPhysicalDeviceToolProperties()}; |
| 1435 | reinterpret_cast<PFN_vkGetPhysicalDeviceToolPropertiesEXT>( | 1465 | for (const VkPhysicalDeviceToolProperties& tool : tools) { |
| 1436 | dld.vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceToolPropertiesEXT")); | ||
| 1437 | if (!vkGetPhysicalDeviceToolPropertiesEXT) { | ||
| 1438 | return; | ||
| 1439 | } | ||
| 1440 | u32 tool_count = 0; | ||
| 1441 | if (vkGetPhysicalDeviceToolPropertiesEXT(physical, &tool_count, nullptr) != VK_SUCCESS) { | ||
| 1442 | return; | ||
| 1443 | } | ||
| 1444 | std::vector<VkPhysicalDeviceToolPropertiesEXT> tools(tool_count); | ||
| 1445 | if (vkGetPhysicalDeviceToolPropertiesEXT(physical, &tool_count, tools.data()) != VK_SUCCESS) { | ||
| 1446 | return; | ||
| 1447 | } | ||
| 1448 | for (const VkPhysicalDeviceToolPropertiesEXT& tool : tools) { | ||
| 1449 | const std::string_view name = tool.name; | 1466 | const std::string_view name = tool.name; |
| 1450 | LOG_INFO(Render_Vulkan, "{}", name); | 1467 | LOG_INFO(Render_Vulkan, "Attached debugging tool: {}", name); |
| 1451 | has_renderdoc = has_renderdoc || name == "RenderDoc"; | 1468 | has_renderdoc = has_renderdoc || name == "RenderDoc"; |
| 1452 | has_nsight_graphics = has_nsight_graphics || name == "NVIDIA Nsight Graphics"; | 1469 | has_nsight_graphics = has_nsight_graphics || name == "NVIDIA Nsight Graphics"; |
| 1453 | } | 1470 | } |
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: | |||
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | /// Returns true if VK_KHR_pipeline_executable_properties is enabled. | 219 | /// Returns true if VK_KHR_pipeline_executable_properties is enabled. |
| 220 | bool IsKhrPipelineEexecutablePropertiesEnabled() const { | 220 | bool IsKhrPipelineExecutablePropertiesEnabled() const { |
| 221 | return khr_pipeline_executable_properties; | 221 | return khr_pipeline_executable_properties; |
| 222 | } | 222 | } |
| 223 | 223 | ||
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 { | |||
| 130 | X(vkCreateComputePipelines); | 130 | X(vkCreateComputePipelines); |
| 131 | X(vkCreateDescriptorPool); | 131 | X(vkCreateDescriptorPool); |
| 132 | X(vkCreateDescriptorSetLayout); | 132 | X(vkCreateDescriptorSetLayout); |
| 133 | X(vkCreateDescriptorUpdateTemplateKHR); | 133 | X(vkCreateDescriptorUpdateTemplate); |
| 134 | X(vkCreateEvent); | 134 | X(vkCreateEvent); |
| 135 | X(vkCreateFence); | 135 | X(vkCreateFence); |
| 136 | X(vkCreateFramebuffer); | 136 | X(vkCreateFramebuffer); |
| @@ -149,7 +149,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 149 | X(vkDestroyCommandPool); | 149 | X(vkDestroyCommandPool); |
| 150 | X(vkDestroyDescriptorPool); | 150 | X(vkDestroyDescriptorPool); |
| 151 | X(vkDestroyDescriptorSetLayout); | 151 | X(vkDestroyDescriptorSetLayout); |
| 152 | X(vkDestroyDescriptorUpdateTemplateKHR); | 152 | X(vkDestroyDescriptorUpdateTemplate); |
| 153 | X(vkDestroyEvent); | 153 | X(vkDestroyEvent); |
| 154 | X(vkDestroyFence); | 154 | X(vkDestroyFence); |
| 155 | X(vkDestroyFramebuffer); | 155 | X(vkDestroyFramebuffer); |
| @@ -180,18 +180,29 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 180 | X(vkGetQueryPoolResults); | 180 | X(vkGetQueryPoolResults); |
| 181 | X(vkGetPipelineExecutablePropertiesKHR); | 181 | X(vkGetPipelineExecutablePropertiesKHR); |
| 182 | X(vkGetPipelineExecutableStatisticsKHR); | 182 | X(vkGetPipelineExecutableStatisticsKHR); |
| 183 | X(vkGetSemaphoreCounterValueKHR); | 183 | X(vkGetSemaphoreCounterValue); |
| 184 | X(vkMapMemory); | 184 | X(vkMapMemory); |
| 185 | X(vkQueueSubmit); | 185 | X(vkQueueSubmit); |
| 186 | X(vkResetFences); | 186 | X(vkResetFences); |
| 187 | X(vkResetQueryPoolEXT); | 187 | X(vkResetQueryPool); |
| 188 | X(vkSetDebugUtilsObjectNameEXT); | 188 | X(vkSetDebugUtilsObjectNameEXT); |
| 189 | X(vkSetDebugUtilsObjectTagEXT); | 189 | X(vkSetDebugUtilsObjectTagEXT); |
| 190 | X(vkUnmapMemory); | 190 | X(vkUnmapMemory); |
| 191 | X(vkUpdateDescriptorSetWithTemplateKHR); | 191 | X(vkUpdateDescriptorSetWithTemplate); |
| 192 | X(vkUpdateDescriptorSets); | 192 | X(vkUpdateDescriptorSets); |
| 193 | X(vkWaitForFences); | 193 | X(vkWaitForFences); |
| 194 | X(vkWaitSemaphoresKHR); | 194 | X(vkWaitSemaphores); |
| 195 | |||
| 196 | // Support for timeline semaphores is mandatory in Vulkan 1.2 | ||
| 197 | if (!dld.vkGetSemaphoreCounterValue) { | ||
| 198 | Proc(dld.vkGetSemaphoreCounterValue, dld, "vkGetSemaphoreCounterValueKHR", device); | ||
| 199 | Proc(dld.vkWaitSemaphores, dld, "vkWaitSemaphoresKHR", device); | ||
| 200 | } | ||
| 201 | |||
| 202 | // Support for host query reset is mandatory in Vulkan 1.2 | ||
| 203 | if (!dld.vkResetQueryPool) { | ||
| 204 | Proc(dld.vkResetQueryPool, dld, "vkResetQueryPoolEXT", device); | ||
| 205 | } | ||
| 195 | #undef X | 206 | #undef X |
| 196 | } | 207 | } |
| 197 | 208 | ||
| @@ -224,12 +235,13 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept { | |||
| 224 | X(vkCreateDebugUtilsMessengerEXT); | 235 | X(vkCreateDebugUtilsMessengerEXT); |
| 225 | X(vkDestroyDebugUtilsMessengerEXT); | 236 | X(vkDestroyDebugUtilsMessengerEXT); |
| 226 | X(vkDestroySurfaceKHR); | 237 | X(vkDestroySurfaceKHR); |
| 227 | X(vkGetPhysicalDeviceFeatures2KHR); | 238 | X(vkGetPhysicalDeviceFeatures2); |
| 228 | X(vkGetPhysicalDeviceProperties2KHR); | 239 | X(vkGetPhysicalDeviceProperties2); |
| 229 | X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); | 240 | X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); |
| 230 | X(vkGetPhysicalDeviceSurfaceFormatsKHR); | 241 | X(vkGetPhysicalDeviceSurfaceFormatsKHR); |
| 231 | X(vkGetPhysicalDeviceSurfacePresentModesKHR); | 242 | X(vkGetPhysicalDeviceSurfacePresentModesKHR); |
| 232 | X(vkGetPhysicalDeviceSurfaceSupportKHR); | 243 | X(vkGetPhysicalDeviceSurfaceSupportKHR); |
| 244 | X(vkGetPhysicalDeviceToolProperties); | ||
| 233 | X(vkGetSwapchainImagesKHR); | 245 | X(vkGetSwapchainImagesKHR); |
| 234 | X(vkQueuePresentKHR); | 246 | X(vkQueuePresentKHR); |
| 235 | 247 | ||
| @@ -359,9 +371,9 @@ void Destroy(VkDevice device, VkDescriptorSetLayout handle, const DeviceDispatch | |||
| 359 | dld.vkDestroyDescriptorSetLayout(device, handle, nullptr); | 371 | dld.vkDestroyDescriptorSetLayout(device, handle, nullptr); |
| 360 | } | 372 | } |
| 361 | 373 | ||
| 362 | void Destroy(VkDevice device, VkDescriptorUpdateTemplateKHR handle, | 374 | void Destroy(VkDevice device, VkDescriptorUpdateTemplate handle, |
| 363 | const DeviceDispatch& dld) noexcept { | 375 | const DeviceDispatch& dld) noexcept { |
| 364 | dld.vkDestroyDescriptorUpdateTemplateKHR(device, handle, nullptr); | 376 | dld.vkDestroyDescriptorUpdateTemplate(device, handle, nullptr); |
| 365 | } | 377 | } |
| 366 | 378 | ||
| 367 | void Destroy(VkDevice device, VkDeviceMemory handle, const DeviceDispatch& dld) noexcept { | 379 | void Destroy(VkDevice device, VkDeviceMemory handle, const DeviceDispatch& dld) noexcept { |
| @@ -737,11 +749,11 @@ CommandPool Device::CreateCommandPool(const VkCommandPoolCreateInfo& ci) const { | |||
| 737 | return CommandPool(object, handle, *dld); | 749 | return CommandPool(object, handle, *dld); |
| 738 | } | 750 | } |
| 739 | 751 | ||
| 740 | DescriptorUpdateTemplateKHR Device::CreateDescriptorUpdateTemplateKHR( | 752 | DescriptorUpdateTemplate Device::CreateDescriptorUpdateTemplate( |
| 741 | const VkDescriptorUpdateTemplateCreateInfoKHR& ci) const { | 753 | const VkDescriptorUpdateTemplateCreateInfo& ci) const { |
| 742 | VkDescriptorUpdateTemplateKHR object; | 754 | VkDescriptorUpdateTemplate object; |
| 743 | Check(dld->vkCreateDescriptorUpdateTemplateKHR(handle, &ci, nullptr, &object)); | 755 | Check(dld->vkCreateDescriptorUpdateTemplate(handle, &ci, nullptr, &object)); |
| 744 | return DescriptorUpdateTemplateKHR(object, handle, *dld); | 756 | return DescriptorUpdateTemplate(object, handle, *dld); |
| 745 | } | 757 | } |
| 746 | 758 | ||
| 747 | QueryPool Device::CreateQueryPool(const VkQueryPoolCreateInfo& ci) const { | 759 | QueryPool Device::CreateQueryPool(const VkQueryPoolCreateInfo& ci) const { |
| @@ -857,20 +869,20 @@ VkPhysicalDeviceProperties PhysicalDevice::GetProperties() const noexcept { | |||
| 857 | return properties; | 869 | return properties; |
| 858 | } | 870 | } |
| 859 | 871 | ||
| 860 | void PhysicalDevice::GetProperties2KHR(VkPhysicalDeviceProperties2KHR& properties) const noexcept { | 872 | void PhysicalDevice::GetProperties2(VkPhysicalDeviceProperties2& properties) const noexcept { |
| 861 | dld->vkGetPhysicalDeviceProperties2KHR(physical_device, &properties); | 873 | dld->vkGetPhysicalDeviceProperties2(physical_device, &properties); |
| 862 | } | 874 | } |
| 863 | 875 | ||
| 864 | VkPhysicalDeviceFeatures PhysicalDevice::GetFeatures() const noexcept { | 876 | VkPhysicalDeviceFeatures PhysicalDevice::GetFeatures() const noexcept { |
| 865 | VkPhysicalDeviceFeatures2KHR features2; | 877 | VkPhysicalDeviceFeatures2 features2; |
| 866 | features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; | 878 | features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; |
| 867 | features2.pNext = nullptr; | 879 | features2.pNext = nullptr; |
| 868 | dld->vkGetPhysicalDeviceFeatures2KHR(physical_device, &features2); | 880 | dld->vkGetPhysicalDeviceFeatures2(physical_device, &features2); |
| 869 | return features2.features; | 881 | return features2.features; |
| 870 | } | 882 | } |
| 871 | 883 | ||
| 872 | void PhysicalDevice::GetFeatures2KHR(VkPhysicalDeviceFeatures2KHR& features) const noexcept { | 884 | void PhysicalDevice::GetFeatures2(VkPhysicalDeviceFeatures2& features) const noexcept { |
| 873 | dld->vkGetPhysicalDeviceFeatures2KHR(physical_device, &features); | 885 | dld->vkGetPhysicalDeviceFeatures2(physical_device, &features); |
| 874 | } | 886 | } |
| 875 | 887 | ||
| 876 | VkFormatProperties PhysicalDevice::GetFormatProperties(VkFormat format) const noexcept { | 888 | VkFormatProperties PhysicalDevice::GetFormatProperties(VkFormat format) const noexcept { |
| @@ -895,6 +907,18 @@ std::vector<VkQueueFamilyProperties> PhysicalDevice::GetQueueFamilyProperties() | |||
| 895 | return properties; | 907 | return properties; |
| 896 | } | 908 | } |
| 897 | 909 | ||
| 910 | std::vector<VkPhysicalDeviceToolProperties> PhysicalDevice::GetPhysicalDeviceToolProperties() | ||
| 911 | const { | ||
| 912 | u32 num = 0; | ||
| 913 | if (!dld->vkGetPhysicalDeviceToolProperties) { | ||
| 914 | return {}; | ||
| 915 | } | ||
| 916 | dld->vkGetPhysicalDeviceToolProperties(physical_device, &num, nullptr); | ||
| 917 | std::vector<VkPhysicalDeviceToolProperties> properties(num); | ||
| 918 | dld->vkGetPhysicalDeviceToolProperties(physical_device, &num, properties.data()); | ||
| 919 | return properties; | ||
| 920 | } | ||
| 921 | |||
| 898 | bool PhysicalDevice::GetSurfaceSupportKHR(u32 queue_family_index, VkSurfaceKHR surface) const { | 922 | bool PhysicalDevice::GetSurfaceSupportKHR(u32 queue_family_index, VkSurfaceKHR surface) const { |
| 899 | VkBool32 supported; | 923 | VkBool32 supported; |
| 900 | Check(dld->vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_index, surface, | 924 | 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 { | |||
| 168 | PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties{}; | 168 | PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties{}; |
| 169 | PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices{}; | 169 | PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices{}; |
| 170 | PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr{}; | 170 | PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr{}; |
| 171 | PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR{}; | 171 | PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2{}; |
| 172 | PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties{}; | 172 | PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties{}; |
| 173 | PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties{}; | 173 | PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties{}; |
| 174 | PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2{}; | 174 | PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2{}; |
| 175 | PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties{}; | 175 | PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties{}; |
| 176 | PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR{}; | 176 | PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2{}; |
| 177 | PFN_vkGetPhysicalDeviceToolProperties vkGetPhysicalDeviceToolProperties{}; | ||
| 177 | PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties{}; | 178 | PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties{}; |
| 178 | PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR{}; | 179 | PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR{}; |
| 179 | PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR{}; | 180 | PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR{}; |
| @@ -247,7 +248,7 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 247 | PFN_vkCreateComputePipelines vkCreateComputePipelines{}; | 248 | PFN_vkCreateComputePipelines vkCreateComputePipelines{}; |
| 248 | PFN_vkCreateDescriptorPool vkCreateDescriptorPool{}; | 249 | PFN_vkCreateDescriptorPool vkCreateDescriptorPool{}; |
| 249 | PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout{}; | 250 | PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout{}; |
| 250 | PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR{}; | 251 | PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate{}; |
| 251 | PFN_vkCreateEvent vkCreateEvent{}; | 252 | PFN_vkCreateEvent vkCreateEvent{}; |
| 252 | PFN_vkCreateFence vkCreateFence{}; | 253 | PFN_vkCreateFence vkCreateFence{}; |
| 253 | PFN_vkCreateFramebuffer vkCreateFramebuffer{}; | 254 | PFN_vkCreateFramebuffer vkCreateFramebuffer{}; |
| @@ -266,7 +267,7 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 266 | PFN_vkDestroyCommandPool vkDestroyCommandPool{}; | 267 | PFN_vkDestroyCommandPool vkDestroyCommandPool{}; |
| 267 | PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool{}; | 268 | PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool{}; |
| 268 | PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout{}; | 269 | PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout{}; |
| 269 | PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR{}; | 270 | PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate{}; |
| 270 | PFN_vkDestroyEvent vkDestroyEvent{}; | 271 | PFN_vkDestroyEvent vkDestroyEvent{}; |
| 271 | PFN_vkDestroyFence vkDestroyFence{}; | 272 | PFN_vkDestroyFence vkDestroyFence{}; |
| 272 | PFN_vkDestroyFramebuffer vkDestroyFramebuffer{}; | 273 | PFN_vkDestroyFramebuffer vkDestroyFramebuffer{}; |
| @@ -297,18 +298,18 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 297 | PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR{}; | 298 | PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR{}; |
| 298 | PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR{}; | 299 | PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR{}; |
| 299 | PFN_vkGetQueryPoolResults vkGetQueryPoolResults{}; | 300 | PFN_vkGetQueryPoolResults vkGetQueryPoolResults{}; |
| 300 | PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR{}; | 301 | PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue{}; |
| 301 | PFN_vkMapMemory vkMapMemory{}; | 302 | PFN_vkMapMemory vkMapMemory{}; |
| 302 | PFN_vkQueueSubmit vkQueueSubmit{}; | 303 | PFN_vkQueueSubmit vkQueueSubmit{}; |
| 303 | PFN_vkResetFences vkResetFences{}; | 304 | PFN_vkResetFences vkResetFences{}; |
| 304 | PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT{}; | 305 | PFN_vkResetQueryPool vkResetQueryPool{}; |
| 305 | PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{}; | 306 | PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{}; |
| 306 | PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT{}; | 307 | PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT{}; |
| 307 | PFN_vkUnmapMemory vkUnmapMemory{}; | 308 | PFN_vkUnmapMemory vkUnmapMemory{}; |
| 308 | PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR{}; | 309 | PFN_vkUpdateDescriptorSetWithTemplate vkUpdateDescriptorSetWithTemplate{}; |
| 309 | PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets{}; | 310 | PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets{}; |
| 310 | PFN_vkWaitForFences vkWaitForFences{}; | 311 | PFN_vkWaitForFences vkWaitForFences{}; |
| 311 | PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR{}; | 312 | PFN_vkWaitSemaphores vkWaitSemaphores{}; |
| 312 | }; | 313 | }; |
| 313 | 314 | ||
| 314 | /// Loads instance agnostic function pointers. | 315 | /// Loads instance agnostic function pointers. |
| @@ -327,7 +328,7 @@ void Destroy(VkDevice, VkBufferView, const DeviceDispatch&) noexcept; | |||
| 327 | void Destroy(VkDevice, VkCommandPool, const DeviceDispatch&) noexcept; | 328 | void Destroy(VkDevice, VkCommandPool, const DeviceDispatch&) noexcept; |
| 328 | void Destroy(VkDevice, VkDescriptorPool, const DeviceDispatch&) noexcept; | 329 | void Destroy(VkDevice, VkDescriptorPool, const DeviceDispatch&) noexcept; |
| 329 | void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept; | 330 | void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept; |
| 330 | void Destroy(VkDevice, VkDescriptorUpdateTemplateKHR, const DeviceDispatch&) noexcept; | 331 | void Destroy(VkDevice, VkDescriptorUpdateTemplate, const DeviceDispatch&) noexcept; |
| 331 | void Destroy(VkDevice, VkDeviceMemory, const DeviceDispatch&) noexcept; | 332 | void Destroy(VkDevice, VkDeviceMemory, const DeviceDispatch&) noexcept; |
| 332 | void Destroy(VkDevice, VkEvent, const DeviceDispatch&) noexcept; | 333 | void Destroy(VkDevice, VkEvent, const DeviceDispatch&) noexcept; |
| 333 | void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept; | 334 | void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept; |
| @@ -559,7 +560,7 @@ private: | |||
| 559 | 560 | ||
| 560 | using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>; | 561 | using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>; |
| 561 | using DescriptorSetLayout = Handle<VkDescriptorSetLayout, VkDevice, DeviceDispatch>; | 562 | using DescriptorSetLayout = Handle<VkDescriptorSetLayout, VkDevice, DeviceDispatch>; |
| 562 | using DescriptorUpdateTemplateKHR = Handle<VkDescriptorUpdateTemplateKHR, VkDevice, DeviceDispatch>; | 563 | using DescriptorUpdateTemplate = Handle<VkDescriptorUpdateTemplate, VkDevice, DeviceDispatch>; |
| 563 | using Pipeline = Handle<VkPipeline, VkDevice, DeviceDispatch>; | 564 | using Pipeline = Handle<VkPipeline, VkDevice, DeviceDispatch>; |
| 564 | using PipelineLayout = Handle<VkPipelineLayout, VkDevice, DeviceDispatch>; | 565 | using PipelineLayout = Handle<VkPipelineLayout, VkDevice, DeviceDispatch>; |
| 565 | using QueryPool = Handle<VkQueryPool, VkDevice, DeviceDispatch>; | 566 | using QueryPool = Handle<VkQueryPool, VkDevice, DeviceDispatch>; |
| @@ -766,7 +767,7 @@ public: | |||
| 766 | 767 | ||
| 767 | [[nodiscard]] u64 GetCounter() const { | 768 | [[nodiscard]] u64 GetCounter() const { |
| 768 | u64 value; | 769 | u64 value; |
| 769 | Check(dld->vkGetSemaphoreCounterValueKHR(owner, handle, &value)); | 770 | Check(dld->vkGetSemaphoreCounterValue(owner, handle, &value)); |
| 770 | return value; | 771 | return value; |
| 771 | } | 772 | } |
| 772 | 773 | ||
| @@ -778,15 +779,15 @@ public: | |||
| 778 | * @return True on successful wait, false on timeout | 779 | * @return True on successful wait, false on timeout |
| 779 | */ | 780 | */ |
| 780 | bool Wait(u64 value, u64 timeout = std::numeric_limits<u64>::max()) const { | 781 | bool Wait(u64 value, u64 timeout = std::numeric_limits<u64>::max()) const { |
| 781 | const VkSemaphoreWaitInfoKHR wait_info{ | 782 | const VkSemaphoreWaitInfo wait_info{ |
| 782 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR, | 783 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, |
| 783 | .pNext = nullptr, | 784 | .pNext = nullptr, |
| 784 | .flags = 0, | 785 | .flags = 0, |
| 785 | .semaphoreCount = 1, | 786 | .semaphoreCount = 1, |
| 786 | .pSemaphores = &handle, | 787 | .pSemaphores = &handle, |
| 787 | .pValues = &value, | 788 | .pValues = &value, |
| 788 | }; | 789 | }; |
| 789 | const VkResult result = dld->vkWaitSemaphoresKHR(owner, &wait_info, timeout); | 790 | const VkResult result = dld->vkWaitSemaphores(owner, &wait_info, timeout); |
| 790 | switch (result) { | 791 | switch (result) { |
| 791 | case VK_SUCCESS: | 792 | case VK_SUCCESS: |
| 792 | return true; | 793 | return true; |
| @@ -840,8 +841,8 @@ public: | |||
| 840 | 841 | ||
| 841 | CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const; | 842 | CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const; |
| 842 | 843 | ||
| 843 | DescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplateKHR( | 844 | DescriptorUpdateTemplate CreateDescriptorUpdateTemplate( |
| 844 | const VkDescriptorUpdateTemplateCreateInfoKHR& ci) const; | 845 | const VkDescriptorUpdateTemplateCreateInfo& ci) const; |
| 845 | 846 | ||
| 846 | QueryPool CreateQueryPool(const VkQueryPoolCreateInfo& ci) const; | 847 | QueryPool CreateQueryPool(const VkQueryPoolCreateInfo& ci) const; |
| 847 | 848 | ||
| @@ -869,9 +870,9 @@ public: | |||
| 869 | void UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes, | 870 | void UpdateDescriptorSets(Span<VkWriteDescriptorSet> writes, |
| 870 | Span<VkCopyDescriptorSet> copies) const noexcept; | 871 | Span<VkCopyDescriptorSet> copies) const noexcept; |
| 871 | 872 | ||
| 872 | void UpdateDescriptorSet(VkDescriptorSet set, VkDescriptorUpdateTemplateKHR update_template, | 873 | void UpdateDescriptorSet(VkDescriptorSet set, VkDescriptorUpdateTemplate update_template, |
| 873 | const void* data) const noexcept { | 874 | const void* data) const noexcept { |
| 874 | dld->vkUpdateDescriptorSetWithTemplateKHR(handle, set, update_template, data); | 875 | dld->vkUpdateDescriptorSetWithTemplate(handle, set, update_template, data); |
| 875 | } | 876 | } |
| 876 | 877 | ||
| 877 | VkResult AcquireNextImageKHR(VkSwapchainKHR swapchain, u64 timeout, VkSemaphore semaphore, | 878 | VkResult AcquireNextImageKHR(VkSwapchainKHR swapchain, u64 timeout, VkSemaphore semaphore, |
| @@ -884,8 +885,8 @@ public: | |||
| 884 | return dld->vkDeviceWaitIdle(handle); | 885 | return dld->vkDeviceWaitIdle(handle); |
| 885 | } | 886 | } |
| 886 | 887 | ||
| 887 | void ResetQueryPoolEXT(VkQueryPool query_pool, u32 first, u32 count) const noexcept { | 888 | void ResetQueryPool(VkQueryPool query_pool, u32 first, u32 count) const noexcept { |
| 888 | dld->vkResetQueryPoolEXT(handle, query_pool, first, count); | 889 | dld->vkResetQueryPool(handle, query_pool, first, count); |
| 889 | } | 890 | } |
| 890 | 891 | ||
| 891 | VkResult GetQueryResults(VkQueryPool query_pool, u32 first, u32 count, std::size_t data_size, | 892 | VkResult GetQueryResults(VkQueryPool query_pool, u32 first, u32 count, std::size_t data_size, |
| @@ -910,11 +911,11 @@ public: | |||
| 910 | 911 | ||
| 911 | VkPhysicalDeviceProperties GetProperties() const noexcept; | 912 | VkPhysicalDeviceProperties GetProperties() const noexcept; |
| 912 | 913 | ||
| 913 | void GetProperties2KHR(VkPhysicalDeviceProperties2KHR&) const noexcept; | 914 | void GetProperties2(VkPhysicalDeviceProperties2&) const noexcept; |
| 914 | 915 | ||
| 915 | VkPhysicalDeviceFeatures GetFeatures() const noexcept; | 916 | VkPhysicalDeviceFeatures GetFeatures() const noexcept; |
| 916 | 917 | ||
| 917 | void GetFeatures2KHR(VkPhysicalDeviceFeatures2KHR&) const noexcept; | 918 | void GetFeatures2(VkPhysicalDeviceFeatures2&) const noexcept; |
| 918 | 919 | ||
| 919 | VkFormatProperties GetFormatProperties(VkFormat) const noexcept; | 920 | VkFormatProperties GetFormatProperties(VkFormat) const noexcept; |
| 920 | 921 | ||
| @@ -922,6 +923,8 @@ public: | |||
| 922 | 923 | ||
| 923 | std::vector<VkQueueFamilyProperties> GetQueueFamilyProperties() const; | 924 | std::vector<VkQueueFamilyProperties> GetQueueFamilyProperties() const; |
| 924 | 925 | ||
| 926 | std::vector<VkPhysicalDeviceToolProperties> GetPhysicalDeviceToolProperties() const; | ||
| 927 | |||
| 925 | bool GetSurfaceSupportKHR(u32 queue_family_index, VkSurfaceKHR) const; | 928 | bool GetSurfaceSupportKHR(u32 queue_family_index, VkSurfaceKHR) const; |
| 926 | 929 | ||
| 927 | VkSurfaceCapabilitiesKHR GetSurfaceCapabilitiesKHR(VkSurfaceKHR) const; | 930 | VkSurfaceCapabilitiesKHR GetSurfaceCapabilitiesKHR(VkSurfaceKHR) const; |
| @@ -980,7 +983,7 @@ public: | |||
| 980 | dynamic_offsets.size(), dynamic_offsets.data()); | 983 | dynamic_offsets.size(), dynamic_offsets.data()); |
| 981 | } | 984 | } |
| 982 | 985 | ||
| 983 | void PushDescriptorSetWithTemplateKHR(VkDescriptorUpdateTemplateKHR update_template, | 986 | void PushDescriptorSetWithTemplateKHR(VkDescriptorUpdateTemplate update_template, |
| 984 | VkPipelineLayout layout, u32 set, | 987 | VkPipelineLayout layout, u32 set, |
| 985 | const void* data) const noexcept { | 988 | const void* data) const noexcept { |
| 986 | dld->vkCmdPushDescriptorSetWithTemplateKHR(handle, update_template, layout, set, data); | 989 | 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 | |||
| 88 | configuration/configure_input_advanced.cpp | 88 | configuration/configure_input_advanced.cpp |
| 89 | configuration/configure_input_advanced.h | 89 | configuration/configure_input_advanced.h |
| 90 | configuration/configure_input_advanced.ui | 90 | configuration/configure_input_advanced.ui |
| 91 | configuration/configure_input_per_game.cpp | ||
| 92 | configuration/configure_input_per_game.h | ||
| 93 | configuration/configure_input_per_game.ui | ||
| 91 | configuration/configure_input_player.cpp | 94 | configuration/configure_input_player.cpp |
| 92 | configuration/configure_input_player.h | 95 | configuration/configure_input_player.h |
| 93 | configuration/configure_input_player.ui | 96 | 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) { | |||
| 124 | } | 124 | } |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | bool Config::IsCustomConfig() { | ||
| 128 | return type == ConfigType::PerGameConfig; | ||
| 129 | } | ||
| 130 | |||
| 127 | /* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their | 131 | /* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their |
| 128 | * usages later in this file. This allows explicit definition of some types that don't work | 132 | * usages later in this file. This allows explicit definition of some types that don't work |
| 129 | * nicely with the general version. | 133 | * nicely with the general version. |
| @@ -194,8 +198,20 @@ void Config::ReadPlayerValue(std::size_t player_index) { | |||
| 194 | }(); | 198 | }(); |
| 195 | 199 | ||
| 196 | auto& player = Settings::values.players.GetValue()[player_index]; | 200 | auto& player = Settings::values.players.GetValue()[player_index]; |
| 201 | if (IsCustomConfig()) { | ||
| 202 | const auto profile_name = | ||
| 203 | qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{}) | ||
| 204 | .toString() | ||
| 205 | .toStdString(); | ||
| 206 | if (profile_name.empty()) { | ||
| 207 | // Use the global input config | ||
| 208 | player = Settings::values.players.GetValue(true)[player_index]; | ||
| 209 | return; | ||
| 210 | } | ||
| 211 | player.profile_name = profile_name; | ||
| 212 | } | ||
| 197 | 213 | ||
| 198 | if (player_prefix.isEmpty()) { | 214 | if (player_prefix.isEmpty() && Settings::IsConfiguringGlobal()) { |
| 199 | const auto controller = static_cast<Settings::ControllerType>( | 215 | const auto controller = static_cast<Settings::ControllerType>( |
| 200 | qt_config | 216 | qt_config |
| 201 | ->value(QStringLiteral("%1type").arg(player_prefix), | 217 | ->value(QStringLiteral("%1type").arg(player_prefix), |
| @@ -388,9 +404,26 @@ void Config::ReadAudioValues() { | |||
| 388 | void Config::ReadControlValues() { | 404 | void Config::ReadControlValues() { |
| 389 | qt_config->beginGroup(QStringLiteral("Controls")); | 405 | qt_config->beginGroup(QStringLiteral("Controls")); |
| 390 | 406 | ||
| 407 | Settings::values.players.SetGlobal(!IsCustomConfig()); | ||
| 391 | for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { | 408 | for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { |
| 392 | ReadPlayerValue(p); | 409 | ReadPlayerValue(p); |
| 393 | } | 410 | } |
| 411 | ReadGlobalSetting(Settings::values.use_docked_mode); | ||
| 412 | |||
| 413 | // Disable docked mode if handheld is selected | ||
| 414 | const auto controller_type = Settings::values.players.GetValue()[0].controller_type; | ||
| 415 | if (controller_type == Settings::ControllerType::Handheld) { | ||
| 416 | Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig()); | ||
| 417 | Settings::values.use_docked_mode.SetValue(false); | ||
| 418 | } | ||
| 419 | |||
| 420 | ReadGlobalSetting(Settings::values.vibration_enabled); | ||
| 421 | ReadGlobalSetting(Settings::values.enable_accurate_vibrations); | ||
| 422 | ReadGlobalSetting(Settings::values.motion_enabled); | ||
| 423 | if (IsCustomConfig()) { | ||
| 424 | qt_config->endGroup(); | ||
| 425 | return; | ||
| 426 | } | ||
| 394 | ReadDebugValues(); | 427 | ReadDebugValues(); |
| 395 | ReadKeyboardValues(); | 428 | ReadKeyboardValues(); |
| 396 | ReadMouseValues(); | 429 | ReadMouseValues(); |
| @@ -412,18 +445,6 @@ void Config::ReadControlValues() { | |||
| 412 | ReadBasicSetting(Settings::values.tas_loop); | 445 | ReadBasicSetting(Settings::values.tas_loop); |
| 413 | ReadBasicSetting(Settings::values.pause_tas_on_load); | 446 | ReadBasicSetting(Settings::values.pause_tas_on_load); |
| 414 | 447 | ||
| 415 | ReadGlobalSetting(Settings::values.use_docked_mode); | ||
| 416 | |||
| 417 | // Disable docked mode if handheld is selected | ||
| 418 | const auto controller_type = Settings::values.players.GetValue()[0].controller_type; | ||
| 419 | if (controller_type == Settings::ControllerType::Handheld) { | ||
| 420 | Settings::values.use_docked_mode.SetValue(false); | ||
| 421 | } | ||
| 422 | |||
| 423 | ReadGlobalSetting(Settings::values.vibration_enabled); | ||
| 424 | ReadGlobalSetting(Settings::values.enable_accurate_vibrations); | ||
| 425 | ReadGlobalSetting(Settings::values.motion_enabled); | ||
| 426 | |||
| 427 | ReadBasicSetting(Settings::values.controller_navigation); | 448 | ReadBasicSetting(Settings::values.controller_navigation); |
| 428 | 449 | ||
| 429 | qt_config->endGroup(); | 450 | qt_config->endGroup(); |
| @@ -905,7 +926,6 @@ void Config::ReadMultiplayerValues() { | |||
| 905 | 926 | ||
| 906 | void Config::ReadValues() { | 927 | void Config::ReadValues() { |
| 907 | if (global) { | 928 | if (global) { |
| 908 | ReadControlValues(); | ||
| 909 | ReadDataStorageValues(); | 929 | ReadDataStorageValues(); |
| 910 | ReadDebuggingValues(); | 930 | ReadDebuggingValues(); |
| 911 | ReadDisabledAddOnValues(); | 931 | ReadDisabledAddOnValues(); |
| @@ -914,6 +934,7 @@ void Config::ReadValues() { | |||
| 914 | ReadWebServiceValues(); | 934 | ReadWebServiceValues(); |
| 915 | ReadMiscellaneousValues(); | 935 | ReadMiscellaneousValues(); |
| 916 | } | 936 | } |
| 937 | ReadControlValues(); | ||
| 917 | ReadCoreValues(); | 938 | ReadCoreValues(); |
| 918 | ReadCpuValues(); | 939 | ReadCpuValues(); |
| 919 | ReadRendererValues(); | 940 | ReadRendererValues(); |
| @@ -932,12 +953,20 @@ void Config::SavePlayerValue(std::size_t player_index) { | |||
| 932 | }(); | 953 | }(); |
| 933 | 954 | ||
| 934 | const auto& player = Settings::values.players.GetValue()[player_index]; | 955 | const auto& player = Settings::values.players.GetValue()[player_index]; |
| 956 | if (IsCustomConfig()) { | ||
| 957 | if (player.profile_name.empty()) { | ||
| 958 | // No custom profile selected | ||
| 959 | return; | ||
| 960 | } | ||
| 961 | WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix), | ||
| 962 | QString::fromStdString(player.profile_name), QString{}); | ||
| 963 | } | ||
| 935 | 964 | ||
| 936 | WriteSetting(QStringLiteral("%1type").arg(player_prefix), | 965 | WriteSetting(QStringLiteral("%1type").arg(player_prefix), |
| 937 | static_cast<u8>(player.controller_type), | 966 | static_cast<u8>(player.controller_type), |
| 938 | static_cast<u8>(Settings::ControllerType::ProController)); | 967 | static_cast<u8>(Settings::ControllerType::ProController)); |
| 939 | 968 | ||
| 940 | if (!player_prefix.isEmpty()) { | 969 | if (!player_prefix.isEmpty() || !Settings::IsConfiguringGlobal()) { |
| 941 | WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, | 970 | WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, |
| 942 | player_index == 0); | 971 | player_index == 0); |
| 943 | WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix), | 972 | WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix), |
| @@ -1055,7 +1084,6 @@ void Config::SaveIrCameraValues() { | |||
| 1055 | 1084 | ||
| 1056 | void Config::SaveValues() { | 1085 | void Config::SaveValues() { |
| 1057 | if (global) { | 1086 | if (global) { |
| 1058 | SaveControlValues(); | ||
| 1059 | SaveDataStorageValues(); | 1087 | SaveDataStorageValues(); |
| 1060 | SaveDebuggingValues(); | 1088 | SaveDebuggingValues(); |
| 1061 | SaveDisabledAddOnValues(); | 1089 | SaveDisabledAddOnValues(); |
| @@ -1064,6 +1092,7 @@ void Config::SaveValues() { | |||
| 1064 | SaveWebServiceValues(); | 1092 | SaveWebServiceValues(); |
| 1065 | SaveMiscellaneousValues(); | 1093 | SaveMiscellaneousValues(); |
| 1066 | } | 1094 | } |
| 1095 | SaveControlValues(); | ||
| 1067 | SaveCoreValues(); | 1096 | SaveCoreValues(); |
| 1068 | SaveCpuValues(); | 1097 | SaveCpuValues(); |
| 1069 | SaveRendererValues(); | 1098 | SaveRendererValues(); |
| @@ -1088,9 +1117,14 @@ void Config::SaveAudioValues() { | |||
| 1088 | void Config::SaveControlValues() { | 1117 | void Config::SaveControlValues() { |
| 1089 | qt_config->beginGroup(QStringLiteral("Controls")); | 1118 | qt_config->beginGroup(QStringLiteral("Controls")); |
| 1090 | 1119 | ||
| 1120 | Settings::values.players.SetGlobal(!IsCustomConfig()); | ||
| 1091 | for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { | 1121 | for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { |
| 1092 | SavePlayerValue(p); | 1122 | SavePlayerValue(p); |
| 1093 | } | 1123 | } |
| 1124 | if (IsCustomConfig()) { | ||
| 1125 | qt_config->endGroup(); | ||
| 1126 | return; | ||
| 1127 | } | ||
| 1094 | SaveDebugValues(); | 1128 | SaveDebugValues(); |
| 1095 | SaveMouseValues(); | 1129 | SaveMouseValues(); |
| 1096 | SaveTouchscreenValues(); | 1130 | SaveTouchscreenValues(); |
| @@ -1579,6 +1613,13 @@ void Config::SaveControlPlayerValue(std::size_t player_index) { | |||
| 1579 | qt_config->endGroup(); | 1613 | qt_config->endGroup(); |
| 1580 | } | 1614 | } |
| 1581 | 1615 | ||
| 1616 | void Config::ClearControlPlayerValues() { | ||
| 1617 | qt_config->beginGroup(QStringLiteral("Controls")); | ||
| 1618 | // If key is an empty string, all keys in the current group() are removed. | ||
| 1619 | qt_config->remove(QString{}); | ||
| 1620 | qt_config->endGroup(); | ||
| 1621 | } | ||
| 1622 | |||
| 1582 | const std::string& Config::GetConfigFilePath() const { | 1623 | const std::string& Config::GetConfigFilePath() const { |
| 1583 | return qt_config_loc; | 1624 | return qt_config_loc; |
| 1584 | } | 1625 | } |
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: | |||
| 34 | 34 | ||
| 35 | void ReadControlPlayerValue(std::size_t player_index); | 35 | void ReadControlPlayerValue(std::size_t player_index); |
| 36 | void SaveControlPlayerValue(std::size_t player_index); | 36 | void SaveControlPlayerValue(std::size_t player_index); |
| 37 | void ClearControlPlayerValues(); | ||
| 37 | 38 | ||
| 38 | const std::string& GetConfigFilePath() const; | 39 | const std::string& GetConfigFilePath() const; |
| 39 | 40 | ||
| @@ -58,6 +59,7 @@ public: | |||
| 58 | 59 | ||
| 59 | private: | 60 | private: |
| 60 | void Initialize(const std::string& config_name); | 61 | void Initialize(const std::string& config_name); |
| 62 | bool IsCustomConfig(); | ||
| 61 | 63 | ||
| 62 | void ReadValues(); | 64 | void ReadValues(); |
| 63 | void ReadPlayerValue(std::size_t player_index); | 65 | 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 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/hid/emulated_controller.h" | ||
| 7 | #include "core/hid/hid_core.h" | ||
| 8 | #include "ui_configure_input_per_game.h" | ||
| 9 | #include "yuzu/configuration/config.h" | ||
| 10 | #include "yuzu/configuration/configure_input_per_game.h" | ||
| 11 | #include "yuzu/configuration/input_profiles.h" | ||
| 12 | |||
| 13 | ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, Config* config_, | ||
| 14 | QWidget* parent) | ||
| 15 | : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPerGame>()), | ||
| 16 | profiles(std::make_unique<InputProfiles>()), system{system_}, config{config_} { | ||
| 17 | ui->setupUi(this); | ||
| 18 | const std::array labels = { | ||
| 19 | ui->label_player_1, ui->label_player_2, ui->label_player_3, ui->label_player_4, | ||
| 20 | ui->label_player_5, ui->label_player_6, ui->label_player_7, ui->label_player_8, | ||
| 21 | }; | ||
| 22 | profile_comboboxes = { | ||
| 23 | ui->profile_player_1, ui->profile_player_2, ui->profile_player_3, ui->profile_player_4, | ||
| 24 | ui->profile_player_5, ui->profile_player_6, ui->profile_player_7, ui->profile_player_8, | ||
| 25 | }; | ||
| 26 | |||
| 27 | Settings::values.players.SetGlobal(false); | ||
| 28 | |||
| 29 | const auto& profile_names = profiles->GetInputProfileNames(); | ||
| 30 | const auto populate_profiles = [this, &profile_names](size_t player_index) { | ||
| 31 | const auto previous_profile = | ||
| 32 | Settings::values.players.GetValue()[player_index].profile_name; | ||
| 33 | |||
| 34 | auto* const player_combobox = profile_comboboxes[player_index]; | ||
| 35 | player_combobox->addItem(tr("Use global input configuration")); | ||
| 36 | |||
| 37 | for (size_t index = 0; index < profile_names.size(); ++index) { | ||
| 38 | const auto& profile_name = profile_names[index]; | ||
| 39 | player_combobox->addItem(QString::fromStdString(profile_name)); | ||
| 40 | if (profile_name == previous_profile) { | ||
| 41 | // offset by 1 since the first element is the global config | ||
| 42 | player_combobox->setCurrentIndex(static_cast<int>(index + 1)); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | }; | ||
| 46 | for (size_t index = 0; index < profile_comboboxes.size(); ++index) { | ||
| 47 | labels[index]->setText(tr("Player %1 profile").arg(index + 1)); | ||
| 48 | populate_profiles(index); | ||
| 49 | } | ||
| 50 | |||
| 51 | LoadConfiguration(); | ||
| 52 | } | ||
| 53 | |||
| 54 | void ConfigureInputPerGame::ApplyConfiguration() { | ||
| 55 | LoadConfiguration(); | ||
| 56 | SaveConfiguration(); | ||
| 57 | } | ||
| 58 | |||
| 59 | void ConfigureInputPerGame::LoadConfiguration() { | ||
| 60 | static constexpr size_t HANDHELD_INDEX = 8; | ||
| 61 | |||
| 62 | auto& hid_core = system.HIDCore(); | ||
| 63 | for (size_t player_index = 0; player_index < profile_comboboxes.size(); ++player_index) { | ||
| 64 | Settings::values.players.SetGlobal(false); | ||
| 65 | |||
| 66 | auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(player_index); | ||
| 67 | auto* const player_combobox = profile_comboboxes[player_index]; | ||
| 68 | |||
| 69 | const auto selection_index = player_combobox->currentIndex(); | ||
| 70 | if (selection_index == 0) { | ||
| 71 | Settings::values.players.GetValue()[player_index].profile_name = ""; | ||
| 72 | if (player_index == 0) { | ||
| 73 | Settings::values.players.GetValue()[HANDHELD_INDEX] = {}; | ||
| 74 | } | ||
| 75 | Settings::values.players.SetGlobal(true); | ||
| 76 | emulated_controller->ReloadFromSettings(); | ||
| 77 | continue; | ||
| 78 | } | ||
| 79 | const auto profile_name = player_combobox->itemText(selection_index).toStdString(); | ||
| 80 | if (profile_name.empty()) { | ||
| 81 | continue; | ||
| 82 | } | ||
| 83 | auto& player = Settings::values.players.GetValue()[player_index]; | ||
| 84 | player.profile_name = profile_name; | ||
| 85 | // Read from the profile into the custom player settings | ||
| 86 | profiles->LoadProfile(profile_name, player_index); | ||
| 87 | // Make sure the controller is connected | ||
| 88 | player.connected = true; | ||
| 89 | |||
| 90 | emulated_controller->ReloadFromSettings(); | ||
| 91 | |||
| 92 | if (player_index > 0) { | ||
| 93 | continue; | ||
| 94 | } | ||
| 95 | // Handle Handheld cases | ||
| 96 | auto& handheld_player = Settings::values.players.GetValue()[HANDHELD_INDEX]; | ||
| 97 | auto* handheld_controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||
| 98 | if (player.controller_type == Settings::ControllerType::Handheld) { | ||
| 99 | handheld_player = player; | ||
| 100 | } else { | ||
| 101 | handheld_player = {}; | ||
| 102 | } | ||
| 103 | handheld_controller->ReloadFromSettings(); | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | void ConfigureInputPerGame::SaveConfiguration() { | ||
| 108 | Settings::values.players.SetGlobal(false); | ||
| 109 | |||
| 110 | // Clear all controls from the config in case the user reverted back to globals | ||
| 111 | config->ClearControlPlayerValues(); | ||
| 112 | for (size_t index = 0; index < Settings::values.players.GetValue().size(); ++index) { | ||
| 113 | config->SaveControlPlayerValue(index); | ||
| 114 | } | ||
| 115 | } | ||
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 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | |||
| 8 | #include <QWidget> | ||
| 9 | |||
| 10 | #include "ui_configure_input_per_game.h" | ||
| 11 | #include "yuzu/configuration/input_profiles.h" | ||
| 12 | |||
| 13 | class QComboBox; | ||
| 14 | |||
| 15 | namespace Core { | ||
| 16 | class System; | ||
| 17 | } // namespace Core | ||
| 18 | |||
| 19 | class Config; | ||
| 20 | |||
| 21 | class ConfigureInputPerGame : public QWidget { | ||
| 22 | Q_OBJECT | ||
| 23 | |||
| 24 | public: | ||
| 25 | explicit ConfigureInputPerGame(Core::System& system_, Config* config_, | ||
| 26 | QWidget* parent = nullptr); | ||
| 27 | |||
| 28 | /// Load and Save configurations to settings file. | ||
| 29 | void ApplyConfiguration(); | ||
| 30 | |||
| 31 | private: | ||
| 32 | /// Load configuration from settings file. | ||
| 33 | void LoadConfiguration(); | ||
| 34 | |||
| 35 | /// Save configuration to settings file. | ||
| 36 | void SaveConfiguration(); | ||
| 37 | |||
| 38 | std::unique_ptr<Ui::ConfigureInputPerGame> ui; | ||
| 39 | std::unique_ptr<InputProfiles> profiles; | ||
| 40 | |||
| 41 | std::array<QComboBox*, 8> profile_comboboxes; | ||
| 42 | |||
| 43 | Core::System& system; | ||
| 44 | Config* config; | ||
| 45 | }; | ||
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 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigureInputPerGame</class> | ||
| 4 | <widget class="QWidget" name="PerGameInput"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>541</width> | ||
| 10 | <height>759</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <property name="windowTitle"> | ||
| 14 | <string>Form</string> | ||
| 15 | </property> | ||
| 16 | <property name="accessibleName"> | ||
| 17 | <string>Graphics</string> | ||
| 18 | </property> | ||
| 19 | <layout class="QVBoxLayout" name="verticalLayout_1"> | ||
| 20 | <item> | ||
| 21 | <layout class="QVBoxLayout" name="verticalLayout_2"> | ||
| 22 | <property name="spacing"> | ||
| 23 | <number>0</number> | ||
| 24 | </property> | ||
| 25 | <item> | ||
| 26 | <widget class="QGroupBox" name="groupBox"> | ||
| 27 | <property name="title"> | ||
| 28 | <string>Input Profiles</string> | ||
| 29 | </property> | ||
| 30 | <layout class="QVBoxLayout" name="verticalLayout_4"> | ||
| 31 | <item> | ||
| 32 | <widget class="QWidget" name="player_1" native="true"> | ||
| 33 | <layout class="QHBoxLayout" name="input_profile_layout_1"> | ||
| 34 | <property name="leftMargin"> | ||
| 35 | <number>0</number> | ||
| 36 | </property> | ||
| 37 | <property name="topMargin"> | ||
| 38 | <number>0</number> | ||
| 39 | </property> | ||
| 40 | <property name="rightMargin"> | ||
| 41 | <number>0</number> | ||
| 42 | </property> | ||
| 43 | <property name="bottomMargin"> | ||
| 44 | <number>0</number> | ||
| 45 | </property> | ||
| 46 | <item> | ||
| 47 | <widget class="QLabel" name="label_player_1"> | ||
| 48 | <property name="text"> | ||
| 49 | <string>Player 1 Profile</string> | ||
| 50 | </property> | ||
| 51 | </widget> | ||
| 52 | </item> | ||
| 53 | <item> | ||
| 54 | <widget class="QComboBox" name="profile_player_1"> | ||
| 55 | <property name="sizePolicy"> | ||
| 56 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 57 | <horstretch>0</horstretch> | ||
| 58 | <verstretch>0</verstretch> | ||
| 59 | </sizepolicy> | ||
| 60 | </property> | ||
| 61 | </widget> | ||
| 62 | </item> | ||
| 63 | </layout> | ||
| 64 | </widget> | ||
| 65 | </item> | ||
| 66 | <item> | ||
| 67 | <widget class="QWidget" name="player_2" native="true"> | ||
| 68 | <layout class="QHBoxLayout" name="input_profile_layout_2"> | ||
| 69 | <property name="leftMargin"> | ||
| 70 | <number>0</number> | ||
| 71 | </property> | ||
| 72 | <property name="topMargin"> | ||
| 73 | <number>0</number> | ||
| 74 | </property> | ||
| 75 | <property name="rightMargin"> | ||
| 76 | <number>0</number> | ||
| 77 | </property> | ||
| 78 | <property name="bottomMargin"> | ||
| 79 | <number>0</number> | ||
| 80 | </property> | ||
| 81 | <item> | ||
| 82 | <widget class="QLabel" name="label_player_2"> | ||
| 83 | <property name="text"> | ||
| 84 | <string>Player 2 Profile</string> | ||
| 85 | </property> | ||
| 86 | </widget> | ||
| 87 | </item> | ||
| 88 | <item> | ||
| 89 | <widget class="QComboBox" name="profile_player_2"> | ||
| 90 | <property name="sizePolicy"> | ||
| 91 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 92 | <horstretch>0</horstretch> | ||
| 93 | <verstretch>0</verstretch> | ||
| 94 | </sizepolicy> | ||
| 95 | </property> | ||
| 96 | </widget> | ||
| 97 | </item> | ||
| 98 | </layout> | ||
| 99 | </widget> | ||
| 100 | </item> | ||
| 101 | <item> | ||
| 102 | <widget class="QWidget" name="player_3" native="true"> | ||
| 103 | <layout class="QHBoxLayout" name="input_profile_layout_3"> | ||
| 104 | <property name="leftMargin"> | ||
| 105 | <number>0</number> | ||
| 106 | </property> | ||
| 107 | <property name="topMargin"> | ||
| 108 | <number>0</number> | ||
| 109 | </property> | ||
| 110 | <property name="rightMargin"> | ||
| 111 | <number>0</number> | ||
| 112 | </property> | ||
| 113 | <property name="bottomMargin"> | ||
| 114 | <number>0</number> | ||
| 115 | </property> | ||
| 116 | <item> | ||
| 117 | <widget class="QLabel" name="label_player_3"> | ||
| 118 | <property name="text"> | ||
| 119 | <string>Player 3 Profile</string> | ||
| 120 | </property> | ||
| 121 | </widget> | ||
| 122 | </item> | ||
| 123 | <item> | ||
| 124 | <widget class="QComboBox" name="profile_player_3"> | ||
| 125 | <property name="sizePolicy"> | ||
| 126 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 127 | <horstretch>0</horstretch> | ||
| 128 | <verstretch>0</verstretch> | ||
| 129 | </sizepolicy> | ||
| 130 | </property> | ||
| 131 | </widget> | ||
| 132 | </item> | ||
| 133 | </layout> | ||
| 134 | </widget> | ||
| 135 | </item> | ||
| 136 | <item> | ||
| 137 | <widget class="QWidget" name="player_4" native="true"> | ||
| 138 | <layout class="QHBoxLayout" name="input_profile_layout_4"> | ||
| 139 | <property name="leftMargin"> | ||
| 140 | <number>0</number> | ||
| 141 | </property> | ||
| 142 | <property name="topMargin"> | ||
| 143 | <number>0</number> | ||
| 144 | </property> | ||
| 145 | <property name="rightMargin"> | ||
| 146 | <number>0</number> | ||
| 147 | </property> | ||
| 148 | <property name="bottomMargin"> | ||
| 149 | <number>0</number> | ||
| 150 | </property> | ||
| 151 | <item> | ||
| 152 | <widget class="QLabel" name="label_player_4"> | ||
| 153 | <property name="text"> | ||
| 154 | <string>Player 4 Profile</string> | ||
| 155 | </property> | ||
| 156 | </widget> | ||
| 157 | </item> | ||
| 158 | <item> | ||
| 159 | <widget class="QComboBox" name="profile_player_4"> | ||
| 160 | <property name="sizePolicy"> | ||
| 161 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 162 | <horstretch>0</horstretch> | ||
| 163 | <verstretch>0</verstretch> | ||
| 164 | </sizepolicy> | ||
| 165 | </property> | ||
| 166 | </widget> | ||
| 167 | </item> | ||
| 168 | </layout> | ||
| 169 | </widget> | ||
| 170 | </item> | ||
| 171 | <item> | ||
| 172 | <widget class="QWidget" name="player_5" native="true"> | ||
| 173 | <layout class="QHBoxLayout" name="input_profile_layout_5"> | ||
| 174 | <property name="leftMargin"> | ||
| 175 | <number>0</number> | ||
| 176 | </property> | ||
| 177 | <property name="topMargin"> | ||
| 178 | <number>0</number> | ||
| 179 | </property> | ||
| 180 | <property name="rightMargin"> | ||
| 181 | <number>0</number> | ||
| 182 | </property> | ||
| 183 | <property name="bottomMargin"> | ||
| 184 | <number>0</number> | ||
| 185 | </property> | ||
| 186 | <item> | ||
| 187 | <widget class="QLabel" name="label_player_5"> | ||
| 188 | <property name="text"> | ||
| 189 | <string>Player 5 Profile</string> | ||
| 190 | </property> | ||
| 191 | </widget> | ||
| 192 | </item> | ||
| 193 | <item> | ||
| 194 | <widget class="QComboBox" name="profile_player_5"> | ||
| 195 | <property name="sizePolicy"> | ||
| 196 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 197 | <horstretch>0</horstretch> | ||
| 198 | <verstretch>0</verstretch> | ||
| 199 | </sizepolicy> | ||
| 200 | </property> | ||
| 201 | </widget> | ||
| 202 | </item> | ||
| 203 | </layout> | ||
| 204 | </widget> | ||
| 205 | </item> | ||
| 206 | <item> | ||
| 207 | <widget class="QWidget" name="player_6" native="true"> | ||
| 208 | <layout class="QHBoxLayout" name="input_profile_layout_6"> | ||
| 209 | <property name="leftMargin"> | ||
| 210 | <number>0</number> | ||
| 211 | </property> | ||
| 212 | <property name="topMargin"> | ||
| 213 | <number>0</number> | ||
| 214 | </property> | ||
| 215 | <property name="rightMargin"> | ||
| 216 | <number>0</number> | ||
| 217 | </property> | ||
| 218 | <property name="bottomMargin"> | ||
| 219 | <number>0</number> | ||
| 220 | </property> | ||
| 221 | <item> | ||
| 222 | <widget class="QLabel" name="label_player_6"> | ||
| 223 | <property name="text"> | ||
| 224 | <string>Player 6 Profile</string> | ||
| 225 | </property> | ||
| 226 | </widget> | ||
| 227 | </item> | ||
| 228 | <item> | ||
| 229 | <widget class="QComboBox" name="profile_player_6"> | ||
| 230 | <property name="sizePolicy"> | ||
| 231 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 232 | <horstretch>0</horstretch> | ||
| 233 | <verstretch>0</verstretch> | ||
| 234 | </sizepolicy> | ||
| 235 | </property> | ||
| 236 | </widget> | ||
| 237 | </item> | ||
| 238 | </layout> | ||
| 239 | </widget> | ||
| 240 | </item> | ||
| 241 | <item> | ||
| 242 | <widget class="QWidget" name="player_7" native="true"> | ||
| 243 | <layout class="QHBoxLayout" name="input_profile_layout_7"> | ||
| 244 | <property name="leftMargin"> | ||
| 245 | <number>0</number> | ||
| 246 | </property> | ||
| 247 | <property name="topMargin"> | ||
| 248 | <number>0</number> | ||
| 249 | </property> | ||
| 250 | <property name="rightMargin"> | ||
| 251 | <number>0</number> | ||
| 252 | </property> | ||
| 253 | <property name="bottomMargin"> | ||
| 254 | <number>0</number> | ||
| 255 | </property> | ||
| 256 | <item> | ||
| 257 | <widget class="QLabel" name="label_player_7"> | ||
| 258 | <property name="text"> | ||
| 259 | <string>Player 7 Profile</string> | ||
| 260 | </property> | ||
| 261 | </widget> | ||
| 262 | </item> | ||
| 263 | <item> | ||
| 264 | <widget class="QComboBox" name="profile_player_7"> | ||
| 265 | <property name="sizePolicy"> | ||
| 266 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 267 | <horstretch>0</horstretch> | ||
| 268 | <verstretch>0</verstretch> | ||
| 269 | </sizepolicy> | ||
| 270 | </property> | ||
| 271 | </widget> | ||
| 272 | </item> | ||
| 273 | </layout> | ||
| 274 | </widget> | ||
| 275 | </item> | ||
| 276 | <item> | ||
| 277 | <widget class="QWidget" name="player_8" native="true"> | ||
| 278 | <layout class="QHBoxLayout" name="input_profile_layout_8"> | ||
| 279 | <property name="leftMargin"> | ||
| 280 | <number>0</number> | ||
| 281 | </property> | ||
| 282 | <property name="topMargin"> | ||
| 283 | <number>0</number> | ||
| 284 | </property> | ||
| 285 | <property name="rightMargin"> | ||
| 286 | <number>0</number> | ||
| 287 | </property> | ||
| 288 | <property name="bottomMargin"> | ||
| 289 | <number>0</number> | ||
| 290 | </property> | ||
| 291 | <item> | ||
| 292 | <widget class="QLabel" name="label_player_8"> | ||
| 293 | <property name="text"> | ||
| 294 | <string>Player 8 Profile</string> | ||
| 295 | </property> | ||
| 296 | </widget> | ||
| 297 | </item> | ||
| 298 | <item> | ||
| 299 | <widget class="QComboBox" name="profile_player_8"> | ||
| 300 | <property name="sizePolicy"> | ||
| 301 | <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||
| 302 | <horstretch>0</horstretch> | ||
| 303 | <verstretch>0</verstretch> | ||
| 304 | </sizepolicy> | ||
| 305 | </property> | ||
| 306 | </widget> | ||
| 307 | </item> | ||
| 308 | </layout> | ||
| 309 | </widget> | ||
| 310 | </item> | ||
| 311 | </layout> | ||
| 312 | </widget> | ||
| 313 | </item> | ||
| 314 | </layout> | ||
| 315 | </item> | ||
| 316 | <item> | ||
| 317 | <spacer name="verticalSpacer"> | ||
| 318 | <property name="orientation"> | ||
| 319 | <enum>Qt::Vertical</enum> | ||
| 320 | </property> | ||
| 321 | <property name="sizeHint" stdset="0"> | ||
| 322 | <size> | ||
| 323 | <width>20</width> | ||
| 324 | <height>40</height> | ||
| 325 | </size> | ||
| 326 | </property> | ||
| 327 | </spacer> | ||
| 328 | </item> | ||
| 329 | </layout> | ||
| 330 | </widget> | ||
| 331 | <resources/> | ||
| 332 | <connections/> | ||
| 333 | </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() { | |||
| 1553 | } | 1553 | } |
| 1554 | 1554 | ||
| 1555 | void ConfigureInputPlayer::SaveProfile() { | 1555 | void ConfigureInputPlayer::SaveProfile() { |
| 1556 | static constexpr size_t HANDHELD_INDEX = 8; | ||
| 1556 | const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex()); | 1557 | const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex()); |
| 1557 | 1558 | ||
| 1558 | if (profile_name.isEmpty()) { | 1559 | if (profile_name.isEmpty()) { |
| @@ -1561,7 +1562,12 @@ void ConfigureInputPlayer::SaveProfile() { | |||
| 1561 | 1562 | ||
| 1562 | ApplyConfiguration(); | 1563 | ApplyConfiguration(); |
| 1563 | 1564 | ||
| 1564 | if (!profiles->SaveProfile(profile_name.toStdString(), player_index)) { | 1565 | // When we're in handheld mode, only the handheld emulated controller bindings are updated |
| 1566 | const bool is_handheld = player_index == 0 && emulated_controller->GetNpadIdType() == | ||
| 1567 | Core::HID::NpadIdType::Handheld; | ||
| 1568 | const auto profile_player_index = is_handheld ? HANDHELD_INDEX : player_index; | ||
| 1569 | |||
| 1570 | if (!profiles->SaveProfile(profile_name.toStdString(), profile_player_index)) { | ||
| 1565 | QMessageBox::critical(this, tr("Save Input Profile"), | 1571 | QMessageBox::critical(this, tr("Save Input Profile"), |
| 1566 | tr("Failed to save the input profile \"%1\"").arg(profile_name)); | 1572 | tr("Failed to save the input profile \"%1\"").arg(profile_name)); |
| 1567 | UpdateInputProfiles(); | 1573 | 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; | |||
| 38 | 38 | ||
| 39 | namespace Ui { | 39 | namespace Ui { |
| 40 | class ConfigureInputPlayer; | 40 | class ConfigureInputPlayer; |
| 41 | } | 41 | } // namespace Ui |
| 42 | 42 | ||
| 43 | namespace Core::HID { | 43 | namespace Core::HID { |
| 44 | class HIDCore; | 44 | 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 @@ | |||
| 28 | #include "yuzu/configuration/configure_general.h" | 28 | #include "yuzu/configuration/configure_general.h" |
| 29 | #include "yuzu/configuration/configure_graphics.h" | 29 | #include "yuzu/configuration/configure_graphics.h" |
| 30 | #include "yuzu/configuration/configure_graphics_advanced.h" | 30 | #include "yuzu/configuration/configure_graphics_advanced.h" |
| 31 | #include "yuzu/configuration/configure_input.h" | 31 | #include "yuzu/configuration/configure_input_per_game.h" |
| 32 | #include "yuzu/configuration/configure_per_game.h" | 32 | #include "yuzu/configuration/configure_per_game.h" |
| 33 | #include "yuzu/configuration/configure_per_game_addons.h" | 33 | #include "yuzu/configuration/configure_per_game_addons.h" |
| 34 | #include "yuzu/configuration/configure_system.h" | 34 | #include "yuzu/configuration/configure_system.h" |
| @@ -50,6 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st | |||
| 50 | general_tab = std::make_unique<ConfigureGeneral>(system_, this); | 50 | general_tab = std::make_unique<ConfigureGeneral>(system_, this); |
| 51 | graphics_tab = std::make_unique<ConfigureGraphics>(system_, this); | 51 | graphics_tab = std::make_unique<ConfigureGraphics>(system_, this); |
| 52 | graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); | 52 | graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); |
| 53 | input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); | ||
| 53 | system_tab = std::make_unique<ConfigureSystem>(system_, this); | 54 | system_tab = std::make_unique<ConfigureSystem>(system_, this); |
| 54 | 55 | ||
| 55 | ui->setupUi(this); | 56 | ui->setupUi(this); |
| @@ -61,6 +62,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st | |||
| 61 | ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); | 62 | ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); |
| 62 | ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); | 63 | ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); |
| 63 | ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); | 64 | ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); |
| 65 | ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); | ||
| 64 | 66 | ||
| 65 | setFocusPolicy(Qt::ClickFocus); | 67 | setFocusPolicy(Qt::ClickFocus); |
| 66 | setWindowTitle(tr("Properties")); | 68 | setWindowTitle(tr("Properties")); |
| @@ -91,6 +93,7 @@ void ConfigurePerGame::ApplyConfiguration() { | |||
| 91 | graphics_tab->ApplyConfiguration(); | 93 | graphics_tab->ApplyConfiguration(); |
| 92 | graphics_advanced_tab->ApplyConfiguration(); | 94 | graphics_advanced_tab->ApplyConfiguration(); |
| 93 | audio_tab->ApplyConfiguration(); | 95 | audio_tab->ApplyConfiguration(); |
| 96 | input_tab->ApplyConfiguration(); | ||
| 94 | 97 | ||
| 95 | system.ApplySettings(); | 98 | system.ApplySettings(); |
| 96 | Settings::LogSettings(); | 99 | 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 { | |||
| 16 | class System; | 16 | class System; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | namespace InputCommon { | ||
| 20 | class InputSubsystem; | ||
| 21 | } | ||
| 22 | |||
| 19 | class ConfigurePerGameAddons; | 23 | class ConfigurePerGameAddons; |
| 20 | class ConfigureAudio; | 24 | class ConfigureAudio; |
| 21 | class ConfigureCpu; | 25 | class ConfigureCpu; |
| 22 | class ConfigureGeneral; | 26 | class ConfigureGeneral; |
| 23 | class ConfigureGraphics; | 27 | class ConfigureGraphics; |
| 24 | class ConfigureGraphicsAdvanced; | 28 | class ConfigureGraphicsAdvanced; |
| 29 | class ConfigureInputPerGame; | ||
| 25 | class ConfigureSystem; | 30 | class ConfigureSystem; |
| 26 | 31 | ||
| 27 | class QGraphicsScene; | 32 | class QGraphicsScene; |
| @@ -72,5 +77,6 @@ private: | |||
| 72 | std::unique_ptr<ConfigureGeneral> general_tab; | 77 | std::unique_ptr<ConfigureGeneral> general_tab; |
| 73 | std::unique_ptr<ConfigureGraphics> graphics_tab; | 78 | std::unique_ptr<ConfigureGraphics> graphics_tab; |
| 74 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; | 79 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; |
| 80 | std::unique_ptr<ConfigureInputPerGame> input_tab; | ||
| 75 | std::unique_ptr<ConfigureSystem> system_tab; | 81 | std::unique_ptr<ConfigureSystem> system_tab; |
| 76 | }; | 82 | }; |
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 | |||
| 126 | #include "yuzu/compatibility_list.h" | 126 | #include "yuzu/compatibility_list.h" |
| 127 | #include "yuzu/configuration/config.h" | 127 | #include "yuzu/configuration/config.h" |
| 128 | #include "yuzu/configuration/configure_dialog.h" | 128 | #include "yuzu/configuration/configure_dialog.h" |
| 129 | #include "yuzu/configuration/configure_input_per_game.h" | ||
| 129 | #include "yuzu/debugger/console.h" | 130 | #include "yuzu/debugger/console.h" |
| 130 | #include "yuzu/debugger/controller.h" | 131 | #include "yuzu/debugger/controller.h" |
| 131 | #include "yuzu/debugger/profiler.h" | 132 | #include "yuzu/debugger/profiler.h" |
| @@ -1658,6 +1659,11 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | |||
| 1658 | LOG_INFO(Frontend, "yuzu starting..."); | 1659 | LOG_INFO(Frontend, "yuzu starting..."); |
| 1659 | StoreRecentFile(filename); // Put the filename on top of the list | 1660 | StoreRecentFile(filename); // Put the filename on top of the list |
| 1660 | 1661 | ||
| 1662 | // Save configurations | ||
| 1663 | UpdateUISettings(); | ||
| 1664 | game_list->SaveInterfaceLayout(); | ||
| 1665 | config->Save(); | ||
| 1666 | |||
| 1661 | u64 title_id{0}; | 1667 | u64 title_id{0}; |
| 1662 | 1668 | ||
| 1663 | last_filename_booted = filename; | 1669 | last_filename_booted = filename; |
| @@ -1674,14 +1680,10 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | |||
| 1674 | ? Common::FS::PathToUTF8String(file_path.filename()) | 1680 | ? Common::FS::PathToUTF8String(file_path.filename()) |
| 1675 | : fmt::format("{:016X}", title_id); | 1681 | : fmt::format("{:016X}", title_id); |
| 1676 | Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig); | 1682 | Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig); |
| 1683 | system->HIDCore().ReloadInputDevices(); | ||
| 1677 | system->ApplySettings(); | 1684 | system->ApplySettings(); |
| 1678 | } | 1685 | } |
| 1679 | 1686 | ||
| 1680 | // Save configurations | ||
| 1681 | UpdateUISettings(); | ||
| 1682 | game_list->SaveInterfaceLayout(); | ||
| 1683 | config->Save(); | ||
| 1684 | |||
| 1685 | Settings::LogSettings(); | 1687 | Settings::LogSettings(); |
| 1686 | 1688 | ||
| 1687 | if (UISettings::values.select_user_on_boot) { | 1689 | if (UISettings::values.select_user_on_boot) { |
| @@ -2802,6 +2804,7 @@ void GMainWindow::OnStopGame() { | |||
| 2802 | ShutdownGame(); | 2804 | ShutdownGame(); |
| 2803 | 2805 | ||
| 2804 | Settings::RestoreGlobalState(system->IsPoweredOn()); | 2806 | Settings::RestoreGlobalState(system->IsPoweredOn()); |
| 2807 | system->HIDCore().ReloadInputDevices(); | ||
| 2805 | UpdateStatusButtons(); | 2808 | UpdateStatusButtons(); |
| 2806 | } | 2809 | } |
| 2807 | 2810 | ||
| @@ -3281,6 +3284,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file | |||
| 3281 | // Do not cause the global config to write local settings into the config file | 3284 | // Do not cause the global config to write local settings into the config file |
| 3282 | const bool is_powered_on = system->IsPoweredOn(); | 3285 | const bool is_powered_on = system->IsPoweredOn(); |
| 3283 | Settings::RestoreGlobalState(is_powered_on); | 3286 | Settings::RestoreGlobalState(is_powered_on); |
| 3287 | system->HIDCore().ReloadInputDevices(); | ||
| 3284 | 3288 | ||
| 3285 | UISettings::values.configuration_applied = false; | 3289 | UISettings::values.configuration_applied = false; |
| 3286 | 3290 | ||
| @@ -3764,6 +3768,7 @@ void GMainWindow::OnCoreError(Core::SystemResultStatus result, std::string detai | |||
| 3764 | ShutdownGame(); | 3768 | ShutdownGame(); |
| 3765 | 3769 | ||
| 3766 | Settings::RestoreGlobalState(system->IsPoweredOn()); | 3770 | Settings::RestoreGlobalState(system->IsPoweredOn()); |
| 3771 | system->HIDCore().ReloadInputDevices(); | ||
| 3767 | UpdateStatusButtons(); | 3772 | UpdateStatusButtons(); |
| 3768 | } | 3773 | } |
| 3769 | } else { | 3774 | } else { |
| @@ -3915,18 +3920,19 @@ void GMainWindow::closeEvent(QCloseEvent* event) { | |||
| 3915 | // Unload controllers early | 3920 | // Unload controllers early |
| 3916 | controller_dialog->UnloadController(); | 3921 | controller_dialog->UnloadController(); |
| 3917 | game_list->UnloadController(); | 3922 | game_list->UnloadController(); |
| 3918 | system->HIDCore().UnloadInputDevices(); | ||
| 3919 | 3923 | ||
| 3920 | // Shutdown session if the emu thread is active... | 3924 | // Shutdown session if the emu thread is active... |
| 3921 | if (emu_thread != nullptr) { | 3925 | if (emu_thread != nullptr) { |
| 3922 | ShutdownGame(); | 3926 | ShutdownGame(); |
| 3923 | 3927 | ||
| 3924 | Settings::RestoreGlobalState(system->IsPoweredOn()); | 3928 | Settings::RestoreGlobalState(system->IsPoweredOn()); |
| 3929 | system->HIDCore().ReloadInputDevices(); | ||
| 3925 | UpdateStatusButtons(); | 3930 | UpdateStatusButtons(); |
| 3926 | } | 3931 | } |
| 3927 | 3932 | ||
| 3928 | render_window->close(); | 3933 | render_window->close(); |
| 3929 | multiplayer_state->Close(); | 3934 | multiplayer_state->Close(); |
| 3935 | system->HIDCore().UnloadInputDevices(); | ||
| 3930 | system->GetRoomNetwork().Shutdown(); | 3936 | system->GetRoomNetwork().Shutdown(); |
| 3931 | 3937 | ||
| 3932 | QWidget::closeEvent(event); | 3938 | 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) | |||
| 38 | if (MSVC) | 38 | if (MSVC) |
| 39 | target_link_libraries(yuzu-cmd PRIVATE getopt) | 39 | target_link_libraries(yuzu-cmd PRIVATE getopt) |
| 40 | endif() | 40 | endif() |
| 41 | target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} SDL2 Threads::Threads) | 41 | target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) |
| 42 | 42 | ||
| 43 | create_resource("../../dist/yuzu.bmp" "yuzu_cmd/yuzu_icon.h" "yuzu_icon") | 43 | create_resource("../../dist/yuzu.bmp" "yuzu_cmd/yuzu_icon.h" "yuzu_icon") |
| 44 | target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR}) | 44 | target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR}) |