Compare commits
38 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adec4d0da7 | ||
|
|
4e89979c87 | ||
|
|
8fd4e44014 | ||
|
|
49219b8a86 | ||
|
|
d6b63239ae | ||
|
|
cafca891ea | ||
|
|
c845d8a9e8 | ||
|
|
1a6785d296 | ||
|
|
b6d93b2c77 | ||
|
|
c4af7b3f5c | ||
|
|
96ffc174aa | ||
|
|
d7ec031419 | ||
|
|
55a3cbfa0d | ||
|
|
55b546a110 | ||
|
|
6b8ab9ed8f | ||
|
|
a7f1fa7bfc | ||
|
|
b6373c5ea5 | ||
|
|
0941ae0b61 | ||
|
|
47b133c0b8 | ||
|
|
a9efea8ae9 | ||
|
|
25dda06f49 | ||
|
|
7a329ae56c | ||
|
|
d0883027d6 | ||
|
|
bbb963a31a | ||
|
|
51abe35e05 | ||
|
|
64ff79f919 | ||
|
|
e507c01a22 | ||
|
|
ad787b20ca | ||
|
|
c2c9b44749 | ||
|
|
8265c167d3 | ||
|
|
780ae92265 | ||
|
|
2ec7d0b5fd | ||
|
|
7f42432f42 | ||
|
|
e96f55b6e2 | ||
|
|
7d8095d944 | ||
|
|
8f6245be9a | ||
|
|
35319ca3a5 | ||
|
|
3e6c835a64 |
@@ -1,7 +1,7 @@
|
||||
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
||||
|
||||
1
externals/CMakeLists.txt
vendored
1
externals/CMakeLists.txt
vendored
@@ -69,7 +69,6 @@ if (YUZU_USE_EXTERNAL_SDL2)
|
||||
set(SDL_SHARED OFF)
|
||||
|
||||
add_subdirectory(SDL EXCLUDE_FROM_ALL)
|
||||
add_library(SDL2 ALIAS SDL2-static)
|
||||
endif()
|
||||
|
||||
# ENet
|
||||
|
||||
@@ -226,6 +226,10 @@ if(ENABLE_CUBEB)
|
||||
target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
|
||||
endif()
|
||||
if(ENABLE_SDL2)
|
||||
target_link_libraries(audio_core PRIVATE SDL2)
|
||||
if (YUZU_USE_EXTERNAL_SDL2)
|
||||
target_link_libraries(audio_core PRIVATE SDL2-static)
|
||||
else()
|
||||
target_link_libraries(audio_core PRIVATE SDL2)
|
||||
endif()
|
||||
target_compile_definitions(audio_core PRIVATE HAVE_SDL2)
|
||||
endif()
|
||||
|
||||
@@ -266,19 +266,20 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
|
||||
}
|
||||
|
||||
void SinkStream::Stall() {
|
||||
if (stalled) {
|
||||
std::scoped_lock lk{stall_guard};
|
||||
if (stalled_lock) {
|
||||
return;
|
||||
}
|
||||
stalled = true;
|
||||
system.StallProcesses();
|
||||
stalled_lock = system.StallProcesses();
|
||||
}
|
||||
|
||||
void SinkStream::Unstall() {
|
||||
if (!stalled) {
|
||||
std::scoped_lock lk{stall_guard};
|
||||
if (!stalled_lock) {
|
||||
return;
|
||||
}
|
||||
system.UnstallProcesses();
|
||||
stalled = false;
|
||||
stalled_lock.unlock();
|
||||
}
|
||||
|
||||
} // namespace AudioCore::Sink
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
@@ -240,8 +241,8 @@ private:
|
||||
f32 system_volume{1.0f};
|
||||
/// Set via IAudioDevice service calls
|
||||
f32 device_volume{1.0f};
|
||||
/// True if coretiming has been stalled
|
||||
bool stalled{false};
|
||||
std::mutex stall_guard;
|
||||
std::unique_lock<std::mutex> stalled_lock;
|
||||
};
|
||||
|
||||
using SinkStreamPtr = std::unique_ptr<SinkStream>;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "alignment.h"
|
||||
#include "cache_management.h"
|
||||
#include "common_types.h"
|
||||
#include "common/cache_management.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdlib.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
||||
@@ -383,6 +383,16 @@ void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDevic
|
||||
}
|
||||
}
|
||||
|
||||
inline void RegisterInputFactory(const std::string& name,
|
||||
std::shared_ptr<Factory<InputDevice>> factory) {
|
||||
RegisterFactory<InputDevice>(name, std::move(factory));
|
||||
}
|
||||
|
||||
inline void RegisterOutputFactory(const std::string& name,
|
||||
std::shared_ptr<Factory<OutputDevice>> factory) {
|
||||
RegisterFactory<OutputDevice>(name, std::move(factory));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters an input device factory.
|
||||
* @tparam InputDeviceType the type of input devices the factory can create
|
||||
@@ -395,6 +405,14 @@ void UnregisterFactory(const std::string& name) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void UnregisterInputFactory(const std::string& name) {
|
||||
UnregisterFactory<InputDevice>(name);
|
||||
}
|
||||
|
||||
inline void UnregisterOutputFactory(const std::string& name) {
|
||||
UnregisterFactory<OutputDevice>(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an input device from given paramters.
|
||||
* @tparam InputDeviceType the type of input devices to create
|
||||
@@ -416,13 +434,21 @@ std::unique_ptr<InputDeviceType> CreateDeviceFromString(const std::string& param
|
||||
return pair->second->Create(package);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<InputDevice> CreateInputDeviceFromString(const std::string& params) {
|
||||
return CreateDeviceFromString<InputDevice>(params);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<OutputDevice> CreateOutputDeviceFromString(const std::string& params) {
|
||||
return CreateDeviceFromString<OutputDevice>(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an input device from given paramters.
|
||||
* Create an input device from given parameters.
|
||||
* @tparam InputDeviceType the type of input devices to create
|
||||
* @param A ParamPackage that contains all parameters for creating the device
|
||||
* @param package A ParamPackage that contains all parameters for creating the device
|
||||
*/
|
||||
template <typename InputDeviceType>
|
||||
std::unique_ptr<InputDeviceType> CreateDevice(const Common::ParamPackage package) {
|
||||
std::unique_ptr<InputDeviceType> CreateDevice(const ParamPackage& package) {
|
||||
const std::string engine = package.Get("engine", "null");
|
||||
const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
|
||||
const auto pair = factory_list.find(engine);
|
||||
@@ -435,4 +461,12 @@ std::unique_ptr<InputDeviceType> CreateDevice(const Common::ParamPackage package
|
||||
return pair->second->Create(package);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<InputDevice> CreateInputDevice(const ParamPackage& package) {
|
||||
return CreateDevice<InputDevice>(package);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<OutputDevice> CreateOutputDevice(const ParamPackage& package) {
|
||||
return CreateDevice<OutputDevice>(package);
|
||||
}
|
||||
|
||||
} // namespace Common::Input
|
||||
|
||||
@@ -189,7 +189,7 @@ struct System::Impl {
|
||||
|
||||
kernel.Suspend(false);
|
||||
core_timing.SyncPause(false);
|
||||
is_paused = false;
|
||||
is_paused.store(false, std::memory_order_relaxed);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -200,14 +200,13 @@ struct System::Impl {
|
||||
|
||||
core_timing.SyncPause(true);
|
||||
kernel.Suspend(true);
|
||||
is_paused = true;
|
||||
is_paused.store(true, std::memory_order_relaxed);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool IsPaused() const {
|
||||
std::unique_lock lk(suspend_guard);
|
||||
return is_paused;
|
||||
return is_paused.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> StallProcesses() {
|
||||
@@ -218,7 +217,7 @@ struct System::Impl {
|
||||
}
|
||||
|
||||
void UnstallProcesses() {
|
||||
if (!is_paused) {
|
||||
if (!IsPaused()) {
|
||||
core_timing.SyncPause(false);
|
||||
kernel.Suspend(false);
|
||||
}
|
||||
@@ -465,7 +464,7 @@ struct System::Impl {
|
||||
}
|
||||
|
||||
mutable std::mutex suspend_guard;
|
||||
bool is_paused{};
|
||||
std::atomic_bool is_paused{};
|
||||
std::atomic<bool> is_shutting_down{};
|
||||
|
||||
Timing::CoreTiming core_timing;
|
||||
|
||||
@@ -68,7 +68,7 @@ void EmulatedConsole::ReloadInput() {
|
||||
// If you load any device here add the equivalent to the UnloadInput() function
|
||||
SetTouchParams();
|
||||
|
||||
motion_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(motion_params);
|
||||
motion_devices = Common::Input::CreateInputDevice(motion_params);
|
||||
if (motion_devices) {
|
||||
motion_devices->SetCallback({
|
||||
.on_change =
|
||||
@@ -79,7 +79,7 @@ void EmulatedConsole::ReloadInput() {
|
||||
// Unique index for identifying touch device source
|
||||
std::size_t index = 0;
|
||||
for (auto& touch_device : touch_devices) {
|
||||
touch_device = Common::Input::CreateDevice<Common::Input::InputDevice>(touch_params[index]);
|
||||
touch_device = Common::Input::CreateInputDevice(touch_params[index]);
|
||||
if (!touch_device) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/input_converter.h"
|
||||
@@ -144,29 +146,23 @@ void EmulatedController::LoadDevices() {
|
||||
|
||||
LoadTASParams();
|
||||
|
||||
std::transform(button_params.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
|
||||
button_params.begin() + Settings::NativeButton::BUTTON_NS_END,
|
||||
button_devices.begin(), Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
std::transform(stick_params.begin() + Settings::NativeAnalog::STICK_HID_BEGIN,
|
||||
stick_params.begin() + Settings::NativeAnalog::STICK_HID_END,
|
||||
stick_devices.begin(), Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
std::transform(motion_params.begin() + Settings::NativeMotion::MOTION_HID_BEGIN,
|
||||
motion_params.begin() + Settings::NativeMotion::MOTION_HID_END,
|
||||
motion_devices.begin(), Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
std::transform(trigger_params.begin(), trigger_params.end(), trigger_devices.begin(),
|
||||
Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
std::transform(battery_params.begin(), battery_params.end(), battery_devices.begin(),
|
||||
Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
camera_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(camera_params);
|
||||
nfc_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(nfc_params);
|
||||
std::transform(output_params.begin(), output_params.end(), output_devices.begin(),
|
||||
Common::Input::CreateDevice<Common::Input::OutputDevice>);
|
||||
std::ranges::transform(button_params, button_devices.begin(), Common::Input::CreateInputDevice);
|
||||
std::ranges::transform(stick_params, stick_devices.begin(), Common::Input::CreateInputDevice);
|
||||
std::ranges::transform(motion_params, motion_devices.begin(), Common::Input::CreateInputDevice);
|
||||
std::ranges::transform(trigger_params, trigger_devices.begin(),
|
||||
Common::Input::CreateInputDevice);
|
||||
std::ranges::transform(battery_params, battery_devices.begin(),
|
||||
Common::Input::CreateInputDevice);
|
||||
camera_devices = Common::Input::CreateInputDevice(camera_params);
|
||||
nfc_devices = Common::Input::CreateInputDevice(nfc_params);
|
||||
std::ranges::transform(output_params, output_devices.begin(),
|
||||
Common::Input::CreateOutputDevice);
|
||||
|
||||
// Initialize TAS devices
|
||||
std::transform(tas_button_params.begin(), tas_button_params.end(), tas_button_devices.begin(),
|
||||
Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
std::transform(tas_stick_params.begin(), tas_stick_params.end(), tas_stick_devices.begin(),
|
||||
Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
std::ranges::transform(tas_button_params, tas_button_devices.begin(),
|
||||
Common::Input::CreateInputDevice);
|
||||
std::ranges::transform(tas_stick_params, tas_stick_devices.begin(),
|
||||
Common::Input::CreateInputDevice);
|
||||
}
|
||||
|
||||
void EmulatedController::LoadTASParams() {
|
||||
|
||||
@@ -25,12 +25,12 @@ void EmulatedDevices::ReloadInput() {
|
||||
Common::ParamPackage mouse_params;
|
||||
mouse_params.Set("engine", "mouse");
|
||||
mouse_params.Set("button", static_cast<int>(key_index));
|
||||
mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params);
|
||||
mouse_device = Common::Input::CreateInputDevice(mouse_params);
|
||||
key_index++;
|
||||
}
|
||||
|
||||
mouse_stick_device = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
"engine:mouse,axis_x:0,axis_y:1");
|
||||
mouse_stick_device =
|
||||
Common::Input::CreateInputDeviceFromString("engine:mouse,axis_x:0,axis_y:1");
|
||||
|
||||
// First two axis are reserved for mouse position
|
||||
key_index = 2;
|
||||
@@ -38,7 +38,7 @@ void EmulatedDevices::ReloadInput() {
|
||||
Common::ParamPackage mouse_params;
|
||||
mouse_params.Set("engine", "mouse");
|
||||
mouse_params.Set("axis", static_cast<int>(key_index));
|
||||
mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params);
|
||||
mouse_device = Common::Input::CreateInputDevice(mouse_params);
|
||||
key_index++;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ void EmulatedDevices::ReloadInput() {
|
||||
keyboard_params.Set("button", static_cast<int>(key_index));
|
||||
keyboard_params.Set("port", 1);
|
||||
keyboard_params.Set("pad", 0);
|
||||
keyboard_device = Common::Input::CreateDevice<Common::Input::InputDevice>(keyboard_params);
|
||||
keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
|
||||
key_index++;
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ void EmulatedDevices::ReloadInput() {
|
||||
keyboard_params.Set("button", static_cast<int>(key_index));
|
||||
keyboard_params.Set("port", 1);
|
||||
keyboard_params.Set("pad", 1);
|
||||
keyboard_device = Common::Input::CreateDevice<Common::Input::InputDevice>(keyboard_params);
|
||||
keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
|
||||
key_index++;
|
||||
}
|
||||
|
||||
ring_analog_device = Common::Input::CreateDevice<Common::Input::InputDevice>(ring_params);
|
||||
ring_analog_device = Common::Input::CreateInputDevice(ring_params);
|
||||
|
||||
for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) {
|
||||
if (!mouse_button_devices[index]) {
|
||||
|
||||
@@ -28,13 +28,15 @@ SyncpointManager::SyncpointManager(Tegra::Host1x::Host1x& host1x_) : host1x{host
|
||||
SyncpointManager::~SyncpointManager() = default;
|
||||
|
||||
u32 SyncpointManager::ReserveSyncpoint(u32 id, bool client_managed) {
|
||||
if (syncpoints.at(id).reserved) {
|
||||
auto& syncpoint = syncpoints.at(id);
|
||||
|
||||
if (syncpoint.reserved) {
|
||||
ASSERT_MSG(false, "Requested syncpoint is in use");
|
||||
return 0;
|
||||
}
|
||||
|
||||
syncpoints.at(id).reserved = true;
|
||||
syncpoints.at(id).interface_managed = client_managed;
|
||||
syncpoint.reserved = true;
|
||||
syncpoint.interface_managed = client_managed;
|
||||
|
||||
return id;
|
||||
}
|
||||
@@ -56,11 +58,12 @@ u32 SyncpointManager::AllocateSyncpoint(bool client_managed) {
|
||||
|
||||
void SyncpointManager::FreeSyncpoint(u32 id) {
|
||||
std::lock_guard lock(reservation_lock);
|
||||
ASSERT(syncpoints.at(id).reserved);
|
||||
syncpoints.at(id).reserved = false;
|
||||
auto& syncpoint = syncpoints.at(id);
|
||||
ASSERT(syncpoint.reserved);
|
||||
syncpoint.reserved = false;
|
||||
}
|
||||
|
||||
bool SyncpointManager::IsSyncpointAllocated(u32 id) {
|
||||
bool SyncpointManager::IsSyncpointAllocated(u32 id) const {
|
||||
return (id <= SyncpointCount) && syncpoints[id].reserved;
|
||||
}
|
||||
|
||||
@@ -69,7 +72,7 @@ bool SyncpointManager::HasSyncpointExpired(u32 id, u32 threshold) const {
|
||||
|
||||
if (!syncpoint.reserved) {
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the interface manages counters then we don't keep track of the maximum value as it handles
|
||||
@@ -82,40 +85,51 @@ bool SyncpointManager::HasSyncpointExpired(u32 id, u32 threshold) const {
|
||||
}
|
||||
|
||||
u32 SyncpointManager::IncrementSyncpointMaxExt(u32 id, u32 amount) {
|
||||
if (!syncpoints.at(id).reserved) {
|
||||
auto& syncpoint = syncpoints.at(id);
|
||||
|
||||
if (!syncpoint.reserved) {
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return syncpoints.at(id).counter_max += amount;
|
||||
return syncpoint.counter_max += amount;
|
||||
}
|
||||
|
||||
u32 SyncpointManager::ReadSyncpointMinValue(u32 id) {
|
||||
if (!syncpoints.at(id).reserved) {
|
||||
auto& syncpoint = syncpoints.at(id);
|
||||
|
||||
if (!syncpoint.reserved) {
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return syncpoints.at(id).counter_min;
|
||||
return syncpoint.counter_min;
|
||||
}
|
||||
|
||||
u32 SyncpointManager::UpdateMin(u32 id) {
|
||||
if (!syncpoints.at(id).reserved) {
|
||||
auto& syncpoint = syncpoints.at(id);
|
||||
|
||||
if (!syncpoint.reserved) {
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
syncpoints.at(id).counter_min = host1x.GetSyncpointManager().GetHostSyncpointValue(id);
|
||||
return syncpoints.at(id).counter_min;
|
||||
syncpoint.counter_min = host1x.GetSyncpointManager().GetHostSyncpointValue(id);
|
||||
return syncpoint.counter_min;
|
||||
}
|
||||
|
||||
NvFence SyncpointManager::GetSyncpointFence(u32 id) {
|
||||
if (!syncpoints.at(id).reserved) {
|
||||
auto& syncpoint = syncpoints.at(id);
|
||||
|
||||
if (!syncpoint.reserved) {
|
||||
ASSERT(false);
|
||||
return NvFence{};
|
||||
}
|
||||
|
||||
return {.id = static_cast<s32>(id), .value = syncpoints.at(id).counter_max};
|
||||
return {
|
||||
.id = static_cast<s32>(id),
|
||||
.value = syncpoint.counter_max,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::NvCore
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
/**
|
||||
* @brief Checks if the given syncpoint is both allocated and below the number of HW syncpoints
|
||||
*/
|
||||
bool IsSyncpointAllocated(u32 id);
|
||||
bool IsSyncpointAllocated(u32 id) const;
|
||||
|
||||
/**
|
||||
* @brief Finds a free syncpoint and reserves it
|
||||
|
||||
@@ -55,48 +55,40 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
|
||||
Module::Module(Core::System& system)
|
||||
: container{system.Host1x()}, service_context{system, "nvdrv"}, events_interface{*this} {
|
||||
builders["/dev/nvhost-as-gpu"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvhost_as_gpu>(system, *this, container);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvhost_as_gpu>(system, *this, container);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvhost-gpu"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvhost_gpu>(system, events_interface, container);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvhost_gpu>(system, events_interface, container);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvhost-ctrl-gpu"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvhost_ctrl_gpu>(system, events_interface);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvhost_ctrl_gpu>(system, events_interface);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvmap"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvmap>(system, container);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvmap>(system, container);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvdisp_disp0"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvdisp_disp0>(system, container);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvdisp_disp0>(system, container);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvhost-ctrl"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvhost_ctrl>(system, events_interface, container);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvhost_ctrl>(system, events_interface, container);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvhost-nvdec"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvhost_nvdec>(system, container);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvhost_nvdec>(system, container);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvhost-nvjpg"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device = std::make_shared<Devices::nvhost_nvjpg>(system);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvhost_nvjpg>(system);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
builders["/dev/nvhost-vic"] = [this, &system](DeviceFD fd) {
|
||||
std::shared_ptr<Devices::nvdevice> device =
|
||||
std::make_shared<Devices::nvhost_vic>(system, container);
|
||||
return open_files.emplace(fd, device).first;
|
||||
auto device = std::make_shared<Devices::nvhost_vic>(system, container);
|
||||
return open_files.emplace(fd, std::move(device)).first;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Service::android {
|
||||
|
||||
class IProducerListener {
|
||||
public:
|
||||
virtual ~IProducerListener() = default;
|
||||
virtual void OnBufferReleased() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,11 @@ if (ENABLE_SDL2)
|
||||
drivers/sdl_driver.cpp
|
||||
drivers/sdl_driver.h
|
||||
)
|
||||
target_link_libraries(input_common PRIVATE SDL2)
|
||||
if (YUZU_USE_EXTERNAL_SDL2)
|
||||
target_link_libraries(input_common PRIVATE SDL2-static)
|
||||
else()
|
||||
target_link_libraries(input_common PRIVATE SDL2)
|
||||
endif()
|
||||
target_compile_definitions(input_common PRIVATE HAVE_SDL2)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -361,6 +361,12 @@ void SDLDriver::CloseJoystick(SDL_Joystick* sdl_joystick) {
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDriver::PumpEvents() const {
|
||||
if (initialized) {
|
||||
SDL_PumpEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) {
|
||||
switch (event.type) {
|
||||
case SDL_JOYBUTTONUP: {
|
||||
@@ -451,14 +457,6 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
|
||||
|
||||
initialized = true;
|
||||
if (start_thread) {
|
||||
poll_thread = std::thread([this] {
|
||||
Common::SetCurrentThreadName("SDL_MainLoop");
|
||||
using namespace std::chrono_literals;
|
||||
while (initialized) {
|
||||
SDL_PumpEvents();
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
});
|
||||
vibration_thread = std::thread([this] {
|
||||
Common::SetCurrentThreadName("SDL_Vibration");
|
||||
using namespace std::chrono_literals;
|
||||
@@ -481,7 +479,6 @@ SDLDriver::~SDLDriver() {
|
||||
|
||||
initialized = false;
|
||||
if (start_thread) {
|
||||
poll_thread.join();
|
||||
vibration_thread.join();
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ public:
|
||||
/// Unregisters SDL device factories and shut them down.
|
||||
~SDLDriver() override;
|
||||
|
||||
void PumpEvents() const;
|
||||
|
||||
/// Handle SDL_Events for joysticks from SDL_PollEvent
|
||||
void HandleGameControllerEvent(const SDL_Event& event);
|
||||
|
||||
@@ -128,7 +130,6 @@ private:
|
||||
bool start_thread = false;
|
||||
std::atomic<bool> initialized = false;
|
||||
|
||||
std::thread poll_thread;
|
||||
std::thread vibration_thread;
|
||||
};
|
||||
} // namespace InputCommon
|
||||
|
||||
@@ -294,6 +294,15 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr Common::Input::AnalogProperties properties{
|
||||
.deadzone = 0.0f,
|
||||
.range = 1.0f,
|
||||
.threshold = 0.5f,
|
||||
.offset = 0.0f,
|
||||
.inverted = false,
|
||||
.toggle = false,
|
||||
};
|
||||
|
||||
Button up;
|
||||
Button down;
|
||||
Button left;
|
||||
@@ -311,23 +320,17 @@ private:
|
||||
float last_x_axis_value{};
|
||||
float last_y_axis_value{};
|
||||
Common::Input::ButtonStatus modifier_status{};
|
||||
const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false};
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update;
|
||||
};
|
||||
|
||||
std::unique_ptr<Common::Input::InputDevice> StickFromButton::Create(
|
||||
const Common::ParamPackage& params) {
|
||||
const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
|
||||
auto up = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
params.Get("up", null_engine));
|
||||
auto down = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
params.Get("down", null_engine));
|
||||
auto left = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
params.Get("left", null_engine));
|
||||
auto right = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
params.Get("right", null_engine));
|
||||
auto modifier = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
params.Get("modifier", null_engine));
|
||||
auto up = Common::Input::CreateInputDeviceFromString(params.Get("up", null_engine));
|
||||
auto down = Common::Input::CreateInputDeviceFromString(params.Get("down", null_engine));
|
||||
auto left = Common::Input::CreateInputDeviceFromString(params.Get("left", null_engine));
|
||||
auto right = Common::Input::CreateInputDeviceFromString(params.Get("right", null_engine));
|
||||
auto modifier = Common::Input::CreateInputDeviceFromString(params.Get("modifier", null_engine));
|
||||
auto modifier_scale = params.Get("modifier_scale", 0.5f);
|
||||
auto modifier_angle = params.Get("modifier_angle", 5.5f);
|
||||
return std::make_unique<Stick>(std::move(up), std::move(down), std::move(left),
|
||||
|
||||
@@ -59,18 +59,25 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr Common::Input::AnalogProperties properties{
|
||||
.deadzone = 0.0f,
|
||||
.range = 1.0f,
|
||||
.threshold = 0.5f,
|
||||
.offset = 0.0f,
|
||||
.inverted = false,
|
||||
.toggle = false,
|
||||
};
|
||||
|
||||
Button button;
|
||||
bool last_button_value;
|
||||
const float x;
|
||||
const float y;
|
||||
const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false};
|
||||
};
|
||||
|
||||
std::unique_ptr<Common::Input::InputDevice> TouchFromButton::Create(
|
||||
const Common::ParamPackage& params) {
|
||||
const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
|
||||
auto button = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
params.Get("button", null_engine));
|
||||
auto button = Common::Input::CreateInputDeviceFromString(params.Get("button", null_engine));
|
||||
const float x = params.Get("x", 0.0f) / 1280.0f;
|
||||
const float y = params.Get("y", 0.0f) / 720.0f;
|
||||
return std::make_unique<TouchFromButtonDevice>(std::move(button), x, y);
|
||||
|
||||
@@ -33,129 +33,113 @@ struct InputSubsystem::Impl {
|
||||
keyboard->SetMappingCallback(mapping_callback);
|
||||
keyboard_factory = std::make_shared<InputFactory>(keyboard);
|
||||
keyboard_output_factory = std::make_shared<OutputFactory>(keyboard);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(keyboard->GetEngineName(),
|
||||
keyboard_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(keyboard->GetEngineName(),
|
||||
keyboard_output_factory);
|
||||
Common::Input::RegisterInputFactory(keyboard->GetEngineName(), keyboard_factory);
|
||||
Common::Input::RegisterOutputFactory(keyboard->GetEngineName(), keyboard_output_factory);
|
||||
|
||||
mouse = std::make_shared<Mouse>("mouse");
|
||||
mouse->SetMappingCallback(mapping_callback);
|
||||
mouse_factory = std::make_shared<InputFactory>(mouse);
|
||||
mouse_output_factory = std::make_shared<OutputFactory>(mouse);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(mouse->GetEngineName(),
|
||||
mouse_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(mouse->GetEngineName(),
|
||||
mouse_output_factory);
|
||||
Common::Input::RegisterInputFactory(mouse->GetEngineName(), mouse_factory);
|
||||
Common::Input::RegisterOutputFactory(mouse->GetEngineName(), mouse_output_factory);
|
||||
|
||||
touch_screen = std::make_shared<TouchScreen>("touch");
|
||||
touch_screen_factory = std::make_shared<InputFactory>(touch_screen);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(touch_screen->GetEngineName(),
|
||||
touch_screen_factory);
|
||||
Common::Input::RegisterInputFactory(touch_screen->GetEngineName(), touch_screen_factory);
|
||||
|
||||
gcadapter = std::make_shared<GCAdapter>("gcpad");
|
||||
gcadapter->SetMappingCallback(mapping_callback);
|
||||
gcadapter_input_factory = std::make_shared<InputFactory>(gcadapter);
|
||||
gcadapter_output_factory = std::make_shared<OutputFactory>(gcadapter);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(gcadapter->GetEngineName(),
|
||||
gcadapter_input_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(gcadapter->GetEngineName(),
|
||||
gcadapter_output_factory);
|
||||
Common::Input::RegisterInputFactory(gcadapter->GetEngineName(), gcadapter_input_factory);
|
||||
Common::Input::RegisterOutputFactory(gcadapter->GetEngineName(), gcadapter_output_factory);
|
||||
|
||||
udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp");
|
||||
udp_client->SetMappingCallback(mapping_callback);
|
||||
udp_client_input_factory = std::make_shared<InputFactory>(udp_client);
|
||||
udp_client_output_factory = std::make_shared<OutputFactory>(udp_client);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(udp_client->GetEngineName(),
|
||||
udp_client_input_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(udp_client->GetEngineName(),
|
||||
udp_client_output_factory);
|
||||
Common::Input::RegisterInputFactory(udp_client->GetEngineName(), udp_client_input_factory);
|
||||
Common::Input::RegisterOutputFactory(udp_client->GetEngineName(),
|
||||
udp_client_output_factory);
|
||||
|
||||
tas_input = std::make_shared<TasInput::Tas>("tas");
|
||||
tas_input->SetMappingCallback(mapping_callback);
|
||||
tas_input_factory = std::make_shared<InputFactory>(tas_input);
|
||||
tas_output_factory = std::make_shared<OutputFactory>(tas_input);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(tas_input->GetEngineName(),
|
||||
tas_input_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(tas_input->GetEngineName(),
|
||||
tas_output_factory);
|
||||
Common::Input::RegisterInputFactory(tas_input->GetEngineName(), tas_input_factory);
|
||||
Common::Input::RegisterOutputFactory(tas_input->GetEngineName(), tas_output_factory);
|
||||
|
||||
camera = std::make_shared<Camera>("camera");
|
||||
camera->SetMappingCallback(mapping_callback);
|
||||
camera_input_factory = std::make_shared<InputFactory>(camera);
|
||||
camera_output_factory = std::make_shared<OutputFactory>(camera);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(camera->GetEngineName(),
|
||||
camera_input_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(camera->GetEngineName(),
|
||||
camera_output_factory);
|
||||
Common::Input::RegisterInputFactory(camera->GetEngineName(), camera_input_factory);
|
||||
Common::Input::RegisterOutputFactory(camera->GetEngineName(), camera_output_factory);
|
||||
|
||||
virtual_amiibo = std::make_shared<VirtualAmiibo>("virtual_amiibo");
|
||||
virtual_amiibo->SetMappingCallback(mapping_callback);
|
||||
virtual_amiibo_input_factory = std::make_shared<InputFactory>(virtual_amiibo);
|
||||
virtual_amiibo_output_factory = std::make_shared<OutputFactory>(virtual_amiibo);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(virtual_amiibo->GetEngineName(),
|
||||
virtual_amiibo_input_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(virtual_amiibo->GetEngineName(),
|
||||
virtual_amiibo_output_factory);
|
||||
Common::Input::RegisterInputFactory(virtual_amiibo->GetEngineName(),
|
||||
virtual_amiibo_input_factory);
|
||||
Common::Input::RegisterOutputFactory(virtual_amiibo->GetEngineName(),
|
||||
virtual_amiibo_output_factory);
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
sdl = std::make_shared<SDLDriver>("sdl");
|
||||
sdl->SetMappingCallback(mapping_callback);
|
||||
sdl_input_factory = std::make_shared<InputFactory>(sdl);
|
||||
sdl_output_factory = std::make_shared<OutputFactory>(sdl);
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(sdl->GetEngineName(),
|
||||
sdl_input_factory);
|
||||
Common::Input::RegisterFactory<Common::Input::OutputDevice>(sdl->GetEngineName(),
|
||||
sdl_output_factory);
|
||||
Common::Input::RegisterInputFactory(sdl->GetEngineName(), sdl_input_factory);
|
||||
Common::Input::RegisterOutputFactory(sdl->GetEngineName(), sdl_output_factory);
|
||||
#endif
|
||||
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(
|
||||
"touch_from_button", std::make_shared<TouchFromButton>());
|
||||
Common::Input::RegisterFactory<Common::Input::InputDevice>(
|
||||
"analog_from_button", std::make_shared<StickFromButton>());
|
||||
Common::Input::RegisterInputFactory("touch_from_button",
|
||||
std::make_shared<TouchFromButton>());
|
||||
Common::Input::RegisterInputFactory("analog_from_button",
|
||||
std::make_shared<StickFromButton>());
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(keyboard->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(keyboard->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(keyboard->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(keyboard->GetEngineName());
|
||||
keyboard.reset();
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(mouse->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(mouse->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(mouse->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(mouse->GetEngineName());
|
||||
mouse.reset();
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(touch_screen->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(touch_screen->GetEngineName());
|
||||
touch_screen.reset();
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(gcadapter->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(gcadapter->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(gcadapter->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(gcadapter->GetEngineName());
|
||||
gcadapter.reset();
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(udp_client->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(udp_client->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(udp_client->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(udp_client->GetEngineName());
|
||||
udp_client.reset();
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(tas_input->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(tas_input->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(tas_input->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(tas_input->GetEngineName());
|
||||
tas_input.reset();
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(camera->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(camera->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(camera->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(camera->GetEngineName());
|
||||
camera.reset();
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(
|
||||
virtual_amiibo->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(
|
||||
virtual_amiibo->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(virtual_amiibo->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(virtual_amiibo->GetEngineName());
|
||||
virtual_amiibo.reset();
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>(sdl->GetEngineName());
|
||||
Common::Input::UnregisterFactory<Common::Input::OutputDevice>(sdl->GetEngineName());
|
||||
Common::Input::UnregisterInputFactory(sdl->GetEngineName());
|
||||
Common::Input::UnregisterOutputFactory(sdl->GetEngineName());
|
||||
sdl.reset();
|
||||
#endif
|
||||
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>("touch_from_button");
|
||||
Common::Input::UnregisterFactory<Common::Input::InputDevice>("analog_from_button");
|
||||
Common::Input::UnregisterInputFactory("touch_from_button");
|
||||
Common::Input::UnregisterInputFactory("analog_from_button");
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
|
||||
@@ -334,6 +318,12 @@ struct InputSubsystem::Impl {
|
||||
#endif
|
||||
}
|
||||
|
||||
void PumpEvents() const {
|
||||
#ifdef HAVE_SDL2
|
||||
sdl->PumpEvents();
|
||||
#endif
|
||||
}
|
||||
|
||||
void RegisterInput(const MappingData& data) {
|
||||
mapping_factory->RegisterInput(data);
|
||||
}
|
||||
@@ -482,6 +472,10 @@ void InputSubsystem::StopMapping() const {
|
||||
impl->mapping_factory->StopMapping();
|
||||
}
|
||||
|
||||
void InputSubsystem::PumpEvents() const {
|
||||
impl->PumpEvents();
|
||||
}
|
||||
|
||||
std::string GenerateKeyboardParam(int key_code) {
|
||||
Common::ParamPackage param;
|
||||
param.Set("engine", "keyboard");
|
||||
|
||||
@@ -147,6 +147,9 @@ public:
|
||||
/// Stop polling from all backends.
|
||||
void StopMapping() const;
|
||||
|
||||
/// Signals SDL driver for new input events
|
||||
void PumpEvents() const;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
@@ -253,8 +253,8 @@ if (YUZU_USE_BUNDLED_FFMPEG AND NOT WIN32)
|
||||
add_dependencies(video_core ffmpeg-build)
|
||||
endif()
|
||||
|
||||
target_include_directories(video_core PRIVATE ${FFmpeg_INCLUDE_DIR})
|
||||
target_link_libraries(video_core PRIVATE ${FFmpeg_LIBRARIES})
|
||||
target_include_directories(video_core PRIVATE ${FFmpeg_INCLUDE_avcodec} ${FFmpeg_INCLUDE_avutil} ${FFmpeg_INCLUDE_swscale})
|
||||
target_link_libraries(video_core PRIVATE ${FFmpeg_LIBRARY_avcodec} ${FFmpeg_LIBRARY_avutil} ${FFmpeg_LIBRARY_swscale})
|
||||
target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})
|
||||
|
||||
add_dependencies(video_core host_shaders)
|
||||
|
||||
@@ -49,10 +49,9 @@ void State::ProcessData(std::span<const u8> read_buffer) {
|
||||
if (regs.line_count == 1) {
|
||||
rasterizer->AccelerateInlineToMemory(address, copy_size, read_buffer);
|
||||
} else {
|
||||
for (u32 line = 0; line < regs.line_count; ++line) {
|
||||
const GPUVAddr dest_line = address + static_cast<size_t>(line) * regs.dest.pitch;
|
||||
std::span<const u8> buffer(read_buffer.data() +
|
||||
static_cast<size_t>(line) * regs.line_length_in,
|
||||
for (size_t line = 0; line < regs.line_count; ++line) {
|
||||
const GPUVAddr dest_line = address + line * regs.dest.pitch;
|
||||
std::span<const u8> buffer(read_buffer.data() + line * regs.line_length_in,
|
||||
regs.line_length_in);
|
||||
rasterizer->AccelerateInlineToMemory(dest_line, regs.line_length_in, buffer);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ struct Registers {
|
||||
u32 y;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
|
||||
u32 BlockWidth() const {
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
u32 addr_lower;
|
||||
|
||||
[[nodiscard]] constexpr GPUVAddr Address() const noexcept {
|
||||
return (static_cast<GPUVAddr>(addr_upper) << 32) | static_cast<GPUVAddr>(addr_lower);
|
||||
return (GPUVAddr{addr_upper} << 32) | GPUVAddr{addr_lower};
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size");
|
||||
|
||||
@@ -50,11 +50,11 @@ void KeplerCompute::CallMultiMethod(u32 method, const u32* base_start, u32 amoun
|
||||
u32 methods_pending) {
|
||||
switch (method) {
|
||||
case KEPLER_COMPUTE_REG_INDEX(data_upload):
|
||||
upload_state.ProcessData(base_start, static_cast<size_t>(amount));
|
||||
upload_state.ProcessData(base_start, amount);
|
||||
return;
|
||||
default:
|
||||
for (std::size_t i = 0; i < amount; i++) {
|
||||
CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
|
||||
for (u32 i = 0; i < amount; i++) {
|
||||
CallMethod(method, base_start[i], methods_pending - i <= 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
struct {
|
||||
u32 address;
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address) << 8));
|
||||
return GPUVAddr{address} << 8;
|
||||
}
|
||||
} launch_desc_loc;
|
||||
|
||||
@@ -83,8 +83,7 @@ public:
|
||||
u32 address_low;
|
||||
u32 limit;
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
} tsc;
|
||||
|
||||
@@ -95,8 +94,7 @@ public:
|
||||
u32 address_low;
|
||||
u32 limit;
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
} tic;
|
||||
|
||||
@@ -106,8 +104,7 @@ public:
|
||||
u32 address_high;
|
||||
u32 address_low;
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
} code_loc;
|
||||
|
||||
@@ -162,8 +159,7 @@ public:
|
||||
BitField<15, 17, u32> size;
|
||||
};
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high.Value()) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high.Value()} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
std::array<ConstBufferConfig, NumConstBuffers> const_buffer_config;
|
||||
|
||||
@@ -42,11 +42,11 @@ void KeplerMemory::CallMultiMethod(u32 method, const u32* base_start, u32 amount
|
||||
u32 methods_pending) {
|
||||
switch (method) {
|
||||
case KEPLERMEMORY_REG_INDEX(data):
|
||||
upload_state.ProcessData(base_start, static_cast<size_t>(amount));
|
||||
upload_state.ProcessData(base_start, amount);
|
||||
return;
|
||||
default:
|
||||
for (std::size_t i = 0; i < amount; i++) {
|
||||
CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
|
||||
for (u32 i = 0; i < amount; i++) {
|
||||
CallMethod(method, base_start[i], methods_pending - i <= 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -370,11 +370,11 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
|
||||
ProcessCBMultiData(base_start, amount);
|
||||
break;
|
||||
case MAXWELL3D_REG_INDEX(inline_data):
|
||||
upload_state.ProcessData(base_start, static_cast<size_t>(amount));
|
||||
upload_state.ProcessData(base_start, amount);
|
||||
return;
|
||||
default:
|
||||
for (std::size_t i = 0; i < amount; i++) {
|
||||
CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
|
||||
for (u32 i = 0; i < amount; i++) {
|
||||
CallMethod(method, base_start[i], methods_pending - i <= 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -652,12 +652,12 @@ void Maxwell3D::ProcessDeferredDraw() {
|
||||
return;
|
||||
}
|
||||
|
||||
u32 method_count = static_cast<u32>(deferred_draw_method.size());
|
||||
const auto method_count = deferred_draw_method.size();
|
||||
u32 instance_count = 1;
|
||||
u32 vertex_buffer_count = 0;
|
||||
u32 index_buffer_count = 0;
|
||||
for (u32 index = 0; index < method_count; ++index) {
|
||||
u32 method = deferred_draw_method[index];
|
||||
for (size_t index = 0; index < method_count; ++index) {
|
||||
const u32 method = deferred_draw_method[index];
|
||||
if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) {
|
||||
instance_count = ++vertex_buffer_count;
|
||||
} else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) {
|
||||
|
||||
@@ -96,8 +96,7 @@ public:
|
||||
u32 type;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -106,8 +105,7 @@ public:
|
||||
u32 address_low;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,8 +122,7 @@ public:
|
||||
Mode mode;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(offset_high) << 32) |
|
||||
offset_low);
|
||||
return (GPUVAddr{offset_high} << 32) | GPUVAddr{offset_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -187,7 +184,7 @@ public:
|
||||
default:
|
||||
// Thresholds begin at 0x10 (1 << 4)
|
||||
// Threshold is in the range 0x1 to 0x13
|
||||
return 1 << (4 + threshold.Value() - 1);
|
||||
return 1U << (4 + threshold.Value() - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -468,8 +465,7 @@ public:
|
||||
INSERT_PADDING_BYTES_NOINIT(0xC);
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(Buffer) == 0x20);
|
||||
@@ -511,12 +507,11 @@ public:
|
||||
u32 default_size_per_warp;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
|
||||
u64 Size() const {
|
||||
return (static_cast<u64>(size_high) << 32) | size_low;
|
||||
return (u64{size_high} << 32) | u64{size_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -538,13 +533,11 @@ public:
|
||||
u32 storage_limit_address_low;
|
||||
|
||||
GPUVAddr StorageAddress() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(storage_address_high) << 32) |
|
||||
storage_address_low);
|
||||
return (GPUVAddr{storage_address_high} << 32) | GPUVAddr{storage_address_low};
|
||||
}
|
||||
GPUVAddr StorageLimitAddress() const {
|
||||
return static_cast<GPUVAddr>(
|
||||
(static_cast<GPUVAddr>(storage_limit_address_high) << 32) |
|
||||
storage_limit_address_low);
|
||||
return (GPUVAddr{storage_limit_address_high} << 32) |
|
||||
GPUVAddr{storage_limit_address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -829,11 +822,11 @@ public:
|
||||
struct CompressionThresholdSamples {
|
||||
u32 samples;
|
||||
|
||||
u32 Samples() {
|
||||
u32 Samples() const {
|
||||
if (samples == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1 << (samples - 1);
|
||||
return 1U << (samples - 1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1138,8 +1131,7 @@ public:
|
||||
INSERT_PADDING_BYTES_NOINIT(0x18);
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(RenderTargetConfig) == 0x40);
|
||||
@@ -1482,8 +1474,7 @@ public:
|
||||
u32 address_low;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1533,8 +1524,7 @@ public:
|
||||
u32 address_low;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1561,8 +1551,7 @@ public:
|
||||
u32 array_pitch;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1910,8 +1899,7 @@ public:
|
||||
Mode mode;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1921,8 +1909,7 @@ public:
|
||||
u32 limit;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1932,8 +1919,7 @@ public:
|
||||
u32 limit;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1981,8 +1967,7 @@ public:
|
||||
u32 address_low;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2027,8 +2012,7 @@ public:
|
||||
u32 address_low;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2224,19 +2208,16 @@ public:
|
||||
}
|
||||
|
||||
GPUVAddr StartAddress() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_addr_high) << 32) |
|
||||
start_addr_low);
|
||||
return (GPUVAddr{start_addr_high} << 32) | GPUVAddr{start_addr_low};
|
||||
}
|
||||
|
||||
GPUVAddr EndAddress() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_addr_high) << 32) |
|
||||
limit_addr_low);
|
||||
return (GPUVAddr{limit_addr_high} << 32) | GPUVAddr{limit_addr_low};
|
||||
}
|
||||
|
||||
/// Adjust the index buffer offset so it points to the first desired index.
|
||||
GPUVAddr IndexStart() const {
|
||||
return StartAddress() +
|
||||
static_cast<size_t>(first) * static_cast<size_t>(FormatSizeInBytes());
|
||||
return StartAddress() + size_t{first} * size_t{FormatSizeInBytes()};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2464,8 +2445,7 @@ public:
|
||||
} query;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2479,8 +2459,7 @@ public:
|
||||
u32 frequency;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
|
||||
bool IsEnabled() const {
|
||||
@@ -2494,8 +2473,7 @@ public:
|
||||
u32 address_low;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(VertexStreamLimit) == 0x8);
|
||||
@@ -2543,8 +2521,7 @@ public:
|
||||
std::array<u32, NumCBData> buffer;
|
||||
|
||||
GPUVAddr Address() const {
|
||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
|
||||
address_low);
|
||||
return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call)
|
||||
|
||||
void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
|
||||
u32 methods_pending) {
|
||||
for (size_t i = 0; i < amount; ++i) {
|
||||
CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
|
||||
for (u32 i = 0; i < amount; ++i) {
|
||||
CallMethod(method, base_start[i], methods_pending - i <= 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,14 +94,14 @@ void MaxwellDMA::Launch() {
|
||||
reinterpret_cast<u8*>(tmp_buffer.data()),
|
||||
regs.line_length_in * sizeof(u32));
|
||||
} else {
|
||||
auto convert_linear_2_blocklinear_addr = [](u64 address) {
|
||||
const auto convert_linear_2_blocklinear_addr = [](u64 address) {
|
||||
return (address & ~0x1f0ULL) | ((address & 0x40) >> 2) | ((address & 0x10) << 1) |
|
||||
((address & 0x180) >> 1) | ((address & 0x20) << 3);
|
||||
};
|
||||
auto src_kind = memory_manager.GetPageKind(regs.offset_in);
|
||||
auto dst_kind = memory_manager.GetPageKind(regs.offset_out);
|
||||
const bool is_src_pitch = IsPitchKind(static_cast<PTEKind>(src_kind));
|
||||
const bool is_dst_pitch = IsPitchKind(static_cast<PTEKind>(dst_kind));
|
||||
const auto src_kind = memory_manager.GetPageKind(regs.offset_in);
|
||||
const auto dst_kind = memory_manager.GetPageKind(regs.offset_out);
|
||||
const bool is_src_pitch = IsPitchKind(src_kind);
|
||||
const bool is_dst_pitch = IsPitchKind(dst_kind);
|
||||
if (!is_src_pitch && is_dst_pitch) {
|
||||
UNIMPLEMENTED_IF(regs.line_length_in % 16 != 0);
|
||||
UNIMPLEMENTED_IF(regs.offset_in % 16 != 0);
|
||||
|
||||
@@ -31,7 +31,7 @@ void Puller::ProcessBindMethod(const MethodCall& method_call) {
|
||||
LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel,
|
||||
method_call.argument);
|
||||
const auto engine_id = static_cast<EngineID>(method_call.argument);
|
||||
bound_engines[method_call.subchannel] = static_cast<EngineID>(engine_id);
|
||||
bound_engines[method_call.subchannel] = engine_id;
|
||||
switch (engine_id) {
|
||||
case EngineID::FERMI_TWOD_A:
|
||||
dma_pusher.BindSubchannel(channel_state.fermi_2d.get(), method_call.subchannel);
|
||||
@@ -285,12 +285,12 @@ void Puller::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start,
|
||||
if (ExecuteMethodOnEngine(method)) {
|
||||
CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending);
|
||||
} else {
|
||||
for (std::size_t i = 0; i < amount; i++) {
|
||||
for (u32 i = 0; i < amount; i++) {
|
||||
CallPullerMethod(MethodCall{
|
||||
method,
|
||||
base_start[i],
|
||||
subchannel,
|
||||
methods_pending - static_cast<u32>(i),
|
||||
methods_pending - i,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ SyncpointManager::ActionHandle SyncpointManager::RegisterAction(
|
||||
}
|
||||
|
||||
void SyncpointManager::DeregisterAction(std::list<RegisteredAction>& action_storage,
|
||||
ActionHandle& handle) {
|
||||
const ActionHandle& handle) {
|
||||
std::unique_lock lk(guard);
|
||||
|
||||
// We want to ensure the iterator still exists prior to erasing it
|
||||
@@ -49,11 +49,11 @@ void SyncpointManager::DeregisterAction(std::list<RegisteredAction>& action_stor
|
||||
}
|
||||
}
|
||||
|
||||
void SyncpointManager::DeregisterGuestAction(u32 syncpoint_id, ActionHandle& handle) {
|
||||
void SyncpointManager::DeregisterGuestAction(u32 syncpoint_id, const ActionHandle& handle) {
|
||||
DeregisterAction(guest_action_storage[syncpoint_id], handle);
|
||||
}
|
||||
|
||||
void SyncpointManager::DeregisterHostAction(u32 syncpoint_id, ActionHandle& handle) {
|
||||
void SyncpointManager::DeregisterHostAction(u32 syncpoint_id, const ActionHandle& handle) {
|
||||
DeregisterAction(host_action_storage[syncpoint_id], handle);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,21 +36,19 @@ public:
|
||||
|
||||
template <typename Func>
|
||||
ActionHandle RegisterGuestAction(u32 syncpoint_id, u32 expected_value, Func&& action) {
|
||||
std::function<void()> func(action);
|
||||
return RegisterAction(syncpoints_guest[syncpoint_id], guest_action_storage[syncpoint_id],
|
||||
expected_value, std::move(func));
|
||||
expected_value, std::move(action));
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
ActionHandle RegisterHostAction(u32 syncpoint_id, u32 expected_value, Func&& action) {
|
||||
std::function<void()> func(action);
|
||||
return RegisterAction(syncpoints_host[syncpoint_id], host_action_storage[syncpoint_id],
|
||||
expected_value, std::move(func));
|
||||
expected_value, std::move(action));
|
||||
}
|
||||
|
||||
void DeregisterGuestAction(u32 syncpoint_id, ActionHandle& handle);
|
||||
void DeregisterGuestAction(u32 syncpoint_id, const ActionHandle& handle);
|
||||
|
||||
void DeregisterHostAction(u32 syncpoint_id, ActionHandle& handle);
|
||||
void DeregisterHostAction(u32 syncpoint_id, const ActionHandle& handle);
|
||||
|
||||
void IncrementGuest(u32 syncpoint_id);
|
||||
|
||||
@@ -76,7 +74,7 @@ private:
|
||||
std::list<RegisteredAction>& action_storage, u32 expected_value,
|
||||
std::function<void()>&& action);
|
||||
|
||||
void DeregisterAction(std::list<RegisteredAction>& action_storage, ActionHandle& handle);
|
||||
void DeregisterAction(std::list<RegisteredAction>& action_storage, const ActionHandle& handle);
|
||||
|
||||
void Wait(std::atomic<u32>& syncpoint, std::condition_variable& wait_cv, u32 expected_value);
|
||||
|
||||
|
||||
@@ -214,23 +214,16 @@ PixelFormat PixelFormatFromGPUPixelFormat(Service::android::PixelFormat format)
|
||||
}
|
||||
|
||||
SurfaceType GetFormatType(PixelFormat pixel_format) {
|
||||
if (static_cast<std::size_t>(pixel_format) <
|
||||
static_cast<std::size_t>(PixelFormat::MaxColorFormat)) {
|
||||
if (pixel_format < PixelFormat::MaxColorFormat) {
|
||||
return SurfaceType::ColorTexture;
|
||||
}
|
||||
|
||||
if (static_cast<std::size_t>(pixel_format) <
|
||||
static_cast<std::size_t>(PixelFormat::MaxDepthFormat)) {
|
||||
if (pixel_format < PixelFormat::MaxDepthFormat) {
|
||||
return SurfaceType::Depth;
|
||||
}
|
||||
|
||||
if (static_cast<std::size_t>(pixel_format) <
|
||||
static_cast<std::size_t>(PixelFormat::MaxStencilFormat)) {
|
||||
if (pixel_format < PixelFormat::MaxStencilFormat) {
|
||||
return SurfaceType::Stencil;
|
||||
}
|
||||
|
||||
if (static_cast<std::size_t>(pixel_format) <
|
||||
static_cast<std::size_t>(PixelFormat::MaxDepthStencilFormat)) {
|
||||
if (pixel_format < PixelFormat::MaxDepthStencilFormat) {
|
||||
return SurfaceType::DepthStencil;
|
||||
}
|
||||
|
||||
|
||||
@@ -387,7 +387,11 @@ if (YUZU_USE_BUNDLED_QT AND QT_VERSION VERSION_LESS 6)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SDL2)
|
||||
target_link_libraries(yuzu PRIVATE SDL2)
|
||||
if (YUZU_USE_EXTERNAL_SDL2)
|
||||
target_link_libraries(yuzu PRIVATE SDL2-static)
|
||||
else()
|
||||
target_link_libraries(yuzu PRIVATE SDL2)
|
||||
endif()
|
||||
target_compile_definitions(yuzu PRIVATE HAVE_SDL2)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||
|
||||
constexpr int default_mouse_hide_timeout = 2500;
|
||||
constexpr int default_mouse_center_timeout = 10;
|
||||
constexpr int default_input_update_timeout = 1;
|
||||
|
||||
/**
|
||||
* "Callouts" are one-time instructional messages shown to the user. In the config settings, there
|
||||
@@ -405,6 +406,10 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan
|
||||
mouse_center_timer.setInterval(default_mouse_center_timeout);
|
||||
connect(&mouse_center_timer, &QTimer::timeout, this, &GMainWindow::CenterMouseCursor);
|
||||
|
||||
update_input_timer.setInterval(default_input_update_timeout);
|
||||
connect(&update_input_timer, &QTimer::timeout, this, &GMainWindow::UpdateInputDrivers);
|
||||
update_input_timer.start();
|
||||
|
||||
MigrateConfigFiles();
|
||||
|
||||
if (has_broken_vulkan) {
|
||||
@@ -3637,6 +3642,13 @@ void GMainWindow::UpdateUISettings() {
|
||||
UISettings::values.first_start = false;
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateInputDrivers() {
|
||||
if (!input_subsystem) {
|
||||
return;
|
||||
}
|
||||
input_subsystem->PumpEvents();
|
||||
}
|
||||
|
||||
void GMainWindow::HideMouseCursor() {
|
||||
if (emu_thread == nullptr && UISettings::values.hide_mouse) {
|
||||
mouse_hide_timer.stop();
|
||||
@@ -4037,7 +4049,6 @@ void GMainWindow::UpdateUITheme() {
|
||||
const QString default_theme =
|
||||
QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second);
|
||||
QString current_theme = UISettings::values.theme;
|
||||
QStringList theme_paths(default_theme_paths);
|
||||
|
||||
if (current_theme.isEmpty()) {
|
||||
current_theme = default_theme;
|
||||
@@ -4050,7 +4061,7 @@ void GMainWindow::UpdateUITheme() {
|
||||
if (current_theme == QStringLiteral("default") || current_theme == QStringLiteral("colorful")) {
|
||||
QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme
|
||||
: startup_icon_theme);
|
||||
QIcon::setThemeSearchPaths(theme_paths);
|
||||
QIcon::setThemeSearchPaths(QStringList(default_theme_paths));
|
||||
if (CheckDarkMode()) {
|
||||
current_theme = QStringLiteral("default_dark");
|
||||
}
|
||||
|
||||
@@ -353,6 +353,7 @@ private:
|
||||
void UpdateGPUAccuracyButton();
|
||||
void UpdateStatusButtons();
|
||||
void UpdateUISettings();
|
||||
void UpdateInputDrivers();
|
||||
void HideMouseCursor();
|
||||
void ShowMouseCursor();
|
||||
void CenterMouseCursor();
|
||||
@@ -404,6 +405,7 @@ private:
|
||||
bool auto_muted = false;
|
||||
QTimer mouse_hide_timer;
|
||||
QTimer mouse_center_timer;
|
||||
QTimer update_input_timer;
|
||||
|
||||
QString startup_icon_theme;
|
||||
bool os_dark_mode = false;
|
||||
|
||||
@@ -4,16 +4,19 @@
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <cstring> // for memset, strncpy
|
||||
#include <cstring>
|
||||
#include <processthreadsapi.h>
|
||||
#include <windows.h>
|
||||
#elif defined(YUZU_UNIX)
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <fmt/core.h>
|
||||
#include "video_core/vulkan_common/vulkan_instance.h"
|
||||
#include "video_core/vulkan_common/vulkan_library.h"
|
||||
#include "yuzu/startup_checks.h"
|
||||
@@ -27,7 +30,7 @@ void CheckVulkan() {
|
||||
Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_0);
|
||||
|
||||
} catch (const Vulkan::vk::Exception& exception) {
|
||||
std::fprintf(stderr, "Failed to initialize Vulkan: %s\n", exception.what());
|
||||
fmt::print(stderr, "Failed to initialize Vulkan: {}\n", exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +52,15 @@ bool CheckEnvVars(bool* is_child) {
|
||||
*is_child = true;
|
||||
return false;
|
||||
} else if (!SetEnvironmentVariableA(IS_CHILD_ENV_VAR, ENV_VAR_ENABLED_TEXT)) {
|
||||
std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s with error %lu\n",
|
||||
IS_CHILD_ENV_VAR, GetLastError());
|
||||
fmt::print(stderr, "SetEnvironmentVariableA failed to set {} with error {}\n",
|
||||
IS_CHILD_ENV_VAR, GetLastError());
|
||||
return true;
|
||||
}
|
||||
#elif defined(YUZU_UNIX)
|
||||
const char* startup_check_var = getenv(STARTUP_CHECK_ENV_VAR);
|
||||
if (startup_check_var != nullptr &&
|
||||
std::strncmp(startup_check_var, ENV_VAR_ENABLED_TEXT, 8) == 0) {
|
||||
CheckVulkan();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -62,8 +72,8 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka
|
||||
// Set the startup variable for child processes
|
||||
const bool env_var_set = SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT);
|
||||
if (!env_var_set) {
|
||||
std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s with error %lu\n",
|
||||
STARTUP_CHECK_ENV_VAR, GetLastError());
|
||||
fmt::print(stderr, "SetEnvironmentVariableA failed to set {} with error {}\n",
|
||||
STARTUP_CHECK_ENV_VAR, GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -81,48 +91,57 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka
|
||||
DWORD exit_code = STILL_ACTIVE;
|
||||
const int err = GetExitCodeProcess(process_info.hProcess, &exit_code);
|
||||
if (err == 0) {
|
||||
std::fprintf(stderr, "GetExitCodeProcess failed with error %lu\n", GetLastError());
|
||||
fmt::print(stderr, "GetExitCodeProcess failed with error {}\n", GetLastError());
|
||||
}
|
||||
|
||||
// Vulkan is broken if the child crashed (return value is not zero)
|
||||
*has_broken_vulkan = (exit_code != 0);
|
||||
|
||||
if (CloseHandle(process_info.hProcess) == 0) {
|
||||
std::fprintf(stderr, "CloseHandle failed with error %lu\n", GetLastError());
|
||||
fmt::print(stderr, "CloseHandle failed with error {}\n", GetLastError());
|
||||
}
|
||||
if (CloseHandle(process_info.hThread) == 0) {
|
||||
std::fprintf(stderr, "CloseHandle failed with error %lu\n", GetLastError());
|
||||
fmt::print(stderr, "CloseHandle failed with error {}\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, nullptr)) {
|
||||
std::fprintf(stderr, "SetEnvironmentVariableA failed to clear %s with error %lu\n",
|
||||
STARTUP_CHECK_ENV_VAR, GetLastError());
|
||||
fmt::print(stderr, "SetEnvironmentVariableA failed to clear {} with error {}\n",
|
||||
STARTUP_CHECK_ENV_VAR, GetLastError());
|
||||
}
|
||||
|
||||
#elif defined(YUZU_UNIX)
|
||||
const int env_var_set = setenv(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT, 1);
|
||||
if (env_var_set == -1) {
|
||||
const int err = errno;
|
||||
fmt::print(stderr, "setenv failed to set {} with error {}\n", STARTUP_CHECK_ENV_VAR, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (perform_vulkan_check) {
|
||||
const pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
CheckVulkan();
|
||||
return true;
|
||||
} else if (pid == -1) {
|
||||
const int err = errno;
|
||||
std::fprintf(stderr, "fork failed with error %d\n", err);
|
||||
const pid_t pid = SpawnChild(arg0);
|
||||
if (pid == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get exit code from child process
|
||||
int status;
|
||||
const int r_val = wait(&status);
|
||||
const int r_val = waitpid(pid, &status, 0);
|
||||
if (r_val == -1) {
|
||||
const int err = errno;
|
||||
std::fprintf(stderr, "wait failed with error %d\n", err);
|
||||
fmt::print(stderr, "wait failed with error {}\n", err);
|
||||
return false;
|
||||
}
|
||||
// Vulkan is broken if the child crashed (return value is not zero)
|
||||
*has_broken_vulkan = (status != 0);
|
||||
}
|
||||
|
||||
const int env_var_cleared = unsetenv(STARTUP_CHECK_ENV_VAR);
|
||||
if (env_var_cleared == -1) {
|
||||
const int err = errno;
|
||||
fmt::print(stderr, "unsetenv failed to clear {} with error {}\n", STARTUP_CHECK_ENV_VAR,
|
||||
err);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -150,10 +169,29 @@ bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags) {
|
||||
pi // lpProcessInformation
|
||||
);
|
||||
if (!process_created) {
|
||||
std::fprintf(stderr, "CreateProcessA failed with error %lu\n", GetLastError());
|
||||
fmt::print(stderr, "CreateProcessA failed with error {}\n", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#elif defined(YUZU_UNIX)
|
||||
pid_t SpawnChild(const char* arg0) {
|
||||
const pid_t pid = fork();
|
||||
|
||||
if (pid == -1) {
|
||||
// error
|
||||
const int err = errno;
|
||||
fmt::print(stderr, "fork failed with error {}\n", err);
|
||||
return pid;
|
||||
} else if (pid == 0) {
|
||||
// child
|
||||
execl(arg0, arg0, nullptr);
|
||||
const int err = errno;
|
||||
fmt::print(stderr, "execl failed with error {}\n", err);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif defined(YUZU_UNIX)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
constexpr char IS_CHILD_ENV_VAR[] = "YUZU_IS_CHILD";
|
||||
@@ -17,4 +19,6 @@ bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulka
|
||||
|
||||
#ifdef _WIN32
|
||||
bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags);
|
||||
#elif defined(YUZU_UNIX)
|
||||
pid_t SpawnChild(const char* arg0);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user