Compare commits
35 Commits
android-21
...
android-22
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f4de06459 | ||
|
|
20f50df7f8 | ||
|
|
776a6ea3f1 | ||
|
|
ffe3984353 | ||
|
|
ec734cb06c | ||
|
|
8292ba7ad6 | ||
|
|
2e65616761 | ||
|
|
07aa1a99fa | ||
|
|
6524f20de4 | ||
|
|
a0f7f2b309 | ||
|
|
ecea5ef757 | ||
|
|
a1ce45b0b1 | ||
|
|
9ba9780a96 | ||
|
|
73e7a259fd | ||
|
|
2cc5c517cf | ||
|
|
c0775e74ec | ||
|
|
3acf35bb98 | ||
|
|
8ddfecfbae | ||
|
|
51f5a6f1f8 | ||
|
|
64fca24b32 | ||
|
|
ba4cee1812 | ||
|
|
06abf3205a | ||
|
|
adfdc9520a | ||
|
|
90cb852908 | ||
|
|
278dd589ec | ||
|
|
15e8791f9d | ||
|
|
498c9bd96a | ||
|
|
6c8df6af44 | ||
|
|
8e93537266 | ||
|
|
b8f16f3538 | ||
|
|
6cc82fd430 | ||
|
|
2bc0132d0c | ||
|
|
da410506a4 | ||
|
|
23e074ff14 | ||
|
|
f854ffd015 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -64,3 +64,6 @@
|
||||
[submodule "oaknut"]
|
||||
path = externals/oaknut
|
||||
url = https://github.com/merryhime/oaknut
|
||||
[submodule "Vulkan-Utility-Libraries"]
|
||||
path = externals/Vulkan-Utility-Libraries
|
||||
url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
|
||||
|
||||
@@ -36,6 +36,8 @@ option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}")
|
||||
|
||||
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON)
|
||||
|
||||
option(YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES "Use Vulkan-Utility-Libraries from externals" ON)
|
||||
|
||||
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
|
||||
|
||||
option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
|
||||
@@ -308,6 +310,10 @@ if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS)
|
||||
find_package(Vulkan 1.3.274 REQUIRED)
|
||||
endif()
|
||||
|
||||
if (NOT YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES)
|
||||
find_package(VulkanUtilityLibraries REQUIRED)
|
||||
endif()
|
||||
|
||||
if (ENABLE_LIBUSB)
|
||||
find_package(libusb 1.0.24 MODULE)
|
||||
endif()
|
||||
@@ -316,6 +322,10 @@ if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
|
||||
find_package(xbyak 6 CONFIG)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE_arm64)
|
||||
find_package(oaknut 2.0.1 CONFIG)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
|
||||
find_package(dynarmic 6.4.0 CONFIG)
|
||||
endif()
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
| Pull Request | Commit | Title | Author | Merged? |
|
||||
|----|----|----|----|----|
|
||||
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`e3171486d`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||
| [12760](https://github.com/yuzu-emu/yuzu-android//pull/12760) | [`c6b88b62d`](https://github.com/yuzu-emu/yuzu-android//pull/12760/files) | am: rewrite for multiprocess support | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||
| [12814](https://github.com/yuzu-emu/yuzu-android//pull/12814) | [`da410506a`](https://github.com/yuzu-emu/yuzu-android//pull/12814/files) | Move time services to new IPC and add debug printing | [Kelebek1](https://github.com/Kelebek1/) | Yes |
|
||||
| [12830](https://github.com/yuzu-emu/yuzu-android//pull/12830) | [`6cc82fd43`](https://github.com/yuzu-emu/yuzu-android//pull/12830/files) | externals/dynarmic: Update to 6.6.1 | [merryhime](https://github.com/merryhime/) | Yes |
|
||||
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`e644610e1`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||
| [12760](https://github.com/yuzu-emu/yuzu-android//pull/12760) | [`8e0a40434`](https://github.com/yuzu-emu/yuzu-android//pull/12760/files) | am: rewrite for multiprocess support | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||
|
||||
|
||||
End of merge log. You can find the original README.md below the break.
|
||||
|
||||
10
externals/CMakeLists.txt
vendored
10
externals/CMakeLists.txt
vendored
@@ -14,16 +14,17 @@ set(BUILD_SHARED_LIBS OFF)
|
||||
# Skip install rules for all externals
|
||||
set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
|
||||
# xbyak
|
||||
# Xbyak (also used by Dynarmic, so needs to be added first)
|
||||
if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
|
||||
add_subdirectory(xbyak)
|
||||
endif()
|
||||
|
||||
# Dynarmic
|
||||
# Oaknut (also used by Dynarmic, so needs to be added first)
|
||||
if (ARCHITECTURE_arm64 AND NOT TARGET merry::oaknut)
|
||||
add_subdirectory(oaknut)
|
||||
endif()
|
||||
|
||||
# Dynarmic
|
||||
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic)
|
||||
set(DYNARMIC_IGNORE_ASSERTS ON)
|
||||
add_subdirectory(dynarmic)
|
||||
@@ -154,6 +155,11 @@ if (YUZU_USE_EXTERNAL_VULKAN_HEADERS)
|
||||
add_subdirectory(Vulkan-Headers)
|
||||
endif()
|
||||
|
||||
# Vulkan-Utility-Libraries
|
||||
if (YUZU_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES)
|
||||
add_subdirectory(Vulkan-Utility-Libraries)
|
||||
endif()
|
||||
|
||||
# TZDB (Time Zone Database)
|
||||
add_subdirectory(nx_tzdb)
|
||||
|
||||
|
||||
1
externals/Vulkan-Utility-Libraries
vendored
Submodule
1
externals/Vulkan-Utility-Libraries
vendored
Submodule
Submodule externals/Vulkan-Utility-Libraries added at 524f8910d0
@@ -261,7 +261,7 @@ object NativeLibrary {
|
||||
/**
|
||||
* Begins emulation.
|
||||
*/
|
||||
external fun run(path: String?, programIndex: Int = 0)
|
||||
external fun run(path: String?, programIndex: Int, frontendInitiated: Boolean)
|
||||
|
||||
// Surface Handling
|
||||
external fun surfaceChanged(surf: Surface?)
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.CardDriverOptionBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||
import org.yuzu.yuzu_emu.model.Driver
|
||||
@@ -57,13 +58,9 @@ class DriverAdapter(private val driverViewModel: DriverViewModel) :
|
||||
title.text = model.title
|
||||
version.text = model.version
|
||||
description.text = model.description
|
||||
if (model.description.isNotEmpty()) {
|
||||
version.visibility = View.VISIBLE
|
||||
description.visibility = View.VISIBLE
|
||||
if (model.title != binding.root.context.getString(R.string.system_gpu_driver)) {
|
||||
buttonDelete.visibility = View.VISIBLE
|
||||
} else {
|
||||
version.visibility = View.GONE
|
||||
description.visibility = View.GONE
|
||||
buttonDelete.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -927,7 +927,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
emulationThread.join()
|
||||
emulationThread = Thread({
|
||||
Log.debug("[EmulationFragment] Starting emulation thread.")
|
||||
NativeLibrary.run(gamePath, programIndex)
|
||||
NativeLibrary.run(gamePath, programIndex, false)
|
||||
}, "NativeEmulation")
|
||||
emulationThread.start()
|
||||
}
|
||||
@@ -981,7 +981,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
State.STOPPED -> {
|
||||
emulationThread = Thread({
|
||||
Log.debug("[EmulationFragment] Starting emulation thread.")
|
||||
NativeLibrary.run(gamePath, programIndex)
|
||||
NativeLibrary.run(gamePath, programIndex, true)
|
||||
}, "NativeEmulation")
|
||||
emulationThread.start()
|
||||
}
|
||||
|
||||
@@ -219,7 +219,8 @@ void EmulationSession::SetAppletId(int applet_id) {
|
||||
}
|
||||
|
||||
Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath,
|
||||
const std::size_t program_index) {
|
||||
const std::size_t program_index,
|
||||
const bool frontend_initiated) {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
// Create the render window.
|
||||
@@ -251,6 +252,8 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
|
||||
// Load the ROM.
|
||||
Service::AM::FrontendAppletParameters params{
|
||||
.applet_id = static_cast<Service::AM::AppletId>(m_applet_id),
|
||||
.launch_type = frontend_initiated ? Service::AM::LaunchType::FrontendInitiated
|
||||
: Service::AM::LaunchType::ApplicationInitiated,
|
||||
.program_index = static_cast<s32>(program_index),
|
||||
};
|
||||
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params);
|
||||
@@ -447,7 +450,8 @@ u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
|
||||
}
|
||||
|
||||
static Core::SystemResultStatus RunEmulation(const std::string& filepath,
|
||||
const size_t program_index = 0) {
|
||||
const size_t program_index,
|
||||
const bool frontend_initiated) {
|
||||
MicroProfileOnThreadCreate("EmuThread");
|
||||
SCOPE_EXIT({ MicroProfileShutdown(); });
|
||||
|
||||
@@ -460,7 +464,8 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath,
|
||||
|
||||
SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); });
|
||||
|
||||
jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index);
|
||||
jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index,
|
||||
frontend_initiated);
|
||||
if (result != Core::SystemResultStatus::Success) {
|
||||
return result;
|
||||
}
|
||||
@@ -757,10 +762,12 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_logSettings(JNIEnv* env, jobject jobj
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path,
|
||||
jint j_program_index) {
|
||||
jint j_program_index,
|
||||
jboolean j_frontend_initiated) {
|
||||
const std::string path = GetJString(env, j_path);
|
||||
|
||||
const Core::SystemResultStatus result{RunEmulation(path, j_program_index)};
|
||||
const Core::SystemResultStatus result{
|
||||
RunEmulation(path, j_program_index, j_frontend_initiated)};
|
||||
if (result != Core::SystemResultStatus::Success) {
|
||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
|
||||
IDCache::GetExitEmulationActivity(), static_cast<int>(result));
|
||||
|
||||
@@ -47,7 +47,8 @@ public:
|
||||
void InitializeSystem(bool reload);
|
||||
void SetAppletId(int applet_id);
|
||||
Core::SystemResultStatus InitializeEmulation(const std::string& filepath,
|
||||
const std::size_t program_index = 0);
|
||||
const std::size_t program_index,
|
||||
const bool frontend_initiated);
|
||||
|
||||
bool IsHandheldOnly();
|
||||
void SetDeviceType([[maybe_unused]] int index, int type);
|
||||
|
||||
@@ -303,8 +303,8 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters(
|
||||
}
|
||||
|
||||
// Applet was started by frontend, so it is foreground.
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
applet->focus_state = FocusState::InFocus;
|
||||
|
||||
this->InsertApplet(std::move(applet));
|
||||
|
||||
@@ -85,24 +85,26 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
||||
applet->library_applet_mode = mode;
|
||||
|
||||
// Set focus state
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
switch (mode) {
|
||||
case LibraryAppletMode::AllForeground:
|
||||
case LibraryAppletMode::NoUI:
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
|
||||
applet->focus_state = FocusState::InFocus;
|
||||
applet->hid_registration.EnableAppletToGetInput(true);
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
break;
|
||||
case LibraryAppletMode::AllForegroundInitiallyHidden:
|
||||
applet->system_buffer_manager.SetWindowVisibility(false);
|
||||
applet->focus_state = FocusState::NotInFocus;
|
||||
applet->hid_registration.EnableAppletToGetInput(false);
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
break;
|
||||
case LibraryAppletMode::Background:
|
||||
case LibraryAppletMode::BackgroundIndirectDisplay:
|
||||
default:
|
||||
applet->focus_state = FocusState::Background;
|
||||
applet->hid_registration.EnableAppletToGetInput(true);
|
||||
applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,14 +122,14 @@ struct RequestLayout {
|
||||
u32 domain_interface_count;
|
||||
};
|
||||
|
||||
template <ArgumentType Type1, ArgumentType Type2, typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0>
|
||||
constexpr u32 GetArgumentRawDataSize() {
|
||||
template <typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0>
|
||||
constexpr u32 GetInRawDataSize() {
|
||||
if constexpr (ArgIndex >= std::tuple_size_v<MethodArguments>) {
|
||||
return static_cast<u32>(DataOffset);
|
||||
} else {
|
||||
using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>;
|
||||
|
||||
if constexpr (ArgumentTraits<ArgType>::Type == Type1 || ArgumentTraits<ArgType>::Type == Type2) {
|
||||
if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InData || ArgumentTraits<ArgType>::Type == ArgumentType::InProcessId) {
|
||||
constexpr size_t ArgAlign = alignof(ArgType);
|
||||
constexpr size_t ArgSize = sizeof(ArgType);
|
||||
|
||||
@@ -138,9 +138,33 @@ constexpr u32 GetArgumentRawDataSize() {
|
||||
constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
|
||||
constexpr size_t ArgEnd = ArgOffset + ArgSize;
|
||||
|
||||
return GetArgumentRawDataSize<Type1, Type2, MethodArguments, ArgAlign, ArgEnd, ArgIndex + 1>();
|
||||
return GetInRawDataSize<MethodArguments, ArgAlign, ArgEnd, ArgIndex + 1>();
|
||||
} else {
|
||||
return GetArgumentRawDataSize<Type1, Type2, MethodArguments, PrevAlign, DataOffset, ArgIndex + 1>();
|
||||
return GetInRawDataSize<MethodArguments, PrevAlign, DataOffset, ArgIndex + 1>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MethodArguments, size_t PrevAlign = 1, size_t DataOffset = 0, size_t ArgIndex = 0>
|
||||
constexpr u32 GetOutRawDataSize() {
|
||||
if constexpr (ArgIndex >= std::tuple_size_v<MethodArguments>) {
|
||||
return static_cast<u32>(DataOffset);
|
||||
} else {
|
||||
using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>;
|
||||
|
||||
if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutData) {
|
||||
using RawArgType = typename ArgType::Type;
|
||||
constexpr size_t ArgAlign = alignof(RawArgType);
|
||||
constexpr size_t ArgSize = sizeof(RawArgType);
|
||||
|
||||
static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment");
|
||||
|
||||
constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
|
||||
constexpr size_t ArgEnd = ArgOffset + ArgSize;
|
||||
|
||||
return GetOutRawDataSize<MethodArguments, ArgAlign, ArgEnd, ArgIndex + 1>();
|
||||
} else {
|
||||
return GetOutRawDataSize<MethodArguments, PrevAlign, DataOffset, ArgIndex + 1>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +189,7 @@ constexpr RequestLayout GetNonDomainReplyInLayout() {
|
||||
return RequestLayout{
|
||||
.copy_handle_count = GetArgumentTypeCount<ArgumentType::InCopyHandle, MethodArguments>(),
|
||||
.move_handle_count = 0,
|
||||
.cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::InData, ArgumentType::InProcessId, MethodArguments>(),
|
||||
.cmif_raw_data_size = GetInRawDataSize<MethodArguments>(),
|
||||
.domain_interface_count = 0,
|
||||
};
|
||||
}
|
||||
@@ -175,7 +199,7 @@ constexpr RequestLayout GetDomainReplyInLayout() {
|
||||
return RequestLayout{
|
||||
.copy_handle_count = GetArgumentTypeCount<ArgumentType::InCopyHandle, MethodArguments>(),
|
||||
.move_handle_count = 0,
|
||||
.cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::InData, ArgumentType::InProcessId, MethodArguments>(),
|
||||
.cmif_raw_data_size = GetInRawDataSize<MethodArguments>(),
|
||||
.domain_interface_count = GetArgumentTypeCount<ArgumentType::InInterface, MethodArguments>(),
|
||||
};
|
||||
}
|
||||
@@ -185,7 +209,7 @@ constexpr RequestLayout GetNonDomainReplyOutLayout() {
|
||||
return RequestLayout{
|
||||
.copy_handle_count = GetArgumentTypeCount<ArgumentType::OutCopyHandle, MethodArguments>(),
|
||||
.move_handle_count = GetArgumentTypeCount<ArgumentType::OutMoveHandle, MethodArguments>() + GetArgumentTypeCount<ArgumentType::OutInterface, MethodArguments>(),
|
||||
.cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::OutData, ArgumentType::OutData, MethodArguments>(),
|
||||
.cmif_raw_data_size = GetOutRawDataSize<MethodArguments>(),
|
||||
.domain_interface_count = 0,
|
||||
};
|
||||
}
|
||||
@@ -195,7 +219,7 @@ constexpr RequestLayout GetDomainReplyOutLayout() {
|
||||
return RequestLayout{
|
||||
.copy_handle_count = GetArgumentTypeCount<ArgumentType::OutCopyHandle, MethodArguments>(),
|
||||
.move_handle_count = GetArgumentTypeCount<ArgumentType::OutMoveHandle, MethodArguments>(),
|
||||
.cmif_raw_data_size = GetArgumentRawDataSize<ArgumentType::OutData, ArgumentType::OutData, MethodArguments>(),
|
||||
.cmif_raw_data_size = GetOutRawDataSize<MethodArguments>(),
|
||||
.domain_interface_count = GetArgumentTypeCount<ArgumentType::OutInterface, MethodArguments>(),
|
||||
};
|
||||
}
|
||||
@@ -259,7 +283,7 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE
|
||||
|
||||
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
|
||||
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InLargeData) {
|
||||
constexpr size_t BufferSize = sizeof(ArgType);
|
||||
constexpr size_t BufferSize = sizeof(typename ArgType::Type);
|
||||
|
||||
// Clear the existing data.
|
||||
std::memset(&std::get<ArgIndex>(args), 0, BufferSize);
|
||||
@@ -300,7 +324,7 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE
|
||||
|
||||
return ReadInArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex, InBufferIndex + 1, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
|
||||
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
|
||||
constexpr size_t BufferSize = sizeof(ArgType);
|
||||
constexpr size_t BufferSize = sizeof(typename ArgType::Type);
|
||||
|
||||
// Clear the existing data.
|
||||
std::memset(&std::get<ArgIndex>(args).raw, 0, BufferSize);
|
||||
@@ -337,13 +361,15 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
|
||||
using ArgType = std::tuple_element_t<ArgIndex, MethodArguments>;
|
||||
|
||||
if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutData) {
|
||||
constexpr size_t ArgAlign = alignof(ArgType);
|
||||
constexpr size_t ArgSize = sizeof(ArgType);
|
||||
using RawArgType = decltype(std::get<ArgIndex>(args).raw);
|
||||
constexpr size_t ArgAlign = alignof(RawArgType);
|
||||
constexpr size_t ArgSize = sizeof(RawArgType);
|
||||
|
||||
static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment");
|
||||
static_assert(!RawDataFinished, "All output interface arguments must appear after raw data");
|
||||
static_assert(!std::is_pointer_v<ArgType>, "Output raw data must not be a pointer");
|
||||
static_assert(std::is_trivially_copyable_v<decltype(std::get<ArgIndex>(args).raw)>, "Output raw data must be trivially copyable");
|
||||
static_assert(!std::is_pointer_v<RawArgType>, "Output raw data must not be a pointer");
|
||||
static_assert(std::is_trivially_copyable_v<RawArgType>, "Output raw data must be trivially copyable");
|
||||
|
||||
constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign);
|
||||
constexpr size_t ArgEnd = ArgOffset + ArgSize;
|
||||
@@ -368,7 +394,7 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ
|
||||
|
||||
return WriteOutArgument<MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(is_domain, args, raw_data, ctx, temp);
|
||||
} else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
|
||||
constexpr size_t BufferSize = sizeof(ArgType);
|
||||
constexpr size_t BufferSize = sizeof(typename ArgType::Type);
|
||||
|
||||
ASSERT(ctx.CanWriteBuffer(OutBufferIndex));
|
||||
if constexpr (ArgType::Attr & BufferAttr_HipcAutoSelect) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/cmif_serialization.h"
|
||||
#include "core/hle/service/hid/hid_server.h"
|
||||
#include "core/hle/service/ipc_helpers.h"
|
||||
#include "core/memory.h"
|
||||
@@ -153,7 +154,7 @@ IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> r
|
||||
{104, &IHidServer::DeactivateNpad, "DeactivateNpad"},
|
||||
{106, &IHidServer::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
|
||||
{107, &IHidServer::DisconnectNpad, "DisconnectNpad"},
|
||||
{108, &IHidServer::GetPlayerLedPattern, "GetPlayerLedPattern"},
|
||||
{108, C<&IHidServer::GetPlayerLedPattern>, "GetPlayerLedPattern"},
|
||||
{109, &IHidServer::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
|
||||
{120, &IHidServer::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
|
||||
{121, &IHidServer::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
|
||||
@@ -1136,19 +1137,39 @@ void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
|
||||
|
||||
Core::HID::LedPattern pattern{0, 0, 0, 0};
|
||||
auto controller = GetResourceManager()->GetNpad();
|
||||
const auto result = controller->GetLedPattern(npad_id, pattern);
|
||||
|
||||
Result IHidServer::GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
|
||||
Core::HID::NpadIdType npad_id) {
|
||||
LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(result);
|
||||
rb.Push(pattern.raw);
|
||||
switch (npad_id) {
|
||||
case Core::HID::NpadIdType::Player1:
|
||||
*out_led_pattern = Core::HID::LedPattern{1, 0, 0, 0};
|
||||
R_SUCCEED();
|
||||
case Core::HID::NpadIdType::Player2:
|
||||
*out_led_pattern = Core::HID::LedPattern{1, 1, 0, 0};
|
||||
R_SUCCEED();
|
||||
case Core::HID::NpadIdType::Player3:
|
||||
*out_led_pattern = Core::HID::LedPattern{1, 1, 1, 0};
|
||||
R_SUCCEED();
|
||||
case Core::HID::NpadIdType::Player4:
|
||||
*out_led_pattern = Core::HID::LedPattern{1, 1, 1, 1};
|
||||
R_SUCCEED();
|
||||
case Core::HID::NpadIdType::Player5:
|
||||
*out_led_pattern = Core::HID::LedPattern{1, 0, 0, 1};
|
||||
R_SUCCEED();
|
||||
case Core::HID::NpadIdType::Player6:
|
||||
*out_led_pattern = Core::HID::LedPattern{1, 0, 1, 0};
|
||||
R_SUCCEED();
|
||||
case Core::HID::NpadIdType::Player7:
|
||||
*out_led_pattern = Core::HID::LedPattern{1, 0, 1, 1};
|
||||
R_SUCCEED();
|
||||
case Core::HID::NpadIdType::Player8:
|
||||
*out_led_pattern = Core::HID::LedPattern{0, 1, 1, 0};
|
||||
R_SUCCEED();
|
||||
default:
|
||||
*out_led_pattern = Core::HID::LedPattern{0, 0, 0, 0};
|
||||
R_SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/cmif_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
@@ -66,7 +68,8 @@ private:
|
||||
void DeactivateNpad(HLERequestContext& ctx);
|
||||
void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
|
||||
void DisconnectNpad(HLERequestContext& ctx);
|
||||
void GetPlayerLedPattern(HLERequestContext& ctx);
|
||||
Result GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
|
||||
Core::HID::NpadIdType npad_id);
|
||||
void ActivateNpadWithRevision(HLERequestContext& ctx);
|
||||
void SetNpadJoyHoldType(HLERequestContext& ctx);
|
||||
void GetNpadJoyHoldType(HLERequestContext& ctx);
|
||||
|
||||
@@ -111,7 +111,8 @@ private:
|
||||
R_RETURN(result);
|
||||
}
|
||||
|
||||
Result UpdateLatest(Out<CharInfo> out_char_info, CharInfo& char_info, SourceFlag source_flag) {
|
||||
Result UpdateLatest(Out<CharInfo> out_char_info, const CharInfo& char_info,
|
||||
SourceFlag source_flag) {
|
||||
LOG_INFO(Service_Mii, "called with source_flag={}", source_flag);
|
||||
|
||||
R_RETURN(manager->UpdateLatest(metadata, *out_char_info, char_info, source_flag));
|
||||
@@ -159,7 +160,7 @@ private:
|
||||
R_RETURN(result);
|
||||
}
|
||||
|
||||
Result UpdateLatest1(Out<StoreData> out_store_data, StoreData& store_data,
|
||||
Result UpdateLatest1(Out<StoreData> out_store_data, const StoreData& store_data,
|
||||
SourceFlag source_flag) {
|
||||
LOG_INFO(Service_Mii, "called with source_flag={}", source_flag);
|
||||
R_UNLESS(is_system, ResultPermissionDenied);
|
||||
@@ -243,7 +244,7 @@ private:
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result GetIndex(Out<s32> out_index, CharInfo& char_info) {
|
||||
Result GetIndex(Out<s32> out_index, const CharInfo& char_info) {
|
||||
LOG_DEBUG(Service_Mii, "called");
|
||||
|
||||
R_RETURN(manager->GetIndex(metadata, char_info, *out_index));
|
||||
@@ -257,25 +258,25 @@ private:
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result Convert(Out<CharInfo> out_char_info, Ver3StoreData& mii_v3) {
|
||||
Result Convert(Out<CharInfo> out_char_info, const Ver3StoreData& mii_v3) {
|
||||
LOG_INFO(Service_Mii, "called");
|
||||
|
||||
R_RETURN(manager->ConvertV3ToCharInfo(*out_char_info, mii_v3));
|
||||
}
|
||||
|
||||
Result ConvertCoreDataToCharInfo(Out<CharInfo> out_char_info, CoreData& core_data) {
|
||||
Result ConvertCoreDataToCharInfo(Out<CharInfo> out_char_info, const CoreData& core_data) {
|
||||
LOG_INFO(Service_Mii, "called");
|
||||
|
||||
R_RETURN(manager->ConvertCoreDataToCharInfo(*out_char_info, core_data));
|
||||
}
|
||||
|
||||
Result ConvertCharInfoToCoreData(Out<CoreData> out_core_data, CharInfo& char_info) {
|
||||
Result ConvertCharInfoToCoreData(Out<CoreData> out_core_data, const CharInfo& char_info) {
|
||||
LOG_INFO(Service_Mii, "called");
|
||||
|
||||
R_RETURN(manager->ConvertCharInfoToCoreData(*out_core_data, char_info));
|
||||
}
|
||||
|
||||
Result Append(CharInfo& char_info) {
|
||||
Result Append(const CharInfo& char_info) {
|
||||
LOG_INFO(Service_Mii, "called");
|
||||
|
||||
R_RETURN(manager->Append(metadata, char_info));
|
||||
|
||||
@@ -83,7 +83,9 @@ SessionId Container::OpenSession(Kernel::KProcess* process) {
|
||||
|
||||
// Check if this memory block is heap.
|
||||
if (svc_mem_info.state == Kernel::Svc::MemoryState::Normal) {
|
||||
if (svc_mem_info.size > region_size) {
|
||||
if (region_start + region_size == svc_mem_info.base_address) {
|
||||
region_size += svc_mem_info.size;
|
||||
} else if (svc_mem_info.size > region_size) {
|
||||
region_size = svc_mem_info.size;
|
||||
region_start = svc_mem_info.base_address;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ SystemSettings DefaultSystemSettings() {
|
||||
.console_sleep_plan = ConsoleSleepPlan::Sleep1Hour,
|
||||
};
|
||||
|
||||
settings.device_time_zone_location_name = {"UTC"};
|
||||
settings.device_time_zone_location_name = Service::PSC::Time::LocationName{"UTC"};
|
||||
settings.user_system_clock_automatic_correction_enabled = true;
|
||||
|
||||
settings.primary_album_storage = PrimaryAlbumStorage::SdCard;
|
||||
|
||||
@@ -24,6 +24,7 @@ enum class Errno : u32 {
|
||||
CONNRESET = 104,
|
||||
NOTCONN = 107,
|
||||
TIMEDOUT = 110,
|
||||
CONNREFUSED = 111,
|
||||
INPROGRESS = 115,
|
||||
};
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ Errno Translate(Network::Errno value) {
|
||||
return Errno::MFILE;
|
||||
case Network::Errno::PIPE:
|
||||
return Errno::PIPE;
|
||||
case Network::Errno::CONNREFUSED:
|
||||
return Errno::CONNREFUSED;
|
||||
case Network::Errno::NOTCONN:
|
||||
return Errno::NOTCONN;
|
||||
case Network::Errno::TIMEDOUT:
|
||||
|
||||
@@ -96,6 +96,7 @@ add_library(hid_core STATIC
|
||||
resources/system_buttons/home_button.h
|
||||
resources/system_buttons/sleep_button.cpp
|
||||
resources/system_buttons/sleep_button.h
|
||||
resources/system_buttons/system_button_types.h
|
||||
resources/touch_screen/gesture.cpp
|
||||
resources/touch_screen/gesture.h
|
||||
resources/touch_screen/gesture_types.h
|
||||
|
||||
@@ -422,7 +422,10 @@ struct NpadPowerInfo {
|
||||
static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
|
||||
|
||||
struct LedPattern {
|
||||
explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
|
||||
LedPattern() {
|
||||
raw = 0;
|
||||
}
|
||||
LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
|
||||
position1.Assign(light1);
|
||||
position2.Assign(light2);
|
||||
position3.Assign(light3);
|
||||
@@ -437,6 +440,16 @@ struct LedPattern {
|
||||
};
|
||||
};
|
||||
|
||||
struct SleepButtonState {
|
||||
union {
|
||||
u64 raw{};
|
||||
|
||||
// Buttons
|
||||
BitField<0, 1, u64> sleep;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(SleepButtonState) == 0x8, "SleepButtonState has incorrect size.");
|
||||
|
||||
struct HomeButtonState {
|
||||
union {
|
||||
u64 raw{};
|
||||
|
||||
@@ -956,17 +956,6 @@ Result NPad::SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
|
||||
if (!IsNpadIdValid(npad_id)) {
|
||||
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
|
||||
return ResultInvalidNpadId;
|
||||
}
|
||||
const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
|
||||
const auto& controller = GetControllerFromNpadIdType(aruid, npad_id).device;
|
||||
pattern = controller->GetLedPattern();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
|
||||
Core::HID::NpadIdType npad_id) const {
|
||||
std::scoped_lock lock{mutex};
|
||||
|
||||
@@ -97,8 +97,6 @@ public:
|
||||
Result ResetIsSixAxisSensorDeviceNewlyAssigned(
|
||||
u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle);
|
||||
|
||||
Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
|
||||
|
||||
Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
|
||||
Core::HID::NpadIdType npad_id) const;
|
||||
Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "hid_core/resources/mouse/mouse_types.h"
|
||||
#include "hid_core/resources/npad/npad_types.h"
|
||||
#include "hid_core/resources/ring_lifo.h"
|
||||
#include "hid_core/resources/system_buttons/system_button_types.h"
|
||||
#include "hid_core/resources/touch_screen/touch_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
@@ -75,24 +76,24 @@ static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000,
|
||||
|
||||
// This is nn::hid::detail::HomeButtonSharedMemoryFormat
|
||||
struct HomeButtonSharedMemoryFormat {
|
||||
CommonHeader header;
|
||||
INSERT_PADDING_BYTES(0x1E0);
|
||||
Lifo<HomeButtonState, HidEntryCount> home_lifo{};
|
||||
INSERT_PADDING_BYTES(0x48);
|
||||
};
|
||||
static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200,
|
||||
"HomeButtonSharedMemoryFormat is an invalid size");
|
||||
|
||||
// This is nn::hid::detail::SleepButtonSharedMemoryFormat
|
||||
struct SleepButtonSharedMemoryFormat {
|
||||
CommonHeader header;
|
||||
INSERT_PADDING_BYTES(0x1E0);
|
||||
Lifo<SleepButtonState, HidEntryCount> sleep_lifo{};
|
||||
INSERT_PADDING_BYTES(0x48);
|
||||
};
|
||||
static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200,
|
||||
"SleepButtonSharedMemoryFormat is an invalid size");
|
||||
|
||||
// This is nn::hid::detail::CaptureButtonSharedMemoryFormat
|
||||
struct CaptureButtonSharedMemoryFormat {
|
||||
CommonHeader header;
|
||||
INSERT_PADDING_BYTES(0x1E0);
|
||||
Lifo<CaptureButtonState, HidEntryCount> capture_lifo{};
|
||||
INSERT_PADDING_BYTES(0x48);
|
||||
};
|
||||
static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200,
|
||||
"CaptureButtonSharedMemoryFormat is an invalid size");
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "hid_core/resources/system_buttons/capture_button.h"
|
||||
@@ -17,10 +19,6 @@ void CaptureButton::OnInit() {}
|
||||
void CaptureButton::OnRelease() {}
|
||||
|
||||
void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
if (!smart_update) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
@@ -29,11 +27,21 @@ void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& header = data->shared_memory_format->capture_button.header;
|
||||
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||
header.total_entry_count = 17;
|
||||
header.entry_count = 0;
|
||||
header.last_entry_index = 0;
|
||||
auto& shared_memory = data->shared_memory_format->capture_button;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.capture_lifo.buffer_count = 0;
|
||||
shared_memory.capture_lifo.buffer_tail = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& last_entry = shared_memory.capture_lifo.ReadCurrentEntry().state;
|
||||
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||
|
||||
auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||
next_state.buttons.raw = controller->GetHomeButtons().raw;
|
||||
|
||||
shared_memory.capture_lifo.WriteNextEntry(next_state);
|
||||
}
|
||||
|
||||
} // namespace Service::HID
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "hid_core/resources/system_buttons/system_button_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -22,6 +23,6 @@ public:
|
||||
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||
|
||||
private:
|
||||
bool smart_update{};
|
||||
CaptureButtonState next_state{};
|
||||
};
|
||||
} // namespace Service::HID
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/core_timing.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/resources/applet_resource.h"
|
||||
#include "hid_core/resources/shared_memory_format.h"
|
||||
#include "hid_core/resources/system_buttons/home_button.h"
|
||||
@@ -17,10 +19,6 @@ void HomeButton::OnInit() {}
|
||||
void HomeButton::OnRelease() {}
|
||||
|
||||
void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
if (!smart_update) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
@@ -29,11 +27,21 @@ void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& header = data->shared_memory_format->home_button.header;
|
||||
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||
header.total_entry_count = 17;
|
||||
header.entry_count = 0;
|
||||
header.last_entry_index = 0;
|
||||
auto& shared_memory = data->shared_memory_format->home_button;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.home_lifo.buffer_count = 0;
|
||||
shared_memory.home_lifo.buffer_tail = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& last_entry = shared_memory.home_lifo.ReadCurrentEntry().state;
|
||||
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||
|
||||
auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||
next_state.buttons.raw = controller->GetHomeButtons().raw;
|
||||
|
||||
shared_memory.home_lifo.WriteNextEntry(next_state);
|
||||
}
|
||||
|
||||
} // namespace Service::HID
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "hid_core/resources/system_buttons/system_button_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -22,6 +23,6 @@ public:
|
||||
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||
|
||||
private:
|
||||
bool smart_update{};
|
||||
HomeButtonState next_state{};
|
||||
};
|
||||
} // namespace Service::HID
|
||||
|
||||
@@ -17,10 +17,6 @@ void SleepButton::OnInit() {}
|
||||
void SleepButton::OnRelease() {}
|
||||
|
||||
void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
if (!smart_update) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock shared_lock{*shared_mutex};
|
||||
const u64 aruid = applet_resource->GetActiveAruid();
|
||||
auto* data = applet_resource->GetAruidData(aruid);
|
||||
@@ -29,11 +25,20 @@ void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& header = data->shared_memory_format->capture_button.header;
|
||||
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||
header.total_entry_count = 17;
|
||||
header.entry_count = 0;
|
||||
header.last_entry_index = 0;
|
||||
auto& shared_memory = data->shared_memory_format->sleep_button;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.sleep_lifo.buffer_count = 0;
|
||||
shared_memory.sleep_lifo.buffer_tail = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& last_entry = shared_memory.sleep_lifo.ReadCurrentEntry().state;
|
||||
next_state.sampling_number = last_entry.sampling_number + 1;
|
||||
|
||||
next_state.buttons.raw = 0;
|
||||
|
||||
shared_memory.sleep_lifo.WriteNextEntry(next_state);
|
||||
}
|
||||
|
||||
} // namespace Service::HID
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/resources/controller_base.h"
|
||||
#include "hid_core/resources/system_buttons/system_button_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
@@ -22,6 +23,6 @@ public:
|
||||
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
|
||||
|
||||
private:
|
||||
bool smart_update{};
|
||||
SleepButtonState next_state{};
|
||||
};
|
||||
} // namespace Service::HID
|
||||
|
||||
31
src/hid_core/resources/system_buttons/system_button_types.h
Normal file
31
src/hid_core/resources/system_buttons/system_button_types.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hid_core/hid_types.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
// This is nn::hid::system::SleepButtonState
|
||||
struct SleepButtonState {
|
||||
s64 sampling_number{};
|
||||
Core::HID::SleepButtonState buttons;
|
||||
};
|
||||
static_assert(sizeof(SleepButtonState) == 0x10, "SleepButtonState is an invalid size");
|
||||
|
||||
// This is nn::hid::system::HomeButtonState
|
||||
struct HomeButtonState {
|
||||
s64 sampling_number{};
|
||||
Core::HID::HomeButtonState buttons;
|
||||
};
|
||||
static_assert(sizeof(HomeButtonState) == 0x10, "HomeButtonState is an invalid size");
|
||||
|
||||
// This is nn::hid::system::SleepButtonState
|
||||
struct CaptureButtonState {
|
||||
s64 sampling_number{};
|
||||
Core::HID::CaptureButtonState buttons;
|
||||
};
|
||||
static_assert(sizeof(CaptureButtonState) == 0x10, "CaptureButtonState is an invalid size");
|
||||
|
||||
} // namespace Service::HID
|
||||
@@ -28,7 +28,7 @@ void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& header = data->shared_memory_format->capture_button.header;
|
||||
auto& header = data->shared_memory_format->unique_pad.header;
|
||||
header.timestamp = core_timing.GetGlobalTimeNs().count();
|
||||
header.total_entry_count = 17;
|
||||
header.entry_count = 0;
|
||||
|
||||
@@ -302,7 +302,7 @@ target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})
|
||||
|
||||
add_dependencies(video_core host_shaders)
|
||||
target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})
|
||||
target_link_libraries(video_core PRIVATE sirit Vulkan::Headers GPUOpen::VulkanMemoryAllocator)
|
||||
target_link_libraries(video_core PRIVATE sirit Vulkan::Headers Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator)
|
||||
|
||||
if (ENABLE_NSIGHT_AFTERMATH)
|
||||
if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK})
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "core/core.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_swapchain.h"
|
||||
#include "video_core/vulkan_common/vk_enum_string_helper.h"
|
||||
#include "video_core/vulkan_common/vulkan_device.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
@@ -151,7 +152,7 @@ bool Swapchain::AcquireNextImage() {
|
||||
vk::Check(result);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", vk::ToString(result));
|
||||
LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", string_VkResult(result));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -187,7 +188,7 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
|
||||
vk::Check(result);
|
||||
break;
|
||||
default:
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", vk::ToString(result));
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", string_VkResult(result));
|
||||
break;
|
||||
}
|
||||
++frame_index;
|
||||
|
||||
@@ -1431,7 +1431,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA
|
||||
}
|
||||
}
|
||||
};
|
||||
ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu);
|
||||
ForEachSparseImageInRegion(channel_state->gpu_memory.GetID(), gpu_addr, size_bytes,
|
||||
region_check_gpu);
|
||||
|
||||
bool can_rescale = info.rescaleable;
|
||||
bool any_rescaled = false;
|
||||
@@ -1842,7 +1843,7 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s
|
||||
if (!storage_id) {
|
||||
return;
|
||||
}
|
||||
auto& gpu_page_table = gpu_page_table_storage[*storage_id];
|
||||
auto& gpu_page_table = gpu_page_table_storage[*storage_id * 2];
|
||||
ForEachGPUPage(gpu_addr, size,
|
||||
[this, &gpu_page_table, &images, gpu_addr, size, func](u64 page) {
|
||||
const auto it = gpu_page_table.find(page);
|
||||
@@ -1882,41 +1883,48 @@ void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, s
|
||||
|
||||
template <class P>
|
||||
template <typename Func>
|
||||
void TextureCache<P>::ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func) {
|
||||
void TextureCache<P>::ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size,
|
||||
Func&& func) {
|
||||
using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type;
|
||||
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
|
||||
boost::container::small_vector<ImageId, 8> images;
|
||||
ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) {
|
||||
const auto it = sparse_page_table.find(page);
|
||||
if (it == sparse_page_table.end()) {
|
||||
if constexpr (BOOL_BREAK) {
|
||||
return false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const ImageId image_id : it->second) {
|
||||
Image& image = slot_images[image_id];
|
||||
if (True(image.flags & ImageFlagBits::Picked)) {
|
||||
continue;
|
||||
}
|
||||
if (!image.OverlapsGPU(gpu_addr, size)) {
|
||||
continue;
|
||||
}
|
||||
image.flags |= ImageFlagBits::Picked;
|
||||
images.push_back(image_id);
|
||||
if constexpr (BOOL_BREAK) {
|
||||
if (func(image_id, image)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
func(image_id, image);
|
||||
}
|
||||
}
|
||||
if constexpr (BOOL_BREAK) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
auto storage_id = getStorageID(as_id);
|
||||
if (!storage_id) {
|
||||
return;
|
||||
}
|
||||
auto& sparse_page_table = gpu_page_table_storage[*storage_id * 2 + 1];
|
||||
ForEachGPUPage(gpu_addr, size,
|
||||
[this, &sparse_page_table, &images, gpu_addr, size, func](u64 page) {
|
||||
const auto it = sparse_page_table.find(page);
|
||||
if (it == sparse_page_table.end()) {
|
||||
if constexpr (BOOL_BREAK) {
|
||||
return false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const ImageId image_id : it->second) {
|
||||
Image& image = slot_images[image_id];
|
||||
if (True(image.flags & ImageFlagBits::Picked)) {
|
||||
continue;
|
||||
}
|
||||
if (!image.OverlapsGPU(gpu_addr, size)) {
|
||||
continue;
|
||||
}
|
||||
image.flags |= ImageFlagBits::Picked;
|
||||
images.push_back(image_id);
|
||||
if constexpr (BOOL_BREAK) {
|
||||
if (func(image_id, image)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
func(image_id, image);
|
||||
}
|
||||
}
|
||||
if constexpr (BOOL_BREAK) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
for (const ImageId image_id : images) {
|
||||
slot_images[image_id].flags &= ~ImageFlagBits::Picked;
|
||||
}
|
||||
@@ -1988,8 +1996,9 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
|
||||
sparse_maps.push_back(map_id);
|
||||
});
|
||||
sparse_views.emplace(image_id, std::move(sparse_maps));
|
||||
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes,
|
||||
[this, image_id](u64 page) { sparse_page_table[page].push_back(image_id); });
|
||||
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
|
||||
(*channel_state->sparse_page_table)[page].push_back(image_id);
|
||||
});
|
||||
}
|
||||
|
||||
template <class P>
|
||||
@@ -2042,7 +2051,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
|
||||
return;
|
||||
}
|
||||
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) {
|
||||
clear_page_table(page, sparse_page_table);
|
||||
clear_page_table(page, (*channel_state->sparse_page_table));
|
||||
});
|
||||
auto it = sparse_views.find(image_id);
|
||||
ASSERT(it != sparse_views.end());
|
||||
@@ -2496,13 +2505,15 @@ void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel
|
||||
const auto it = channel_map.find(channel.bind_id);
|
||||
auto* this_state = &channel_storage[it->second];
|
||||
const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()];
|
||||
this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id];
|
||||
this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2];
|
||||
this_state->sparse_page_table = &gpu_page_table_storage[this_as_ref.storage_id * 2 + 1];
|
||||
}
|
||||
|
||||
/// Bind a channel for execution.
|
||||
template <class P>
|
||||
void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) {
|
||||
gpu_page_table_storage.emplace_back();
|
||||
gpu_page_table_storage.emplace_back();
|
||||
}
|
||||
|
||||
} // namespace VideoCommon
|
||||
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
std::unordered_map<TSCEntry, SamplerId> samplers;
|
||||
|
||||
TextureCacheGPUMap* gpu_page_table;
|
||||
TextureCacheGPUMap* sparse_page_table;
|
||||
};
|
||||
|
||||
template <class P>
|
||||
@@ -357,7 +358,7 @@ private:
|
||||
void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
|
||||
|
||||
template <typename Func>
|
||||
void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func);
|
||||
void ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
|
||||
|
||||
/// Iterates over all the images in a region calling func
|
||||
template <typename Func>
|
||||
@@ -431,7 +432,6 @@ private:
|
||||
std::unordered_map<RenderTargets, FramebufferId> framebuffers;
|
||||
|
||||
std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table;
|
||||
std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>> sparse_page_table;
|
||||
std::unordered_map<ImageId, boost::container::small_vector<ImageViewId, 16>> sparse_views;
|
||||
|
||||
DAddr virtual_invalid_space{};
|
||||
|
||||
8
src/video_core/vulkan_common/vk_enum_string_helper.h
Normal file
8
src/video_core/vulkan_common/vk_enum_string_helper.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "video_core/vulkan_common/vulkan.h"
|
||||
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "video_core/vulkan_common/vk_enum_string_helper.h"
|
||||
#include "video_core/vulkan_common/vma.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
|
||||
@@ -298,109 +299,7 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept {
|
||||
}
|
||||
|
||||
const char* Exception::what() const noexcept {
|
||||
return ToString(result);
|
||||
}
|
||||
|
||||
const char* ToString(VkResult result) noexcept {
|
||||
switch (result) {
|
||||
case VkResult::VK_SUCCESS:
|
||||
return "VK_SUCCESS";
|
||||
case VkResult::VK_NOT_READY:
|
||||
return "VK_NOT_READY";
|
||||
case VkResult::VK_TIMEOUT:
|
||||
return "VK_TIMEOUT";
|
||||
case VkResult::VK_EVENT_SET:
|
||||
return "VK_EVENT_SET";
|
||||
case VkResult::VK_EVENT_RESET:
|
||||
return "VK_EVENT_RESET";
|
||||
case VkResult::VK_INCOMPLETE:
|
||||
return "VK_INCOMPLETE";
|
||||
case VkResult::VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_HOST_MEMORY";
|
||||
case VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
|
||||
case VkResult::VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "VK_ERROR_INITIALIZATION_FAILED";
|
||||
case VkResult::VK_ERROR_DEVICE_LOST:
|
||||
return "VK_ERROR_DEVICE_LOST";
|
||||
case VkResult::VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "VK_ERROR_MEMORY_MAP_FAILED";
|
||||
case VkResult::VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "VK_ERROR_LAYER_NOT_PRESENT";
|
||||
case VkResult::VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "VK_ERROR_EXTENSION_NOT_PRESENT";
|
||||
case VkResult::VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "VK_ERROR_FEATURE_NOT_PRESENT";
|
||||
case VkResult::VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "VK_ERROR_INCOMPATIBLE_DRIVER";
|
||||
case VkResult::VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "VK_ERROR_TOO_MANY_OBJECTS";
|
||||
case VkResult::VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "VK_ERROR_FORMAT_NOT_SUPPORTED";
|
||||
case VkResult::VK_ERROR_FRAGMENTED_POOL:
|
||||
return "VK_ERROR_FRAGMENTED_POOL";
|
||||
case VkResult::VK_ERROR_OUT_OF_POOL_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_POOL_MEMORY";
|
||||
case VkResult::VK_ERROR_INVALID_EXTERNAL_HANDLE:
|
||||
return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
|
||||
case VkResult::VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "VK_ERROR_SURFACE_LOST_KHR";
|
||||
case VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
|
||||
case VkResult::VK_SUBOPTIMAL_KHR:
|
||||
return "VK_SUBOPTIMAL_KHR";
|
||||
case VkResult::VK_ERROR_OUT_OF_DATE_KHR:
|
||||
return "VK_ERROR_OUT_OF_DATE_KHR";
|
||||
case VkResult::VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
|
||||
case VkResult::VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "VK_ERROR_VALIDATION_FAILED_EXT";
|
||||
case VkResult::VK_ERROR_INVALID_SHADER_NV:
|
||||
return "VK_ERROR_INVALID_SHADER_NV";
|
||||
case VkResult::VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
|
||||
return "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR";
|
||||
case VkResult::VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
|
||||
return "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR";
|
||||
case VkResult::VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR:
|
||||
return "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR";
|
||||
case VkResult::VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR:
|
||||
return "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR";
|
||||
case VkResult::VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR:
|
||||
return "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR";
|
||||
case VkResult::VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
|
||||
return "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR";
|
||||
case VkResult::VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
|
||||
case VkResult::VK_ERROR_FRAGMENTATION_EXT:
|
||||
return "VK_ERROR_FRAGMENTATION_EXT";
|
||||
case VkResult::VK_ERROR_NOT_PERMITTED_EXT:
|
||||
return "VK_ERROR_NOT_PERMITTED_EXT";
|
||||
case VkResult::VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
|
||||
return "VK_ERROR_INVALID_DEVICE_ADDRESS_EXT";
|
||||
case VkResult::VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
|
||||
return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
|
||||
case VkResult::VK_ERROR_UNKNOWN:
|
||||
return "VK_ERROR_UNKNOWN";
|
||||
case VkResult::VK_THREAD_IDLE_KHR:
|
||||
return "VK_THREAD_IDLE_KHR";
|
||||
case VkResult::VK_THREAD_DONE_KHR:
|
||||
return "VK_THREAD_DONE_KHR";
|
||||
case VkResult::VK_OPERATION_DEFERRED_KHR:
|
||||
return "VK_OPERATION_DEFERRED_KHR";
|
||||
case VkResult::VK_OPERATION_NOT_DEFERRED_KHR:
|
||||
return "VK_OPERATION_NOT_DEFERRED_KHR";
|
||||
case VkResult::VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR:
|
||||
return "VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR";
|
||||
case VkResult::VK_PIPELINE_COMPILE_REQUIRED_EXT:
|
||||
return "VK_PIPELINE_COMPILE_REQUIRED_EXT";
|
||||
case VkResult::VK_RESULT_MAX_ENUM:
|
||||
return "VK_RESULT_MAX_ENUM";
|
||||
case VkResult::VK_ERROR_COMPRESSION_EXHAUSTED_EXT:
|
||||
return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT";
|
||||
case VkResult::VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT:
|
||||
return "VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT";
|
||||
}
|
||||
return "Unknown";
|
||||
return string_VkResult(result);
|
||||
}
|
||||
|
||||
void Destroy(VkInstance instance, const InstanceDispatch& dld) noexcept {
|
||||
@@ -1067,7 +966,7 @@ u32 AvailableVersion(const InstanceDispatch& dld) noexcept {
|
||||
u32 version;
|
||||
if (const VkResult result = vkEnumerateInstanceVersion(&version); result != VK_SUCCESS) {
|
||||
LOG_ERROR(Render_Vulkan, "vkEnumerateInstanceVersion returned {}, assuming Vulkan 1.1",
|
||||
ToString(result));
|
||||
string_VkResult(result));
|
||||
return VK_API_VERSION_1_1;
|
||||
}
|
||||
return version;
|
||||
|
||||
@@ -125,9 +125,6 @@ private:
|
||||
VkResult result;
|
||||
};
|
||||
|
||||
/// Converts a VkResult enum into a rodata string
|
||||
const char* ToString(VkResult) noexcept;
|
||||
|
||||
/// Throws a Vulkan exception if result is not success.
|
||||
inline void Check(VkResult result) {
|
||||
if (result != VK_SUCCESS) {
|
||||
|
||||
Reference in New Issue
Block a user