Compare commits
101 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09a8e08109 | ||
|
|
ac14ef70b5 | ||
|
|
35abd560c4 | ||
|
|
e7530b341e | ||
|
|
01928b1d17 | ||
|
|
ff1201210c | ||
|
|
f90041a2d4 | ||
|
|
6c81332ca7 | ||
|
|
7133bfdd2c | ||
|
|
556c5df745 | ||
|
|
4530b58eb0 | ||
|
|
53f1560a24 | ||
|
|
c37b8a1028 | ||
|
|
278c38aa4a | ||
|
|
a4e2821530 | ||
|
|
a83f0f7154 | ||
|
|
dbc4c8e314 | ||
|
|
03790771a6 | ||
|
|
0377618288 | ||
|
|
247b1c14d2 | ||
|
|
ec0e644fb0 | ||
|
|
8f1300cd31 | ||
|
|
6219da627b | ||
|
|
5ce97bf0a0 | ||
|
|
b059db74c5 | ||
|
|
c51d9e0b0a | ||
|
|
d7f2078e7b | ||
|
|
b6bbc0d483 | ||
|
|
d894818bb3 | ||
|
|
1744fa6ecf | ||
|
|
dfac2e2d25 | ||
|
|
415dfb6cd3 | ||
|
|
15a07f0282 | ||
|
|
262a70223f | ||
|
|
535e50db1c | ||
|
|
3173a53db9 | ||
|
|
d490f6dcf8 | ||
|
|
6dc35caad1 | ||
|
|
a2d40b8185 | ||
|
|
1ad4c98a5c | ||
|
|
c44db90ad1 | ||
|
|
531e797795 | ||
|
|
ded420cfeb | ||
|
|
63caeca6ba | ||
|
|
63ebf2a328 | ||
|
|
d04120169d | ||
|
|
ad0d5818a6 | ||
|
|
49ec5784b0 | ||
|
|
4cdc701fd3 | ||
|
|
95fa89da27 | ||
|
|
068b2ffbcc | ||
|
|
55fc808d64 | ||
|
|
03dda80e2b | ||
|
|
2cc42e40c5 | ||
|
|
638c892edf | ||
|
|
a60653dcd3 | ||
|
|
7feb490f83 | ||
|
|
9be819faaf | ||
|
|
33ed02a239 | ||
|
|
69b2dbdffd | ||
|
|
17ad323b36 | ||
|
|
c92a211e7c | ||
|
|
c5ca8675c8 | ||
|
|
aca6ab6417 | ||
|
|
0fbd7752c3 | ||
|
|
eaf0c4af11 | ||
|
|
94d77d0e39 | ||
|
|
824adb44fa | ||
|
|
d3e87d70ec | ||
|
|
7ff7e65926 | ||
|
|
d69421b1db | ||
|
|
e44622860a | ||
|
|
bb3dce9363 | ||
|
|
5ee669466f | ||
|
|
eeea426c74 | ||
|
|
ca30190fad | ||
|
|
54c1e0897d | ||
|
|
e6e61424d4 | ||
|
|
b3f68098d5 | ||
|
|
f234531f92 | ||
|
|
9b50b23a50 | ||
|
|
fb7dcbf7af | ||
|
|
a63dcb6d56 | ||
|
|
f8561c7a65 | ||
|
|
a527e5f0cd | ||
|
|
9cebde760f | ||
|
|
8a5794c4db | ||
|
|
cb7f2e5616 | ||
|
|
3b98fab850 | ||
|
|
7c26a9aefe | ||
|
|
2f83d9a61b | ||
|
|
99fdfa1fcd | ||
|
|
65774084fd | ||
|
|
b83eb4dd18 | ||
|
|
52dae41d7f | ||
|
|
875183e7c5 | ||
|
|
2f30c10584 | ||
|
|
c7553abe89 | ||
|
|
20eb368e14 | ||
|
|
f6566338eb | ||
|
|
2985e5e94c |
@@ -8,7 +8,7 @@ steps:
|
||||
displayName: 'Install vulkan-sdk'
|
||||
- script: python -m pip install --upgrade pip conan
|
||||
displayName: 'Install conan'
|
||||
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 --config Release -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cd ..
|
||||
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cmake --install . --config Release && cd ..
|
||||
displayName: 'Configure CMake'
|
||||
- task: MSBuild@1
|
||||
displayName: 'Build'
|
||||
|
||||
4
externals/CMakeLists.txt
vendored
4
externals/CMakeLists.txt
vendored
@@ -64,8 +64,8 @@ endif()
|
||||
add_subdirectory(sirit)
|
||||
|
||||
# libzip
|
||||
find_package(Libzip 1.5)
|
||||
if (NOT LIBZIP_FOUND)
|
||||
find_package(libzip 1.5)
|
||||
if (NOT libzip_FOUND)
|
||||
message(STATUS "libzip 1.5 or newer not found, falling back to externals")
|
||||
add_subdirectory(libzip EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
Submodule externals/dynarmic updated: 646fd05920...c788bcdf17
72
externals/find-modules/FindLibzip.cmake
vendored
72
externals/find-modules/FindLibzip.cmake
vendored
@@ -1,72 +0,0 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_LIBZIP QUIET libzip)
|
||||
|
||||
find_path(LIBZIP_INCLUDE_DIR
|
||||
NAMES zip.h
|
||||
PATHS ${PC_LIBZIP_INCLUDE_DIRS}
|
||||
"$ENV{LIB_DIR}/include"
|
||||
"$ENV{INCLUDE}"
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
find_path(LIBZIP_INCLUDE_DIR_ZIPCONF
|
||||
NAMES zipconf.h
|
||||
HINTS ${PC_LIBZIP_INCLUDE_DIRS}
|
||||
"$ENV{LIB_DIR}/include"
|
||||
"$ENV{LIB_DIR}/lib/libzip/include"
|
||||
"$ENV{LIB}/lib/libzip/include"
|
||||
/usr/local/lib/libzip/include
|
||||
/usr/lib/libzip/include
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
"$ENV{INCLUDE}"
|
||||
)
|
||||
find_library(LIBZIP_LIBRARY
|
||||
NAMES zip
|
||||
PATHS ${PC_LIBZIP_LIBRARY_DIRS}
|
||||
"$ENV{LIB_DIR}/lib" "$ENV{LIB}" /usr/local/lib /usr/lib
|
||||
)
|
||||
|
||||
if (LIBZIP_INCLUDE_DIR_ZIPCONF)
|
||||
FILE(READ "${LIBZIP_INCLUDE_DIR_ZIPCONF}/zipconf.h" _LIBZIP_VERSION_CONTENTS)
|
||||
if (_LIBZIP_VERSION_CONTENTS)
|
||||
STRING(REGEX REPLACE ".*#define LIBZIP_VERSION \"([0-9.]+)\".*" "\\1" LIBZIP_VERSION "${_LIBZIP_VERSION_CONTENTS}")
|
||||
endif()
|
||||
unset(_LIBZIP_VERSION_CONTENTS)
|
||||
endif()
|
||||
|
||||
set(LIBZIP_VERSION ${LIBZIP_VERSION} CACHE STRING "Version number of libzip")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libzip
|
||||
FOUND_VAR LIBZIP_FOUND
|
||||
REQUIRED_VARS
|
||||
LIBZIP_LIBRARY
|
||||
LIBZIP_INCLUDE_DIR
|
||||
LIBZIP_INCLUDE_DIR_ZIPCONF
|
||||
LIBZIP_VERSION
|
||||
VERSION_VAR LIBZIP_VERSION
|
||||
)
|
||||
|
||||
if(LIBZIP_FOUND)
|
||||
set(LIBZIP_LIBRARIES ${LIBZIP_LIBRARY})
|
||||
set(LIBZIP_INCLUDE_DIRS ${LIBZIP_INCLUDE_DIR})
|
||||
set(LIBZIP_DEFINITIONS ${PC_LIBZIP_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(LIBZIP_FOUND AND NOT TARGET libzip::libzip)
|
||||
add_library(libzip::libzip UNKNOWN IMPORTED)
|
||||
set_target_properties(libzip::libzip PROPERTIES
|
||||
IMPORTED_LOCATION "${LIBZIP_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_LIBZIP_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${LIBZIP_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
LIBZIP_INCLUDE_DIR
|
||||
LIBZIP_INCLUDE_DIR_ZIPCONF
|
||||
LIBZIP_LIBRARY
|
||||
LIBZIP_VERSION
|
||||
)
|
||||
72
externals/find-modules/Findlibzip.cmake
vendored
Normal file
72
externals/find-modules/Findlibzip.cmake
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_libzip QUIET libzip)
|
||||
|
||||
find_path(libzip_INCLUDE_DIR
|
||||
NAMES zip.h
|
||||
PATHS ${PC_libzip_INCLUDE_DIRS}
|
||||
"$ENV{LIB_DIR}/include"
|
||||
"$ENV{INCLUDE}"
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
find_path(libzip_INCLUDE_DIR_ZIPCONF
|
||||
NAMES zipconf.h
|
||||
HINTS ${PC_libzip_INCLUDE_DIRS}
|
||||
"$ENV{LIB_DIR}/include"
|
||||
"$ENV{LIB_DIR}/lib/libzip/include"
|
||||
"$ENV{LIB}/lib/libzip/include"
|
||||
/usr/local/lib/libzip/include
|
||||
/usr/lib/libzip/include
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
"$ENV{INCLUDE}"
|
||||
)
|
||||
find_library(libzip_LIBRARY
|
||||
NAMES zip
|
||||
PATHS ${PC_libzip_LIBRARY_DIRS}
|
||||
"$ENV{LIB_DIR}/lib" "$ENV{LIB}" /usr/local/lib /usr/lib
|
||||
)
|
||||
|
||||
if (libzip_INCLUDE_DIR_ZIPCONF)
|
||||
FILE(READ "${libzip_INCLUDE_DIR_ZIPCONF}/zipconf.h" _libzip_VERSION_CONTENTS)
|
||||
if (_libzip_VERSION_CONTENTS)
|
||||
STRING(REGEX REPLACE ".*#define LIBZIP_VERSION \"([0-9.]+)\".*" "\\1" libzip_VERSION "${_libzip_VERSION_CONTENTS}")
|
||||
endif()
|
||||
unset(_libzip_VERSION_CONTENTS)
|
||||
endif()
|
||||
|
||||
set(libzip_VERSION ${libzip_VERSION} CACHE STRING "Version number of libzip")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(libzip
|
||||
FOUND_VAR libzip_FOUND
|
||||
REQUIRED_VARS
|
||||
libzip_LIBRARY
|
||||
libzip_INCLUDE_DIR
|
||||
libzip_INCLUDE_DIR_ZIPCONF
|
||||
libzip_VERSION
|
||||
VERSION_VAR libzip_VERSION
|
||||
)
|
||||
|
||||
if(libzip_FOUND)
|
||||
set(libzip_LIBRARIES ${libzip_LIBRARY})
|
||||
set(libzip_INCLUDE_DIRS ${libzip_INCLUDE_DIR})
|
||||
set(libzip_DEFINITIONS ${PC_libzip_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(libzip_FOUND AND NOT TARGET libzip::libzip)
|
||||
add_library(libzip::libzip UNKNOWN IMPORTED)
|
||||
set_target_properties(libzip::libzip PROPERTIES
|
||||
IMPORTED_LOCATION "${libzip_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_libzip_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${libzip_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
libzip_INCLUDE_DIR
|
||||
libzip_INCLUDE_DIR_ZIPCONF
|
||||
libzip_LIBRARY
|
||||
libzip_VERSION
|
||||
)
|
||||
@@ -97,6 +97,7 @@ add_custom_command(OUTPUT scm_rev.cpp
|
||||
add_library(common STATIC
|
||||
algorithm.h
|
||||
alignment.h
|
||||
assert.cpp
|
||||
assert.h
|
||||
atomic_ops.h
|
||||
detached_tasks.cpp
|
||||
|
||||
11
src/common/assert.cpp
Normal file
11
src/common/assert.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/assert.h"
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
|
||||
void assert_handle_failure() {
|
||||
Crash();
|
||||
}
|
||||
@@ -4,10 +4,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
// Sometimes we want to try to continue even after hitting an assert.
|
||||
// However touching this file yields a global recompilation as this header is included almost
|
||||
// everywhere. So let's just move the handling of the failed assert to a single cpp file.
|
||||
void assert_handle_failure();
|
||||
|
||||
// For asserts we'd like to keep all the junk executed when an assert happens away from the
|
||||
// important code in the function. One way of doing this is to put all the relevant code inside a
|
||||
// lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to
|
||||
@@ -17,15 +20,14 @@
|
||||
// enough for our purposes.
|
||||
template <typename Fn>
|
||||
#if defined(_MSC_VER)
|
||||
[[msvc::noinline, noreturn]]
|
||||
[[msvc::noinline]]
|
||||
#elif defined(__GNUC__)
|
||||
[[gnu::cold, gnu::noinline, noreturn]]
|
||||
[[gnu::cold, gnu::noinline]]
|
||||
#endif
|
||||
static void
|
||||
assert_noinline_call(const Fn& fn) {
|
||||
fn();
|
||||
Crash();
|
||||
exit(1); // Keeps GCC's mouth shut about this actually returning
|
||||
assert_handle_failure();
|
||||
}
|
||||
|
||||
#define ASSERT(_a_) \
|
||||
|
||||
@@ -114,18 +114,17 @@ public:
|
||||
static constexpr u64 minimum_run_cycles = 1000U;
|
||||
};
|
||||
|
||||
std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable& page_table,
|
||||
std::size_t address_space_bits) const {
|
||||
std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* page_table) const {
|
||||
Dynarmic::A32::UserConfig config;
|
||||
config.callbacks = cb.get();
|
||||
// TODO(bunnei): Implement page table for 32-bit
|
||||
// config.page_table = &page_table.pointers;
|
||||
config.coprocessors[15] = cp15;
|
||||
config.define_unpredictable_behaviour = true;
|
||||
static constexpr std::size_t PAGE_BITS = 12;
|
||||
static constexpr std::size_t NUM_PAGE_TABLE_ENTRIES = 1 << (32 - PAGE_BITS);
|
||||
config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>(
|
||||
page_table.pointers.data());
|
||||
if (page_table) {
|
||||
config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>(
|
||||
page_table->pointers.data());
|
||||
}
|
||||
config.absolute_offset_page_table = true;
|
||||
config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
|
||||
config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
|
||||
@@ -138,6 +137,10 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
|
||||
// Timing
|
||||
config.wall_clock_cntpct = uses_wall_clock;
|
||||
|
||||
// Code cache size
|
||||
config.code_cache_size = 512 * 1024 * 1024;
|
||||
config.far_code_offset = 256 * 1024 * 1024;
|
||||
|
||||
// Safe optimizations
|
||||
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) {
|
||||
if (!Settings::values.cpuopt_page_tables) {
|
||||
@@ -201,7 +204,8 @@ ARM_Dynarmic_32::ARM_Dynarmic_32(System& system, CPUInterrupts& interrupt_handle
|
||||
: ARM_Interface{system, interrupt_handlers, uses_wall_clock},
|
||||
cb(std::make_unique<DynarmicCallbacks32>(*this)),
|
||||
cp15(std::make_shared<DynarmicCP15>(*this)), core_index{core_index},
|
||||
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
|
||||
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)},
|
||||
jit(MakeJit(nullptr)) {}
|
||||
|
||||
ARM_Dynarmic_32::~ARM_Dynarmic_32() = default;
|
||||
|
||||
@@ -256,9 +260,6 @@ void ARM_Dynarmic_32::ChangeProcessorID(std::size_t new_core_id) {
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
Dynarmic::A32::Context context;
|
||||
jit->SaveContext(context);
|
||||
ctx.cpu_registers = context.Regs();
|
||||
@@ -268,9 +269,6 @@ void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) {
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
Dynarmic::A32::Context context;
|
||||
context.Regs() = ctx.cpu_registers;
|
||||
context.ExtRegs() = ctx.extension_registers;
|
||||
@@ -284,23 +282,14 @@ void ARM_Dynarmic_32::PrepareReschedule() {
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::ClearInstructionCache() {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->ClearCache();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->InvalidateCacheRange(static_cast<u32>(addr), size);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::ClearExclusiveState() {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->ClearExclusiveState();
|
||||
}
|
||||
|
||||
@@ -316,7 +305,7 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table,
|
||||
LoadContext(ctx);
|
||||
return;
|
||||
}
|
||||
jit = MakeJit(page_table, new_address_space_size_in_bits);
|
||||
jit = MakeJit(&page_table);
|
||||
LoadContext(ctx);
|
||||
jit_cache.emplace(key, jit);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,7 @@ public:
|
||||
std::size_t new_address_space_size_in_bits) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable& page_table,
|
||||
std::size_t address_space_bits) const;
|
||||
std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const;
|
||||
|
||||
using JitCacheKey = std::pair<Common::PageTable*, std::size_t>;
|
||||
using JitCacheType =
|
||||
@@ -80,10 +79,10 @@ private:
|
||||
|
||||
std::unique_ptr<DynarmicCallbacks32> cb;
|
||||
JitCacheType jit_cache;
|
||||
std::shared_ptr<Dynarmic::A32::Jit> jit;
|
||||
std::shared_ptr<DynarmicCP15> cp15;
|
||||
std::size_t core_index;
|
||||
DynarmicExclusiveMonitor& exclusive_monitor;
|
||||
std::shared_ptr<Dynarmic::A32::Jit> jit;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
static constexpr u64 minimum_run_cycles = 1000U;
|
||||
};
|
||||
|
||||
std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable& page_table,
|
||||
std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* page_table,
|
||||
std::size_t address_space_bits) const {
|
||||
Dynarmic::A64::UserConfig config;
|
||||
|
||||
@@ -150,13 +150,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
|
||||
config.callbacks = cb.get();
|
||||
|
||||
// Memory
|
||||
config.page_table = reinterpret_cast<void**>(page_table.pointers.data());
|
||||
config.page_table_address_space_bits = address_space_bits;
|
||||
config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
|
||||
config.silently_mirror_page_table = false;
|
||||
config.absolute_offset_page_table = true;
|
||||
config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
|
||||
config.only_detect_misalignment_via_page_table_on_page_boundary = true;
|
||||
if (page_table) {
|
||||
config.page_table = reinterpret_cast<void**>(page_table->pointers.data());
|
||||
config.page_table_address_space_bits = address_space_bits;
|
||||
config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
|
||||
config.silently_mirror_page_table = false;
|
||||
config.absolute_offset_page_table = true;
|
||||
config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
|
||||
config.only_detect_misalignment_via_page_table_on_page_boundary = true;
|
||||
}
|
||||
|
||||
// Multi-process state
|
||||
config.processor_id = core_index;
|
||||
@@ -175,6 +177,10 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
|
||||
// Timing
|
||||
config.wall_clock_cntpct = uses_wall_clock;
|
||||
|
||||
// Code cache size
|
||||
config.code_cache_size = 512 * 1024 * 1024;
|
||||
config.far_code_offset = 256 * 1024 * 1024;
|
||||
|
||||
// Safe optimizations
|
||||
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) {
|
||||
if (!Settings::values.cpuopt_page_tables) {
|
||||
@@ -237,7 +243,8 @@ ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handle
|
||||
std::size_t core_index)
|
||||
: ARM_Interface{system, interrupt_handlers, uses_wall_clock},
|
||||
cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index},
|
||||
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
|
||||
exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)},
|
||||
jit(MakeJit(nullptr, 48)) {}
|
||||
|
||||
ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;
|
||||
|
||||
@@ -294,9 +301,6 @@ void ARM_Dynarmic_64::ChangeProcessorID(std::size_t new_core_id) {
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
ctx.cpu_registers = jit->GetRegisters();
|
||||
ctx.sp = jit->GetSP();
|
||||
ctx.pc = jit->GetPC();
|
||||
@@ -308,9 +312,6 @@ void ARM_Dynarmic_64::SaveContext(ThreadContext64& ctx) {
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::LoadContext(const ThreadContext64& ctx) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->SetRegisters(ctx.cpu_registers);
|
||||
jit->SetSP(ctx.sp);
|
||||
jit->SetPC(ctx.pc);
|
||||
@@ -326,23 +327,14 @@ void ARM_Dynarmic_64::PrepareReschedule() {
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::ClearInstructionCache() {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->ClearCache();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->InvalidateCacheRange(addr, size);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::ClearExclusiveState() {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->ClearExclusiveState();
|
||||
}
|
||||
|
||||
@@ -358,7 +350,7 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table,
|
||||
LoadContext(ctx);
|
||||
return;
|
||||
}
|
||||
jit = MakeJit(page_table, new_address_space_size_in_bits);
|
||||
jit = MakeJit(&page_table, new_address_space_size_in_bits);
|
||||
LoadContext(ctx);
|
||||
jit_cache.emplace(key, jit);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
std::size_t new_address_space_size_in_bits) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable& page_table,
|
||||
std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table,
|
||||
std::size_t address_space_bits) const;
|
||||
|
||||
using JitCacheKey = std::pair<Common::PageTable*, std::size_t>;
|
||||
@@ -71,10 +71,11 @@ private:
|
||||
friend class DynarmicCallbacks64;
|
||||
std::unique_ptr<DynarmicCallbacks64> cb;
|
||||
JitCacheType jit_cache;
|
||||
std::shared_ptr<Dynarmic::A64::Jit> jit;
|
||||
|
||||
std::size_t core_index;
|
||||
DynarmicExclusiveMonitor& exclusive_monitor;
|
||||
|
||||
std::shared_ptr<Dynarmic::A64::Jit> jit;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
@@ -68,9 +68,9 @@ struct KernelCore::Impl {
|
||||
InitializePhysicalCores();
|
||||
InitializeSystemResourceLimit(kernel, system);
|
||||
InitializeMemoryLayout();
|
||||
InitializePreemption(kernel);
|
||||
InitializeSchedulers();
|
||||
InitializeSuspendThreads();
|
||||
InitializePreemption(kernel);
|
||||
}
|
||||
|
||||
void InitializeCores() {
|
||||
|
||||
@@ -281,11 +281,6 @@ ResultCode ProcessCapabilities::HandleSyscallFlags(u32& set_svc_bits, u32 flags)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (svc_number >= svc_capabilities.size()) {
|
||||
LOG_ERROR(Kernel, "Process svc capability is out of range! svc_number={}", svc_number);
|
||||
return ResultOutOfRange;
|
||||
}
|
||||
|
||||
svc_capabilities[svc_number] = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ enum class ProgramType {
|
||||
class ProcessCapabilities {
|
||||
public:
|
||||
using InterruptCapabilities = std::bitset<1024>;
|
||||
using SyscallCapabilities = std::bitset<128>;
|
||||
using SyscallCapabilities = std::bitset<192>;
|
||||
|
||||
ProcessCapabilities() = default;
|
||||
ProcessCapabilities(const ProcessCapabilities&) = delete;
|
||||
|
||||
@@ -2455,6 +2455,74 @@ static const FunctionDef SVC_Table_32[] = {
|
||||
{0x79, nullptr, "Unknown"},
|
||||
{0x7A, nullptr, "Unknown"},
|
||||
{0x7B, nullptr, "TerminateProcess32"},
|
||||
{0x7C, nullptr, "GetProcessInfo32"},
|
||||
{0x7D, nullptr, "CreateResourceLimit32"},
|
||||
{0x7E, nullptr, "SetResourceLimitLimitValue32"},
|
||||
{0x7F, nullptr, "CallSecureMonitor32"},
|
||||
{0x80, nullptr, "Unknown"},
|
||||
{0x81, nullptr, "Unknown"},
|
||||
{0x82, nullptr, "Unknown"},
|
||||
{0x83, nullptr, "Unknown"},
|
||||
{0x84, nullptr, "Unknown"},
|
||||
{0x85, nullptr, "Unknown"},
|
||||
{0x86, nullptr, "Unknown"},
|
||||
{0x87, nullptr, "Unknown"},
|
||||
{0x88, nullptr, "Unknown"},
|
||||
{0x89, nullptr, "Unknown"},
|
||||
{0x8A, nullptr, "Unknown"},
|
||||
{0x8B, nullptr, "Unknown"},
|
||||
{0x8C, nullptr, "Unknown"},
|
||||
{0x8D, nullptr, "Unknown"},
|
||||
{0x8E, nullptr, "Unknown"},
|
||||
{0x8F, nullptr, "Unknown"},
|
||||
{0x90, nullptr, "Unknown"},
|
||||
{0x91, nullptr, "Unknown"},
|
||||
{0x92, nullptr, "Unknown"},
|
||||
{0x93, nullptr, "Unknown"},
|
||||
{0x94, nullptr, "Unknown"},
|
||||
{0x95, nullptr, "Unknown"},
|
||||
{0x96, nullptr, "Unknown"},
|
||||
{0x97, nullptr, "Unknown"},
|
||||
{0x98, nullptr, "Unknown"},
|
||||
{0x99, nullptr, "Unknown"},
|
||||
{0x9A, nullptr, "Unknown"},
|
||||
{0x9B, nullptr, "Unknown"},
|
||||
{0x9C, nullptr, "Unknown"},
|
||||
{0x9D, nullptr, "Unknown"},
|
||||
{0x9E, nullptr, "Unknown"},
|
||||
{0x9F, nullptr, "Unknown"},
|
||||
{0xA0, nullptr, "Unknown"},
|
||||
{0xA1, nullptr, "Unknown"},
|
||||
{0xA2, nullptr, "Unknown"},
|
||||
{0xA3, nullptr, "Unknown"},
|
||||
{0xA4, nullptr, "Unknown"},
|
||||
{0xA5, nullptr, "Unknown"},
|
||||
{0xA6, nullptr, "Unknown"},
|
||||
{0xA7, nullptr, "Unknown"},
|
||||
{0xA8, nullptr, "Unknown"},
|
||||
{0xA9, nullptr, "Unknown"},
|
||||
{0xAA, nullptr, "Unknown"},
|
||||
{0xAB, nullptr, "Unknown"},
|
||||
{0xAC, nullptr, "Unknown"},
|
||||
{0xAD, nullptr, "Unknown"},
|
||||
{0xAE, nullptr, "Unknown"},
|
||||
{0xAF, nullptr, "Unknown"},
|
||||
{0xB0, nullptr, "Unknown"},
|
||||
{0xB1, nullptr, "Unknown"},
|
||||
{0xB2, nullptr, "Unknown"},
|
||||
{0xB3, nullptr, "Unknown"},
|
||||
{0xB4, nullptr, "Unknown"},
|
||||
{0xB5, nullptr, "Unknown"},
|
||||
{0xB6, nullptr, "Unknown"},
|
||||
{0xB7, nullptr, "Unknown"},
|
||||
{0xB8, nullptr, "Unknown"},
|
||||
{0xB9, nullptr, "Unknown"},
|
||||
{0xBA, nullptr, "Unknown"},
|
||||
{0xBB, nullptr, "Unknown"},
|
||||
{0xBC, nullptr, "Unknown"},
|
||||
{0xBD, nullptr, "Unknown"},
|
||||
{0xBE, nullptr, "Unknown"},
|
||||
{0xBF, nullptr, "Unknown"},
|
||||
};
|
||||
|
||||
static const FunctionDef SVC_Table_64[] = {
|
||||
@@ -2586,6 +2654,70 @@ static const FunctionDef SVC_Table_64[] = {
|
||||
{0x7D, SvcWrap64<CreateResourceLimit>, "CreateResourceLimit"},
|
||||
{0x7E, SvcWrap64<SetResourceLimitLimitValue>, "SetResourceLimitLimitValue"},
|
||||
{0x7F, nullptr, "CallSecureMonitor"},
|
||||
{0x80, nullptr, "Unknown"},
|
||||
{0x81, nullptr, "Unknown"},
|
||||
{0x82, nullptr, "Unknown"},
|
||||
{0x83, nullptr, "Unknown"},
|
||||
{0x84, nullptr, "Unknown"},
|
||||
{0x85, nullptr, "Unknown"},
|
||||
{0x86, nullptr, "Unknown"},
|
||||
{0x87, nullptr, "Unknown"},
|
||||
{0x88, nullptr, "Unknown"},
|
||||
{0x89, nullptr, "Unknown"},
|
||||
{0x8A, nullptr, "Unknown"},
|
||||
{0x8B, nullptr, "Unknown"},
|
||||
{0x8C, nullptr, "Unknown"},
|
||||
{0x8D, nullptr, "Unknown"},
|
||||
{0x8E, nullptr, "Unknown"},
|
||||
{0x8F, nullptr, "Unknown"},
|
||||
{0x90, nullptr, "Unknown"},
|
||||
{0x91, nullptr, "Unknown"},
|
||||
{0x92, nullptr, "Unknown"},
|
||||
{0x93, nullptr, "Unknown"},
|
||||
{0x94, nullptr, "Unknown"},
|
||||
{0x95, nullptr, "Unknown"},
|
||||
{0x96, nullptr, "Unknown"},
|
||||
{0x97, nullptr, "Unknown"},
|
||||
{0x98, nullptr, "Unknown"},
|
||||
{0x99, nullptr, "Unknown"},
|
||||
{0x9A, nullptr, "Unknown"},
|
||||
{0x9B, nullptr, "Unknown"},
|
||||
{0x9C, nullptr, "Unknown"},
|
||||
{0x9D, nullptr, "Unknown"},
|
||||
{0x9E, nullptr, "Unknown"},
|
||||
{0x9F, nullptr, "Unknown"},
|
||||
{0xA0, nullptr, "Unknown"},
|
||||
{0xA1, nullptr, "Unknown"},
|
||||
{0xA2, nullptr, "Unknown"},
|
||||
{0xA3, nullptr, "Unknown"},
|
||||
{0xA4, nullptr, "Unknown"},
|
||||
{0xA5, nullptr, "Unknown"},
|
||||
{0xA6, nullptr, "Unknown"},
|
||||
{0xA7, nullptr, "Unknown"},
|
||||
{0xA8, nullptr, "Unknown"},
|
||||
{0xA9, nullptr, "Unknown"},
|
||||
{0xAA, nullptr, "Unknown"},
|
||||
{0xAB, nullptr, "Unknown"},
|
||||
{0xAC, nullptr, "Unknown"},
|
||||
{0xAD, nullptr, "Unknown"},
|
||||
{0xAE, nullptr, "Unknown"},
|
||||
{0xAF, nullptr, "Unknown"},
|
||||
{0xB0, nullptr, "Unknown"},
|
||||
{0xB1, nullptr, "Unknown"},
|
||||
{0xB2, nullptr, "Unknown"},
|
||||
{0xB3, nullptr, "Unknown"},
|
||||
{0xB4, nullptr, "Unknown"},
|
||||
{0xB5, nullptr, "Unknown"},
|
||||
{0xB6, nullptr, "Unknown"},
|
||||
{0xB7, nullptr, "Unknown"},
|
||||
{0xB8, nullptr, "Unknown"},
|
||||
{0xB9, nullptr, "Unknown"},
|
||||
{0xBA, nullptr, "Unknown"},
|
||||
{0xBB, nullptr, "Unknown"},
|
||||
{0xBC, nullptr, "Unknown"},
|
||||
{0xBD, nullptr, "Unknown"},
|
||||
{0xBE, nullptr, "Unknown"},
|
||||
{0xBF, nullptr, "Unknown"},
|
||||
};
|
||||
|
||||
static const FunctionDef* GetSVCInfo32(u32 func_num) {
|
||||
|
||||
@@ -610,12 +610,17 @@ public:
|
||||
explicit DAUTH_O(Core::System& system_, Common::UUID) : ServiceFramework{system_, "dauth:o"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, // [5.0.0-5.1.0] GeneratePostData
|
||||
{1, nullptr, "LoadAuthenticationTokenCache"}, // 6.0.0+
|
||||
{2, nullptr, "InvalidateAuthenticationTokenCache"}, // 6.0.0+
|
||||
{10, nullptr, "EnsureEdgeTokenCacheAsync"}, // 6.0.0+
|
||||
{11, nullptr, "LoadEdgeTokenCache"}, // 6.0.0+
|
||||
{12, nullptr, "InvalidateEdgeTokenCache"}, // 6.0.0+
|
||||
{0, nullptr, "EnsureAuthenticationTokenCacheAsync"},
|
||||
{1, nullptr, "LoadAuthenticationTokenCache"},
|
||||
{2, nullptr, "InvalidateAuthenticationTokenCache"},
|
||||
{10, nullptr, "EnsureEdgeTokenCacheAsync"},
|
||||
{11, nullptr, "LoadEdgeTokenCache"},
|
||||
{12, nullptr, "InvalidateEdgeTokenCache"},
|
||||
{20, nullptr, "EnsureApplicationAuthenticationCacheAsync"},
|
||||
{21, nullptr, "LoadApplicationAuthenticationTokenCache"},
|
||||
{22, nullptr, "LoadApplicationNetworkServiceClientConfigCache"},
|
||||
{23, nullptr, "IsApplicationAuthenticationCacheAvailable"},
|
||||
{24, nullptr, "InvalidateApplicationAuthenticationCache"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -17,28 +17,30 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
||||
{3, &ACC_SU::ListOpenUsers, "ListOpenUsers"},
|
||||
{4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"},
|
||||
{5, &ACC_SU::GetProfile, "GetProfile"},
|
||||
{6, nullptr, "GetProfileDigest"}, // 3.0.0+
|
||||
{6, nullptr, "GetProfileDigest"},
|
||||
{50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
|
||||
{51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
|
||||
{60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
|
||||
{99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
|
||||
{60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
|
||||
{99, nullptr, "DebugActivateOpenContextRetention"},
|
||||
{100, nullptr, "GetUserRegistrationNotifier"},
|
||||
{101, nullptr, "GetUserStateChangeNotifier"},
|
||||
{102, nullptr, "GetBaasAccountManagerForSystemService"},
|
||||
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
|
||||
{104, nullptr, "GetProfileUpdateNotifier"},
|
||||
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
|
||||
{106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
|
||||
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
|
||||
{106, nullptr, "GetProfileSyncNotifier"},
|
||||
{110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"},
|
||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||
{112, nullptr, "LoadSaveDataThumbnail"},
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
|
||||
{120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+
|
||||
{130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+
|
||||
{140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
|
||||
{150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+
|
||||
{190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0
|
||||
{191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"},
|
||||
{120, nullptr, "ListOpenUsersInApplication"},
|
||||
{130, nullptr, "ActivateOpenContextRetention"},
|
||||
{140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"},
|
||||
{150, nullptr, "AuthenticateApplicationAsync"},
|
||||
{151, nullptr, "Unknown151"},
|
||||
{152, nullptr, "Unknown152"},
|
||||
{190, nullptr, "GetUserLastOpenedApplication"},
|
||||
{191, nullptr, "ActivateOpenContextHolder"},
|
||||
{200, nullptr, "BeginUserRegistration"},
|
||||
{201, nullptr, "CompleteUserRegistration"},
|
||||
{202, nullptr, "CancelUserRegistration"},
|
||||
@@ -46,15 +48,15 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
||||
{204, nullptr, "SetUserPosition"},
|
||||
{205, &ACC_SU::GetProfileEditor, "GetProfileEditor"},
|
||||
{206, nullptr, "CompleteUserRegistrationForcibly"},
|
||||
{210, nullptr, "CreateFloatingRegistrationRequest"}, // 3.0.0+
|
||||
{211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+
|
||||
{212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+
|
||||
{210, nullptr, "CreateFloatingRegistrationRequest"},
|
||||
{211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
|
||||
{212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
|
||||
{230, nullptr, "AuthenticateServiceAsync"},
|
||||
{250, nullptr, "GetBaasAccountAdministrator"},
|
||||
{290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
|
||||
{291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, // 3.0.0+
|
||||
{291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
|
||||
{299, nullptr, "SuspendBackgroundDaemon"},
|
||||
{997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+
|
||||
{997, nullptr, "DebugInvalidateTokenCacheForUser"},
|
||||
{998, nullptr, "DebugSetUserStateClose"},
|
||||
{999, nullptr, "DebugSetUserStateOpen"},
|
||||
};
|
||||
|
||||
@@ -17,29 +17,31 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
||||
{3, &ACC_U1::ListOpenUsers, "ListOpenUsers"},
|
||||
{4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"},
|
||||
{5, &ACC_U1::GetProfile, "GetProfile"},
|
||||
{6, nullptr, "GetProfileDigest"}, // 3.0.0+
|
||||
{6, nullptr, "GetProfileDigest"},
|
||||
{50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
|
||||
{51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
|
||||
{60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
|
||||
{99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
|
||||
{60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
|
||||
{99, nullptr, "DebugActivateOpenContextRetention"},
|
||||
{100, nullptr, "GetUserRegistrationNotifier"},
|
||||
{101, nullptr, "GetUserStateChangeNotifier"},
|
||||
{102, nullptr, "GetBaasAccountManagerForSystemService"},
|
||||
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
|
||||
{104, nullptr, "GetProfileUpdateNotifier"},
|
||||
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
|
||||
{106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
|
||||
{105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
|
||||
{106, nullptr, "GetProfileSyncNotifier"},
|
||||
{110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
|
||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||
{112, nullptr, "LoadSaveDataThumbnail"},
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
|
||||
{120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+
|
||||
{130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+
|
||||
{140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
|
||||
{150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+
|
||||
{190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0
|
||||
{191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+
|
||||
{997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+
|
||||
{113, nullptr, "GetSaveDataThumbnailExistence"},
|
||||
{120, nullptr, "ListOpenUsersInApplication"},
|
||||
{130, nullptr, "ActivateOpenContextRetention"},
|
||||
{140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"},
|
||||
{150, nullptr, "AuthenticateApplicationAsync"},
|
||||
{151, nullptr, "Unknown151"},
|
||||
{152, nullptr, "Unknown152"},
|
||||
{190, nullptr, "GetUserLastOpenedApplication"},
|
||||
{191, nullptr, "ActivateOpenContextHolder"},
|
||||
{997, nullptr, "DebugInvalidateTokenCacheForUser"},
|
||||
{998, nullptr, "DebugSetUserStateClose"},
|
||||
{999, nullptr, "DebugSetUserStateOpen"},
|
||||
};
|
||||
|
||||
@@ -231,6 +231,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
|
||||
{10, nullptr, "PerformSystemButtonPressing"},
|
||||
{20, nullptr, "InvalidateTransitionLayer"},
|
||||
{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
|
||||
{31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"},
|
||||
{40, nullptr, "GetAppletResourceUsageInfo"},
|
||||
{100, nullptr, "SetCpuBoostModeForApplet"},
|
||||
{101, nullptr, "CancelCpuBoostModeForApplet"},
|
||||
@@ -242,6 +243,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
|
||||
{130, nullptr, "FriendInvitationSetApplicationParameter"},
|
||||
{131, nullptr, "FriendInvitationClearApplicationParameter"},
|
||||
{132, nullptr, "FriendInvitationPushApplicationParameter"},
|
||||
{900, nullptr, "GetGrcProcessLaunchedSystemEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -295,8 +297,9 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
|
||||
{80, nullptr, "SetWirelessPriorityMode"},
|
||||
{90, &ISelfController::GetAccumulatedSuspendedTickValue, "GetAccumulatedSuspendedTickValue"},
|
||||
{91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
|
||||
{100, nullptr, "SetAlbumImageTakenNotificationEnabled"},
|
||||
{100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
|
||||
{110, nullptr, "SetApplicationAlbumUserData"},
|
||||
{120, nullptr, "SaveCurrentScreenshot"},
|
||||
{1000, nullptr, "GetDebugStorageChannel"},
|
||||
};
|
||||
// clang-format on
|
||||
@@ -560,6 +563,21 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
|
||||
rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent());
|
||||
}
|
||||
|
||||
void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
// This service call sets an internal flag whether a notification is shown when an image is
|
||||
// captured. Currently we do not support capturing images via the capture button, so this can be
|
||||
// stubbed for now.
|
||||
const bool album_image_taken_notification_enabled = rp.Pop<bool>();
|
||||
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called. album_image_taken_notification_enabled={}",
|
||||
album_image_taken_notification_enabled);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
|
||||
on_new_message = Kernel::KEvent::Create(kernel, "AMMessageQueue:OnMessageReceived");
|
||||
on_new_message->Initialize();
|
||||
@@ -630,6 +648,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
|
||||
{11, nullptr, "ReleaseSleepLock"},
|
||||
{12, nullptr, "ReleaseSleepLockTransiently"},
|
||||
{13, nullptr, "GetAcquiredSleepLockEvent"},
|
||||
{14, nullptr, "GetWakeupCount"},
|
||||
{20, nullptr, "PushToGeneralChannel"},
|
||||
{30, nullptr, "GetHomeButtonReaderLockAccessor"},
|
||||
{31, nullptr, "GetReaderLockAccessorEx"},
|
||||
@@ -641,6 +660,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
|
||||
{53, &ICommonStateGetter::BeginVrModeEx, "BeginVrModeEx"},
|
||||
{54, &ICommonStateGetter::EndVrModeEx, "EndVrModeEx"},
|
||||
{55, nullptr, "IsInControllerFirmwareUpdateSection"},
|
||||
{59, nullptr, "SetVrPositionForDebug"},
|
||||
{60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"},
|
||||
{61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"},
|
||||
{62, nullptr, "GetHdcpAuthenticationState"},
|
||||
@@ -649,14 +669,21 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
|
||||
{65, nullptr, "GetApplicationIdByContentActionName"},
|
||||
{66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
|
||||
{67, nullptr, "CancelCpuBoostMode"},
|
||||
{68, nullptr, "GetBuiltInDisplayType"},
|
||||
{80, nullptr, "PerformSystemButtonPressingIfInFocus"},
|
||||
{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
|
||||
{91, nullptr, "GetCurrentPerformanceConfiguration"},
|
||||
{100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
|
||||
{110, nullptr, "OpenMyGpuErrorHandler"},
|
||||
{200, nullptr, "GetOperationModeSystemInfo"},
|
||||
{300, nullptr, "GetSettingsPlatformRegion"},
|
||||
{400, nullptr, "ActivateMigrationService"},
|
||||
{401, nullptr, "DeactivateMigrationService"},
|
||||
{500, nullptr, "DisableSleepTillShutdown"},
|
||||
{501, nullptr, "SuppressDisablingSleepTemporarily"},
|
||||
{502, nullptr, "IsSleepEnabled"},
|
||||
{503, nullptr, "IsDisablingSleepSuppressed"},
|
||||
{900, nullptr, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -1188,11 +1215,14 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
{25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"},
|
||||
{26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"},
|
||||
{27, nullptr, "CreateCacheStorage"},
|
||||
{28, nullptr, "GetSaveDataSizeMax"},
|
||||
{29, nullptr, "GetCacheStorageMax"},
|
||||
{30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
|
||||
{31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
|
||||
{32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
|
||||
{33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
|
||||
{34, nullptr, "SelectApplicationLicense"},
|
||||
{35, nullptr, "GetDeviceSaveDataSizeMax"},
|
||||
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
|
||||
{50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
|
||||
{60, nullptr, "SetMediaPlaybackStateForApplication"},
|
||||
@@ -1216,6 +1246,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
{123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"},
|
||||
{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
|
||||
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
|
||||
{131, nullptr, "SetDelayTimeToAbortOnGpuError"},
|
||||
{140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
|
||||
{141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"},
|
||||
{150, nullptr, "GetNotificationStorageChannelEvent"},
|
||||
@@ -1224,6 +1255,8 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
{170, nullptr, "SetHdcpAuthenticationActivated"},
|
||||
{180, nullptr, "GetLaunchRequiredVersion"},
|
||||
{181, nullptr, "UpgradeLaunchRequiredVersion"},
|
||||
{190, nullptr, "SendServerMaintenanceOverlayNotification"},
|
||||
{200, nullptr, "GetLastApplicationExitReason"},
|
||||
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
|
||||
{1000, nullptr, "CreateMovieMaker"},
|
||||
{1001, nullptr, "PrepareForJit"},
|
||||
@@ -1690,9 +1723,12 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
|
||||
{21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"},
|
||||
{30, nullptr, "GetHomeButtonWriterLockAccessor"},
|
||||
{31, nullptr, "GetWriterLockAccessorEx"},
|
||||
{40, nullptr, "IsSleepEnabled"},
|
||||
{41, nullptr, "IsRebootEnabled"},
|
||||
{100, nullptr, "PopRequestLaunchApplicationForDebug"},
|
||||
{110, nullptr, "IsForceTerminateApplicationDisabledForDebug"},
|
||||
{200, nullptr, "LaunchDevMenu"},
|
||||
{1000, nullptr, "SetLastApplicationExitReason"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -1736,6 +1772,7 @@ IGlobalStateController::IGlobalStateController(Core::System& system_)
|
||||
{13, nullptr, "UpdateDefaultDisplayResolution"},
|
||||
{14, nullptr, "ShouldSleepOnBoot"},
|
||||
{15, nullptr, "GetHdcpAuthenticationFailedEvent"},
|
||||
{30, nullptr, "OpenCradleFirmwareUpdater"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ private:
|
||||
void IsAutoSleepDisabled(Kernel::HLERequestContext& ctx);
|
||||
void GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx);
|
||||
void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx);
|
||||
void SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx);
|
||||
|
||||
enum class ScreenshotPermission : u32 {
|
||||
Inherit = 0,
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace Service::Audio {
|
||||
AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendAudioIns"},
|
||||
{1, nullptr, "RequestResumeAudioIns"},
|
||||
{2, nullptr, "GetAudioInsProcessMasterVolume"},
|
||||
{3, nullptr, "SetAudioInsProcessMasterVolume"},
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -15,19 +15,19 @@ public:
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetAudioInState"},
|
||||
{1, nullptr, "StartAudioIn"},
|
||||
{2, nullptr, "StopAudioIn"},
|
||||
{1, nullptr, "Start"},
|
||||
{2, nullptr, "Stop"},
|
||||
{3, nullptr, "AppendAudioInBuffer"},
|
||||
{4, nullptr, "RegisterBufferEvent"},
|
||||
{5, nullptr, "GetReleasedAudioInBuffer"},
|
||||
{6, nullptr, "ContainsAudioInBuffer"},
|
||||
{7, nullptr, "AppendAudioInBufferWithUserEvent"},
|
||||
{7, nullptr, "AppendUacInBuffer"},
|
||||
{8, nullptr, "AppendAudioInBufferAuto"},
|
||||
{9, nullptr, "GetReleasedAudioInBufferAuto"},
|
||||
{10, nullptr, "AppendAudioInBufferWithUserEventAuto"},
|
||||
{9, nullptr, "GetReleasedAudioInBuffersAuto"},
|
||||
{10, nullptr, "AppendUacInBufferAuto"},
|
||||
{11, nullptr, "GetAudioInBufferCount"},
|
||||
{12, nullptr, "SetAudioInDeviceGain"},
|
||||
{13, nullptr, "GetAudioInDeviceGain"},
|
||||
{12, nullptr, "SetDeviceGain"},
|
||||
{13, nullptr, "GetDeviceGain"},
|
||||
{14, nullptr, "FlushAudioInBuffers"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -9,12 +9,12 @@ namespace Service::Audio {
|
||||
AudOutA::AudOutA(Core::System& system_) : ServiceFramework{system_, "audout:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendAudioOuts"},
|
||||
{1, nullptr, "RequestResumeAudioOuts"},
|
||||
{2, nullptr, "GetAudioOutsProcessMasterVolume"},
|
||||
{3, nullptr, "SetAudioOutsProcessMasterVolume"},
|
||||
{4, nullptr, "GetAudioOutsProcessRecordVolume"},
|
||||
{5, nullptr, "SetAudioOutsProcessRecordVolume"},
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
{4, nullptr, "GetProcessRecordVolume"},
|
||||
{5, nullptr, "SetProcessRecordVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -49,11 +49,11 @@ public:
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
|
||||
{1, &IAudioOut::StartAudioOut, "StartAudioOut"},
|
||||
{2, &IAudioOut::StopAudioOut, "StopAudioOut"},
|
||||
{1, &IAudioOut::StartAudioOut, "Start"},
|
||||
{2, &IAudioOut::StopAudioOut, "Stop"},
|
||||
{3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"},
|
||||
{4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
|
||||
{5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"},
|
||||
{5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffers"},
|
||||
{6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"},
|
||||
{7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"},
|
||||
{8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace Service::Audio {
|
||||
AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendFinalOutputRecorders"},
|
||||
{1, nullptr, "RequestResumeFinalOutputRecorders"},
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -13,16 +13,17 @@ public:
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetFinalOutputRecorderState"},
|
||||
{1, nullptr, "StartFinalOutputRecorder"},
|
||||
{2, nullptr, "StopFinalOutputRecorder"},
|
||||
{1, nullptr, "Start"},
|
||||
{2, nullptr, "Stop"},
|
||||
{3, nullptr, "AppendFinalOutputRecorderBuffer"},
|
||||
{4, nullptr, "RegisterBufferEvent"},
|
||||
{5, nullptr, "GetReleasedFinalOutputRecorderBuffer"},
|
||||
{5, nullptr, "GetReleasedFinalOutputRecorderBuffers"},
|
||||
{6, nullptr, "ContainsFinalOutputRecorderBuffer"},
|
||||
{7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
|
||||
{8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
|
||||
{9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
|
||||
{10, nullptr, "FlushFinalOutputRecorderBuffers"},
|
||||
{11, nullptr, "AttachWorkBuffer"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ namespace Service::Audio {
|
||||
AudRenA::AudRenA(Core::System& system_) : ServiceFramework{system_, "audren:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendAudioRenderers"},
|
||||
{1, nullptr, "RequestResumeAudioRenderers"},
|
||||
{2, nullptr, "GetAudioRenderersProcessMasterVolume"},
|
||||
{3, nullptr, "SetAudioRenderersProcessMasterVolume"},
|
||||
{0, nullptr, "RequestSuspend"},
|
||||
{1, nullptr, "RequestResume"},
|
||||
{2, nullptr, "GetProcessMasterVolume"},
|
||||
{3, nullptr, "SetProcessMasterVolume"},
|
||||
{4, nullptr, "RegisterAppletResourceUserId"},
|
||||
{5, nullptr, "UnregisterAppletResourceUserId"},
|
||||
{6, nullptr, "GetAudioRenderersProcessRecordVolume"},
|
||||
{7, nullptr, "SetAudioRenderersProcessRecordVolume"},
|
||||
{6, nullptr, "GetProcessRecordVolume"},
|
||||
{7, nullptr, "SetProcessRecordVolume"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -332,9 +332,9 @@ AudRenU::AudRenU(Core::System& system_) : ServiceFramework{system_, "audren:u"}
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
|
||||
{1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"},
|
||||
{1, &AudRenU::GetAudioRendererWorkBufferSize, "GetWorkBufferSize"},
|
||||
{2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"},
|
||||
{3, &AudRenU::OpenAudioRendererAuto, "OpenAudioRendererAuto"},
|
||||
{3, &AudRenU::OpenAudioRendererForManualExecution, "OpenAudioRendererForManualExecution"},
|
||||
{4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"},
|
||||
};
|
||||
// clang-format on
|
||||
@@ -665,7 +665,7 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
|
||||
rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1'));
|
||||
}
|
||||
|
||||
void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
|
||||
void AudRenU::OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
|
||||
OpenAudioRendererImpl(ctx);
|
||||
|
||||
@@ -25,7 +25,7 @@ private:
|
||||
void OpenAudioRenderer(Kernel::HLERequestContext& ctx);
|
||||
void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);
|
||||
void GetAudioDeviceService(Kernel::HLERequestContext& ctx);
|
||||
void OpenAudioRendererAuto(Kernel::HLERequestContext& ctx);
|
||||
void OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx);
|
||||
void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx);
|
||||
|
||||
void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx);
|
||||
|
||||
@@ -8,19 +8,19 @@ namespace Service::Audio {
|
||||
|
||||
CodecCtl::CodecCtl(Core::System& system_) : ServiceFramework{system_, "codecctl"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "InitializeCodecController"},
|
||||
{1, nullptr, "FinalizeCodecController"},
|
||||
{2, nullptr, "SleepCodecController"},
|
||||
{3, nullptr, "WakeCodecController"},
|
||||
{4, nullptr, "SetCodecVolume"},
|
||||
{5, nullptr, "GetCodecVolumeMax"},
|
||||
{6, nullptr, "GetCodecVolumeMin"},
|
||||
{7, nullptr, "SetCodecActiveTarget"},
|
||||
{8, nullptr, "GetCodecActiveTarget"},
|
||||
{9, nullptr, "BindCodecHeadphoneMicJackInterrupt"},
|
||||
{10, nullptr, "IsCodecHeadphoneMicJackInserted"},
|
||||
{11, nullptr, "ClearCodecHeadphoneMicJackInterrupt"},
|
||||
{12, nullptr, "IsCodecDeviceRequested"},
|
||||
{0, nullptr, "Initialize"},
|
||||
{1, nullptr, "Finalize"},
|
||||
{2, nullptr, "Sleep"},
|
||||
{3, nullptr, "Wake"},
|
||||
{4, nullptr, "SetVolume"},
|
||||
{5, nullptr, "GetVolumeMax"},
|
||||
{6, nullptr, "GetVolumeMin"},
|
||||
{7, nullptr, "SetActiveTarget"},
|
||||
{8, nullptr, "GetActiveTarget"},
|
||||
{9, nullptr, "BindHeadphoneMicJackInterrupt"},
|
||||
{10, nullptr, "IsHeadphoneMicJackInserted"},
|
||||
{11, nullptr, "ClearHeadphoneMicJackInterrupt"},
|
||||
{12, nullptr, "IsRequested"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -297,6 +297,10 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
|
||||
{1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
|
||||
{2, nullptr, "OpenOpusDecoderForMultiStream"},
|
||||
{3, nullptr, "GetWorkBufferSizeForMultiStream"},
|
||||
{4, nullptr, "OpenHardwareOpusDecoderEx"},
|
||||
{5, nullptr, "GetWorkBufferSizeEx"},
|
||||
{6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"},
|
||||
{7, nullptr, "GetWorkBufferSizeForMultiStreamEx"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -155,10 +155,12 @@ public:
|
||||
{30210, nullptr, "SetDeliveryTaskTimer"},
|
||||
{30300, nullptr, "RegisterSystemApplicationDeliveryTasks"},
|
||||
{90100, nullptr, "EnumerateBackgroundDeliveryTask"},
|
||||
{90101, nullptr, "Unknown90101"},
|
||||
{90200, nullptr, "GetDeliveryList"},
|
||||
{90201, &IBcatService::ClearDeliveryCacheStorage, "ClearDeliveryCacheStorage"},
|
||||
{90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
|
||||
{90300, nullptr, "GetPushNotificationLog"},
|
||||
{90301, nullptr, "Unknown90301"},
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -29,8 +29,8 @@ public:
|
||||
{11, nullptr, "CreateWakeupTimerEx"},
|
||||
{12, nullptr, "GetLastEnabledWakeupTimerType"},
|
||||
{13, nullptr, "CleanAllWakeupTimers"},
|
||||
{14, nullptr, "Unknown"},
|
||||
{15, nullptr, "Unknown2"},
|
||||
{14, nullptr, "GetPowerButton"},
|
||||
{15, nullptr, "SetEnableWakeupTimer"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ CAPS_A::CAPS_A(Core::System& system_) : ServiceFramework{system_, "caps:a"} {
|
||||
{16, nullptr, "GetAlbumMountResult"},
|
||||
{17, nullptr, "GetAlbumUsage16"},
|
||||
{18, nullptr, "Unknown18"},
|
||||
{19, nullptr, "Unknown19"},
|
||||
{100, nullptr, "GetAlbumFileCountEx0"},
|
||||
{101, nullptr, "GetAlbumFileListEx0"},
|
||||
{202, nullptr, "SaveEditedScreenShot"},
|
||||
|
||||
@@ -43,6 +43,7 @@ CAPS_U::CAPS_U(Core::System& system_) : ServiceFramework{system_, "caps:u"} {
|
||||
{141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"},
|
||||
{142, &CAPS_U::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"},
|
||||
{143, nullptr, "GetAlbumFileList4AaeUidAruid"},
|
||||
{144, nullptr, "GetAllAlbumFileList3AaeAruid"},
|
||||
{60002, nullptr, "OpenAccessorSessionForApplication"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -118,9 +118,13 @@ public:
|
||||
explicit IFile(Core::System& system_, FileSys::VirtualFile backend_)
|
||||
: ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
|
||||
{2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"},
|
||||
{4, &IFile::GetSize, "GetSize"}, {5, nullptr, "OperateRange"},
|
||||
{0, &IFile::Read, "Read"},
|
||||
{1, &IFile::Write, "Write"},
|
||||
{2, &IFile::Flush, "Flush"},
|
||||
{3, &IFile::SetSize, "SetSize"},
|
||||
{4, &IFile::GetSize, "GetSize"},
|
||||
{5, nullptr, "OperateRange"},
|
||||
{6, nullptr, "OperateRangeWithBuffer"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -708,7 +712,10 @@ FSP_SRV::FSP_SRV(Core::System& system_)
|
||||
{84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
|
||||
{85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"},
|
||||
{86, nullptr, "OpenSaveDataMover"},
|
||||
{87, nullptr, "OpenSaveDataTransferManagerForRepair"},
|
||||
{100, nullptr, "OpenImageDirectoryFileSystem"},
|
||||
{101, nullptr, "OpenBaseFileSystem"},
|
||||
{102, nullptr, "FormatBaseFileSystem"},
|
||||
{110, nullptr, "OpenContentStorageFileSystem"},
|
||||
{120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
|
||||
{130, nullptr, "OpenCustomStorageFileSystem"},
|
||||
@@ -764,10 +771,12 @@ FSP_SRV::FSP_SRV(Core::System& system_)
|
||||
{1008, nullptr, "OpenRegisteredUpdatePartition"},
|
||||
{1009, nullptr, "GetAndClearMemoryReportInfo"},
|
||||
{1010, nullptr, "SetDataStorageRedirectTarget"},
|
||||
{1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"},
|
||||
{1011, &FSP_SRV::GetProgramIndexForAccessLog, "GetProgramIndexForAccessLog"},
|
||||
{1012, nullptr, "GetFsStackUsage"},
|
||||
{1013, nullptr, "UnsetSaveDataRootPath"},
|
||||
{1014, nullptr, "OutputMultiProgramTagAccessLog"},
|
||||
{1016, nullptr, "FlushAccessLogOnSdCard"},
|
||||
{1017, nullptr, "OutputApplicationInfoAccessLog"},
|
||||
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
|
||||
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
|
||||
{1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"},
|
||||
@@ -1051,7 +1060,7 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
|
||||
void FSP_SRV::GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
||||
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
||||
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
|
||||
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
|
||||
void GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx);
|
||||
void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
|
||||
|
||||
FileSystemController& fsc;
|
||||
|
||||
@@ -133,7 +133,7 @@ private:
|
||||
void GetBlockedUserListIds(Kernel::HLERequestContext& ctx) {
|
||||
// This is safe to stub, as there should be no adverse consequences from reporting no
|
||||
// blocked users.
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Friend, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0); // Indicates there are no blocked users
|
||||
@@ -141,14 +141,14 @@ private:
|
||||
|
||||
void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) {
|
||||
// Stub used by Splatoon 2
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Friend, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void UpdateUserPresence(Kernel::HLERequestContext& ctx) {
|
||||
// Stub used by Retro City Rampage
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Friend, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -159,7 +159,7 @@ private:
|
||||
const auto uuid = rp.PopRaw<Common::UUID>();
|
||||
[[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>();
|
||||
const auto pid = rp.Pop<u64>();
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called, offset={}, uuid={}, pid={}", friend_offset,
|
||||
LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid={}, pid={}", friend_offset,
|
||||
uuid.Format(), pid);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
|
||||
private:
|
||||
void GetEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
LOG_DEBUG(Service_Friend, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -199,7 +199,7 @@ private:
|
||||
}
|
||||
|
||||
void Clear(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
LOG_DEBUG(Service_Friend, "called");
|
||||
while (!notifications.empty()) {
|
||||
notifications.pop();
|
||||
}
|
||||
@@ -210,10 +210,10 @@ private:
|
||||
}
|
||||
|
||||
void Pop(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
LOG_DEBUG(Service_Friend, "called");
|
||||
|
||||
if (notifications.empty()) {
|
||||
LOG_ERROR(Service_ACC, "No notifications in queue!");
|
||||
LOG_ERROR(Service_Friend, "No notifications in queue!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_NO_NOTIFICATIONS);
|
||||
return;
|
||||
@@ -231,7 +231,8 @@ private:
|
||||
break;
|
||||
default:
|
||||
// HOS seems not have an error case for an unknown notification
|
||||
LOG_WARNING(Service_ACC, "Unknown notification {:08X}", notification.notification_type);
|
||||
LOG_WARNING(Service_Friend, "Unknown notification {:08X}",
|
||||
notification.notification_type);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -269,14 +270,14 @@ void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IFriendService>(system);
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
LOG_DEBUG(Service_Friend, "called");
|
||||
}
|
||||
|
||||
void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
auto uuid = rp.PopRaw<Common::UUID>();
|
||||
|
||||
LOG_DEBUG(Service_ACC, "called, uuid={}", uuid.Format());
|
||||
LOG_DEBUG(Service_Friend, "called, uuid={}", uuid.Format());
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
@@ -41,6 +41,12 @@ ARP_R::ARP_R(Core::System& system_, const ARPManager& manager_)
|
||||
{1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"},
|
||||
{2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"},
|
||||
{3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"},
|
||||
{4, nullptr, "GetApplicationInstanceUnregistrationNotifier"},
|
||||
{5, nullptr, "ListApplicationInstanceId"},
|
||||
{6, nullptr, "GetMicroApplicationInstanceId"},
|
||||
{7, nullptr, "GetApplicationCertificate"},
|
||||
{9998, nullptr, "GetPreomiaApplicationLaunchProperty"},
|
||||
{9999, nullptr, "GetPreomiaApplicationControlProperty"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -243,7 +249,8 @@ ARP_W::ARP_W(Core::System& system_, ARPManager& manager_)
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
|
||||
{1, &ARP_W::DeleteProperties, "DeleteProperties"},
|
||||
{1, &ARP_W::UnregisterApplicationInstance , "UnregisterApplicationInstance "},
|
||||
{2, nullptr, "AcquireUpdater"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -270,7 +277,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) {
|
||||
rb.PushIpcInterface(registrar);
|
||||
}
|
||||
|
||||
void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) {
|
||||
void ARP_W::UnregisterApplicationInstance(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto process_id = rp.PopRaw<u64>();
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
|
||||
private:
|
||||
void AcquireRegistrar(Kernel::HLERequestContext& ctx);
|
||||
void DeleteProperties(Kernel::HLERequestContext& ctx);
|
||||
void UnregisterApplicationInstance(Kernel::HLERequestContext& ctx);
|
||||
|
||||
ARPManager& manager;
|
||||
std::shared_ptr<IRegistrar> registrar;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "core/hle/service/hid/controllers/gesture.h"
|
||||
@@ -19,9 +20,9 @@ Controller_Gesture::~Controller_Gesture() = default;
|
||||
|
||||
void Controller_Gesture::OnInit() {
|
||||
for (std::size_t id = 0; id < MAX_FINGERS; ++id) {
|
||||
mouse_finger_id[id] = MAX_FINGERS;
|
||||
keyboard_finger_id[id] = MAX_FINGERS;
|
||||
udp_finger_id[id] = MAX_FINGERS;
|
||||
mouse_finger_id[id] = MAX_POINTS;
|
||||
keyboard_finger_id[id] = MAX_POINTS;
|
||||
udp_finger_id[id] = MAX_POINTS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +143,10 @@ std::optional<std::size_t> Controller_Gesture::GetUnusedFingerID() const {
|
||||
std::size_t Controller_Gesture::UpdateTouchInputEvent(
|
||||
const std::tuple<float, float, bool>& touch_input, std::size_t finger_id) {
|
||||
const auto& [x, y, pressed] = touch_input;
|
||||
if (finger_id > MAX_POINTS) {
|
||||
LOG_ERROR(Service_HID, "Invalid finger id {}", finger_id);
|
||||
return MAX_POINTS;
|
||||
}
|
||||
if (pressed) {
|
||||
if (finger_id == MAX_POINTS) {
|
||||
const auto first_free_id = GetUnusedFingerID();
|
||||
|
||||
@@ -413,12 +413,16 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
|
||||
lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
|
||||
}
|
||||
|
||||
if (controller_type == NPadControllerType::JoyLeft ||
|
||||
controller_type == NPadControllerType::JoyRight) {
|
||||
if (controller_type == NPadControllerType::JoyLeft) {
|
||||
pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus());
|
||||
}
|
||||
|
||||
if (controller_type == NPadControllerType::JoyRight) {
|
||||
pad_state.right_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad_state.right_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus());
|
||||
}
|
||||
|
||||
if (controller_type == NPadControllerType::GameCube) {
|
||||
trigger_entry.l_analog = static_cast<s32>(
|
||||
button_state[ZL - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "core/frontend/input.h"
|
||||
@@ -118,6 +119,10 @@ std::optional<std::size_t> Controller_Touchscreen::GetUnusedFingerID() const {
|
||||
std::size_t Controller_Touchscreen::UpdateTouchInputEvent(
|
||||
const std::tuple<float, float, bool>& touch_input, std::size_t finger_id) {
|
||||
const auto& [x, y, pressed] = touch_input;
|
||||
if (finger_id > MAX_FINGERS) {
|
||||
LOG_ERROR(Service_HID, "Invalid finger id {}", finger_id);
|
||||
return MAX_FINGERS;
|
||||
}
|
||||
if (pressed) {
|
||||
Attributes attribute{};
|
||||
if (finger_id == MAX_FINGERS) {
|
||||
|
||||
@@ -118,9 +118,9 @@ public:
|
||||
explicit DebugMonitor(Core::System& system_) : ServiceFramework{system_, "ldr:dmnt"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "AddProcessToDebugLaunchQueue"},
|
||||
{1, nullptr, "ClearDebugLaunchQueue"},
|
||||
{2, nullptr, "GetNsoInfos"},
|
||||
{0, nullptr, "SetProgramArgument"},
|
||||
{1, nullptr, "FlushArguments"},
|
||||
{2, nullptr, "GetProcessModuleInfo"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -135,8 +135,8 @@ public:
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateProcess"},
|
||||
{1, nullptr, "GetProgramInfo"},
|
||||
{2, nullptr, "RegisterTitle"},
|
||||
{3, nullptr, "UnregisterTitle"},
|
||||
{2, nullptr, "PinProgram"},
|
||||
{3, nullptr, "UnpinProgram"},
|
||||
{4, nullptr, "SetEnabledProgramVerification"},
|
||||
};
|
||||
// clang-format on
|
||||
@@ -150,8 +150,8 @@ public:
|
||||
explicit Shell(Core::System& system_) : ServiceFramework{system_, "ldr:shel"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "AddProcessToLaunchQueue"},
|
||||
{1, nullptr, "ClearLaunchQueue"},
|
||||
{0, nullptr, "SetProgramArgument"},
|
||||
{1, nullptr, "FlushArguments"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -164,19 +164,19 @@ public:
|
||||
explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &RelocatableObject::LoadNro, "LoadNro"},
|
||||
{1, &RelocatableObject::UnloadNro, "UnloadNro"},
|
||||
{2, &RelocatableObject::LoadNrr, "LoadNrr"},
|
||||
{3, &RelocatableObject::UnloadNrr, "UnloadNrr"},
|
||||
{0, &RelocatableObject::LoadModule, "LoadModule"},
|
||||
{1, &RelocatableObject::UnloadModule, "UnloadModule"},
|
||||
{2, &RelocatableObject::RegisterModuleInfo, "RegisterModuleInfo"},
|
||||
{3, &RelocatableObject::UnregisterModuleInfo, "UnregisterModuleInfo"},
|
||||
{4, &RelocatableObject::Initialize, "Initialize"},
|
||||
{10, nullptr, "LoadNrrEx"},
|
||||
{10, nullptr, "RegisterModuleInfo2"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
void LoadNrr(Kernel::HLERequestContext& ctx) {
|
||||
void RegisterModuleInfo(Kernel::HLERequestContext& ctx) {
|
||||
struct Parameters {
|
||||
u64_le process_id;
|
||||
u64_le nrr_address;
|
||||
@@ -273,7 +273,7 @@ public:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void UnloadNrr(Kernel::HLERequestContext& ctx) {
|
||||
void UnregisterModuleInfo(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto pid = rp.Pop<u64>();
|
||||
const auto nrr_address = rp.Pop<VAddr>();
|
||||
@@ -408,7 +408,7 @@ public:
|
||||
data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite);
|
||||
}
|
||||
|
||||
void LoadNro(Kernel::HLERequestContext& ctx) {
|
||||
void LoadModule(Kernel::HLERequestContext& ctx) {
|
||||
struct Parameters {
|
||||
u64_le process_id;
|
||||
u64_le image_address;
|
||||
@@ -546,7 +546,7 @@ public:
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void UnloadNro(Kernel::HLERequestContext& ctx) {
|
||||
void UnloadModule(Kernel::HLERequestContext& ctx) {
|
||||
if (!initialized) {
|
||||
LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
|
||||
@@ -154,6 +154,10 @@ PL_U::PL_U(Core::System& system_)
|
||||
{100, nullptr, "RequestApplicationFunctionAuthorization"},
|
||||
{101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"},
|
||||
{102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"},
|
||||
{103, nullptr, "RefreshApplicationFunctionBlackListDebugRecord"},
|
||||
{104, nullptr, "RequestApplicationFunctionAuthorizationByProgramId"},
|
||||
{105, nullptr, "GetFunctionBlackListSystemVersionToAuthorize"},
|
||||
{106, nullptr, "GetFunctionBlackListVersion"},
|
||||
{1000, nullptr, "LoadNgWordDataForPlatformRegionChina"},
|
||||
{1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"},
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
* @param output A buffer where the output data will be written to.
|
||||
* @returns The result code of the ioctl.
|
||||
*/
|
||||
virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
virtual NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) = 0;
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
* @param output A buffer where the output data will be written to.
|
||||
* @returns The result code of the ioctl.
|
||||
*/
|
||||
virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
virtual NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) = 0;
|
||||
|
||||
/**
|
||||
@@ -53,8 +53,20 @@ public:
|
||||
* @param inline_output A buffer where the inlined output data will be written to.
|
||||
* @returns The result code of the ioctl.
|
||||
*/
|
||||
virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) = 0;
|
||||
virtual NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) = 0;
|
||||
|
||||
/**
|
||||
* Called once a device is openned
|
||||
* @param fd The device fd
|
||||
*/
|
||||
virtual void OnOpen(DeviceFD fd) = 0;
|
||||
|
||||
/**
|
||||
* Called once a device is closed
|
||||
* @param fd The device fd
|
||||
*/
|
||||
virtual void OnClose(DeviceFD fd) = 0;
|
||||
|
||||
protected:
|
||||
Core::System& system;
|
||||
|
||||
@@ -18,24 +18,27 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de
|
||||
: nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
|
||||
nvdisp_disp0 ::~nvdisp_disp0() = default;
|
||||
|
||||
NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvdisp_disp0::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) {
|
||||
NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvdisp_disp0::OnOpen(DeviceFD fd) {}
|
||||
void nvdisp_disp0::OnClose(DeviceFD fd) {}
|
||||
|
||||
void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height,
|
||||
u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform,
|
||||
const Common::Rectangle<int>& crop_rect) {
|
||||
|
||||
@@ -20,11 +20,15 @@ public:
|
||||
explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
|
||||
~nvdisp_disp0() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
|
||||
/// Performs a screen flip, drawing the buffer pointed to by the handle.
|
||||
void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,
|
||||
|
||||
@@ -21,7 +21,7 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_
|
||||
: nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
|
||||
nvhost_as_gpu::~nvhost_as_gpu() = default;
|
||||
|
||||
NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 'A':
|
||||
@@ -39,7 +39,7 @@ NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
case 0x8:
|
||||
return GetVARegions(input, output);
|
||||
case 0x9:
|
||||
return InitalizeEx(input, output);
|
||||
return AllocAsEx(input, output);
|
||||
case 0x14:
|
||||
return Remap(input, output);
|
||||
default:
|
||||
@@ -54,14 +54,14 @@ NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_as_gpu::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) {
|
||||
NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
switch (command.group) {
|
||||
case 'A':
|
||||
switch (command.cmd) {
|
||||
@@ -78,11 +78,19 @@ NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std:
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlInitalizeEx params{};
|
||||
void nvhost_as_gpu::OnOpen(DeviceFD fd) {}
|
||||
void nvhost_as_gpu::OnClose(DeviceFD fd) {}
|
||||
|
||||
NvResult nvhost_as_gpu::AllocAsEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlAllocAsEx params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x{:X}", params.big_page_size);
|
||||
if (params.big_page_size == 0) {
|
||||
params.big_page_size = DEFAULT_BIG_PAGE_SIZE;
|
||||
}
|
||||
|
||||
big_page_size = params.big_page_size;
|
||||
|
||||
return NvResult::Success;
|
||||
}
|
||||
@@ -276,13 +284,18 @@ NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u
|
||||
params.buf_size);
|
||||
|
||||
params.buf_size = 0x30;
|
||||
params.regions[0].offset = 0x04000000;
|
||||
params.regions[0].page_size = 0x1000;
|
||||
params.regions[0].pages = 0x3fbfff;
|
||||
|
||||
params.regions[1].offset = 0x04000000;
|
||||
params.regions[1].page_size = 0x10000;
|
||||
params.regions[1].pages = 0x1bffff;
|
||||
params.small = IoctlVaRegion{
|
||||
.offset = 0x04000000,
|
||||
.page_size = DEFAULT_SMALL_PAGE_SIZE,
|
||||
.pages = 0x3fbfff,
|
||||
};
|
||||
|
||||
params.big = IoctlVaRegion{
|
||||
.offset = 0x04000000,
|
||||
.page_size = big_page_size,
|
||||
.pages = 0x1bffff,
|
||||
};
|
||||
|
||||
// TODO(ogniK): This probably can stay stubbed but should add support way way later
|
||||
|
||||
@@ -299,18 +312,25 @@ NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u
|
||||
params.buf_size);
|
||||
|
||||
params.buf_size = 0x30;
|
||||
params.regions[0].offset = 0x04000000;
|
||||
params.regions[0].page_size = 0x1000;
|
||||
params.regions[0].pages = 0x3fbfff;
|
||||
|
||||
params.regions[1].offset = 0x04000000;
|
||||
params.regions[1].page_size = 0x10000;
|
||||
params.regions[1].pages = 0x1bffff;
|
||||
params.small = IoctlVaRegion{
|
||||
.offset = 0x04000000,
|
||||
.page_size = 0x1000,
|
||||
.pages = 0x3fbfff,
|
||||
};
|
||||
|
||||
params.big = IoctlVaRegion{
|
||||
.offset = 0x04000000,
|
||||
.page_size = big_page_size,
|
||||
.pages = 0x1bffff,
|
||||
};
|
||||
|
||||
// TODO(ogniK): This probably can stay stubbed but should add support way way later
|
||||
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
std::memcpy(inline_output.data(), ¶ms.regions, inline_output.size());
|
||||
std::memcpy(inline_output.data(), ¶ms.small, sizeof(IoctlVaRegion));
|
||||
std::memcpy(inline_output.data() + sizeof(IoctlVaRegion), ¶ms.big, sizeof(IoctlVaRegion));
|
||||
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
namespace Service::Nvidia::Devices {
|
||||
|
||||
constexpr u32 DEFAULT_BIG_PAGE_SIZE = 1 << 16;
|
||||
constexpr u32 DEFAULT_SMALL_PAGE_SIZE = 1 << 12;
|
||||
|
||||
class nvmap;
|
||||
|
||||
enum class AddressSpaceFlags : u32 {
|
||||
@@ -30,11 +33,15 @@ public:
|
||||
explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
|
||||
~nvhost_as_gpu() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
|
||||
private:
|
||||
class BufferMap final {
|
||||
@@ -76,16 +83,16 @@ private:
|
||||
bool is_allocated{};
|
||||
};
|
||||
|
||||
struct IoctlInitalizeEx {
|
||||
u32_le big_page_size{}; // depends on GPU's available_big_page_sizes; 0=default
|
||||
s32_le as_fd{}; // ignored; passes 0
|
||||
u32_le flags{}; // passes 0
|
||||
u32_le reserved{}; // ignored; passes 0
|
||||
u64_le unk0{};
|
||||
u64_le unk1{};
|
||||
u64_le unk2{};
|
||||
struct IoctlAllocAsEx {
|
||||
u32_le flags{}; // usually passes 1
|
||||
s32_le as_fd{}; // ignored; passes 0
|
||||
u32_le big_page_size{};
|
||||
u32_le reserved{}; // ignored; passes 0
|
||||
u64_le va_range_start{};
|
||||
u64_le va_range_end{};
|
||||
u64_le va_range_split{};
|
||||
};
|
||||
static_assert(sizeof(IoctlInitalizeEx) == 40, "IoctlInitalizeEx is incorrect size");
|
||||
static_assert(sizeof(IoctlAllocAsEx) == 40, "IoctlAllocAsEx is incorrect size");
|
||||
|
||||
struct IoctlAllocSpace {
|
||||
u32_le pages{};
|
||||
@@ -149,14 +156,16 @@ private:
|
||||
u64_le buf_addr{}; // (contained output user ptr on linux, ignored)
|
||||
u32_le buf_size{}; // forced to 2*sizeof(struct va_region)
|
||||
u32_le reserved{};
|
||||
IoctlVaRegion regions[2]{};
|
||||
IoctlVaRegion small{};
|
||||
IoctlVaRegion big{};
|
||||
};
|
||||
static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(IoctlVaRegion) * 2,
|
||||
"IoctlGetVaRegions is incorrect size");
|
||||
|
||||
s32 channel{};
|
||||
u32 big_page_size{DEFAULT_BIG_PAGE_SIZE};
|
||||
|
||||
NvResult InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
NvResult AllocAsEx(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
NvResult AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
NvResult Remap(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
NvResult MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
|
||||
@@ -20,7 +20,8 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface,
|
||||
: nvdevice(system), events_interface{events_interface}, syncpoint_manager{syncpoint_manager} {}
|
||||
nvhost_ctrl::~nvhost_ctrl() = default;
|
||||
|
||||
NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 0x0:
|
||||
switch (command.cmd) {
|
||||
@@ -46,18 +47,21 @@ NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::v
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_ctrl::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_outpu) {
|
||||
NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_outpu) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvhost_ctrl::OnOpen(DeviceFD fd) {}
|
||||
void nvhost_ctrl::OnClose(DeviceFD fd) {}
|
||||
|
||||
NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IocGetConfigParams params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(params));
|
||||
|
||||
@@ -18,11 +18,15 @@ public:
|
||||
SyncpointManager& syncpoint_manager);
|
||||
~nvhost_ctrl() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
|
||||
private:
|
||||
struct IocSyncptReadParams {
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Service::Nvidia::Devices {
|
||||
nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {}
|
||||
nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
|
||||
|
||||
NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 'G':
|
||||
@@ -47,13 +47,13 @@ NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_ctrl_gpu::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
switch (command.group) {
|
||||
case 'G':
|
||||
@@ -73,6 +73,9 @@ NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input,
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {}
|
||||
void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {}
|
||||
|
||||
NvResult nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
@@ -245,7 +248,13 @@ NvResult nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<
|
||||
IoctlZbcSetTable params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
// TODO(ogniK): What does this even actually do?
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
|
||||
// Prevent null pointer being passed as arg 1
|
||||
if (output.empty()) {
|
||||
LOG_WARNING(Service_NVDRV, "Avoiding passing null pointer to memcpy");
|
||||
} else {
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
}
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,15 @@ public:
|
||||
explicit nvhost_ctrl_gpu(Core::System& system);
|
||||
~nvhost_ctrl_gpu() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
|
||||
private:
|
||||
struct IoctlGpuCharacteristics {
|
||||
|
||||
@@ -23,7 +23,8 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev,
|
||||
|
||||
nvhost_gpu::~nvhost_gpu() = default;
|
||||
|
||||
NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 0x0:
|
||||
switch (command.cmd) {
|
||||
@@ -74,7 +75,7 @@ NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
|
||||
return NvResult::NotImplemented;
|
||||
};
|
||||
|
||||
NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 'H':
|
||||
@@ -88,12 +89,15 @@ NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) {
|
||||
NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvhost_gpu::OnOpen(DeviceFD fd) {}
|
||||
void nvhost_gpu::OnClose(DeviceFD fd) {}
|
||||
|
||||
NvResult nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSetNvmapFD params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
|
||||
@@ -26,11 +26,15 @@ public:
|
||||
SyncpointManager& syncpoint_manager);
|
||||
~nvhost_gpu() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
|
||||
private:
|
||||
enum class CtxObjects : u32_le {
|
||||
|
||||
@@ -16,7 +16,7 @@ nvhost_nvdec::nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_de
|
||||
: nvhost_nvdec_common(system, std::move(nvmap_dev), syncpoint_manager) {}
|
||||
nvhost_nvdec::~nvhost_nvdec() = default;
|
||||
|
||||
NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 0x0:
|
||||
@@ -57,16 +57,19 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_nvdec::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) {
|
||||
NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvhost_nvdec::OnOpen(DeviceFD fd) {}
|
||||
void nvhost_nvdec::OnClose(DeviceFD fd) {}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -15,11 +15,15 @@ public:
|
||||
SyncpointManager& syncpoint_manager);
|
||||
~nvhost_nvdec() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
};
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -23,17 +23,22 @@ namespace {
|
||||
template <typename T>
|
||||
std::size_t SpliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count,
|
||||
std::size_t offset) {
|
||||
std::memcpy(dst.data(), input.data() + offset, count * sizeof(T));
|
||||
offset += count * sizeof(T);
|
||||
return offset;
|
||||
if (!dst.empty()) {
|
||||
std::memcpy(dst.data(), input.data() + offset, count * sizeof(T));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write vectors will write data to the output buffer
|
||||
template <typename T>
|
||||
std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) {
|
||||
std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T));
|
||||
offset += src.size() * sizeof(T);
|
||||
return offset;
|
||||
if (src.empty()) {
|
||||
return 0;
|
||||
} else {
|
||||
std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T));
|
||||
offset += src.size() * sizeof(T);
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
|
||||
nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {}
|
||||
nvhost_nvjpg::~nvhost_nvjpg() = default;
|
||||
|
||||
NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 'H':
|
||||
@@ -32,18 +32,21 @@ NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input,
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_nvjpg::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) {
|
||||
NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvhost_nvjpg::OnOpen(DeviceFD fd) {}
|
||||
void nvhost_nvjpg::OnClose(DeviceFD fd) {}
|
||||
|
||||
NvResult nvhost_nvjpg::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSetNvmapFD params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
|
||||
@@ -16,11 +16,15 @@ public:
|
||||
explicit nvhost_nvjpg(Core::System& system);
|
||||
~nvhost_nvjpg() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
|
||||
private:
|
||||
struct IoctlSetNvmapFD {
|
||||
|
||||
@@ -16,7 +16,8 @@ nvhost_vic::nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev,
|
||||
|
||||
nvhost_vic::~nvhost_vic() = default;
|
||||
|
||||
NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 0x0:
|
||||
switch (command.cmd) {
|
||||
@@ -55,16 +56,19 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvhost_vic::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) {
|
||||
NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvhost_vic::OnOpen(DeviceFD fd) {}
|
||||
void nvhost_vic::OnClose(DeviceFD fd) {}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -14,10 +14,14 @@ public:
|
||||
SyncpointManager& syncpoint_manager);
|
||||
~nvhost_vic();
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
};
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -19,7 +19,8 @@ nvmap::nvmap(Core::System& system) : nvdevice(system) {
|
||||
|
||||
nvmap::~nvmap() = default;
|
||||
|
||||
NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) {
|
||||
switch (command.group) {
|
||||
case 0x1:
|
||||
switch (command.cmd) {
|
||||
@@ -47,18 +48,21 @@ NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult nvmap::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) {
|
||||
NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) {
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
void nvmap::OnOpen(DeviceFD fd) {}
|
||||
void nvmap::OnClose(DeviceFD fd) {}
|
||||
|
||||
VAddr nvmap::GetObjectAddress(u32 handle) const {
|
||||
auto object = GetObject(handle);
|
||||
ASSERT(object);
|
||||
|
||||
@@ -19,11 +19,15 @@ public:
|
||||
explicit nvmap(Core::System& system);
|
||||
~nvmap() override;
|
||||
|
||||
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
|
||||
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output) override;
|
||||
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
const std::vector<u8>& inline_input, std::vector<u8>& output) override;
|
||||
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
std::vector<u8>& inline_output) override;
|
||||
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
std::vector<u8>& output, std::vector<u8>& inline_output) override;
|
||||
|
||||
void OnOpen(DeviceFD fd) override;
|
||||
void OnClose(DeviceFD fd) override;
|
||||
|
||||
/// Returns the allocated address of an nvmap object given its handle.
|
||||
VAddr GetObjectAddress(u32 handle) const;
|
||||
|
||||
@@ -89,6 +89,8 @@ DeviceFD Module::Open(const std::string& device_name) {
|
||||
auto device = devices[device_name];
|
||||
const DeviceFD fd = next_fd++;
|
||||
|
||||
device->OnOpen(fd);
|
||||
|
||||
open_files[fd] = std::move(device);
|
||||
|
||||
return fd;
|
||||
@@ -108,7 +110,7 @@ NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
return itr->second->Ioctl1(command, input, output);
|
||||
return itr->second->Ioctl1(fd, command, input, output);
|
||||
}
|
||||
|
||||
NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
@@ -125,7 +127,7 @@ NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
return itr->second->Ioctl2(command, input, inline_input, output);
|
||||
return itr->second->Ioctl2(fd, command, input, inline_input, output);
|
||||
}
|
||||
|
||||
NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
|
||||
@@ -142,7 +144,7 @@ NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
return itr->second->Ioctl3(command, input, output, inline_output);
|
||||
return itr->second->Ioctl3(fd, command, input, output, inline_output);
|
||||
}
|
||||
|
||||
NvResult Module::Close(DeviceFD fd) {
|
||||
@@ -158,6 +160,8 @@ NvResult Module::Close(DeviceFD fd) {
|
||||
return NvResult::NotImplemented;
|
||||
}
|
||||
|
||||
itr->second->OnClose(fd);
|
||||
|
||||
open_files.erase(itr);
|
||||
|
||||
return NvResult::Success;
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
{22, nullptr, "DeleteSaveDataBackupAsync"},
|
||||
{25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
|
||||
{26, nullptr, "DownloadSaveDataBackupAsync"},
|
||||
{27, nullptr, "UploadSaveDataBackupAsync"},
|
||||
{9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
|
||||
{9013, nullptr, "GetSaveDataBackupSettingForDebug"},
|
||||
{9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
{19, nullptr, "SetIrqEnable"},
|
||||
{20, nullptr, "SetAspmEnable"},
|
||||
{21, nullptr, "SetResetUponResumeEnable"},
|
||||
{22, nullptr, "Unknown22"},
|
||||
{22, nullptr, "ResetFunction"},
|
||||
{23, nullptr, "Unknown23"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
{1046, nullptr, "DisableFeaturesForReset"},
|
||||
{1047, nullptr, "NotifyApplicationDownloadStarted"},
|
||||
{1048, nullptr, "NotifyNetworkProfileCreated"},
|
||||
{1049, nullptr, "ResetFreeCommunicationApplicationList"},
|
||||
{1061, &IParentalControlService::ConfirmStereoVisionRestrictionConfigurable, "ConfirmStereoVisionRestrictionConfigurable"},
|
||||
{1062, &IParentalControlService::GetStereoVisionRestriction, "GetStereoVisionRestriction"},
|
||||
{1063, &IParentalControlService::SetStereoVisionRestriction, "SetStereoVisionRestriction"},
|
||||
@@ -69,6 +70,8 @@ public:
|
||||
{1421, nullptr, "GetAccountNickname"},
|
||||
{1424, nullptr, "GetAccountState"},
|
||||
{1425, nullptr, "RequestPostEvents"},
|
||||
{1426, nullptr, "GetPostEventInterval"},
|
||||
{1427, nullptr, "SetPostEventInterval"},
|
||||
{1432, nullptr, "GetSynchronizationEvent"},
|
||||
{1451, nullptr, "StartPlayTimer"},
|
||||
{1452, nullptr, "StopPlayTimer"},
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#include "core/hle/service/vi/vi.h"
|
||||
#include "core/hle/service/wlan/wlan.h"
|
||||
#include "core/reporter.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service {
|
||||
|
||||
@@ -146,6 +147,11 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
|
||||
system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name,
|
||||
service_name);
|
||||
UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf));
|
||||
if (Settings::values.use_auto_stub) {
|
||||
LOG_WARNING(Service, "Using auto stub fallback!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -261,6 +261,10 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
|
||||
{155, nullptr, "SetAccountOnlineStorageSettings"},
|
||||
{156, nullptr, "GetPctlReadyFlag"},
|
||||
{157, nullptr, "SetPctlReadyFlag"},
|
||||
{158, nullptr, "GetAnalogStickUserCalibrationL"},
|
||||
{159, nullptr, "SetAnalogStickUserCalibrationL"},
|
||||
{160, nullptr, "GetAnalogStickUserCalibrationR"},
|
||||
{161, nullptr, "SetAnalogStickUserCalibrationR"},
|
||||
{162, nullptr, "GetPtmBatteryVersion"},
|
||||
{163, nullptr, "SetPtmBatteryVersion"},
|
||||
{164, nullptr, "GetUsb30HostEnableFlag"},
|
||||
@@ -302,6 +306,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
|
||||
{200, nullptr, "SetButtonConfigRegisteredSettings"},
|
||||
{201, nullptr, "GetFieldTestingFlag"},
|
||||
{202, nullptr, "SetFieldTestingFlag"},
|
||||
{203, nullptr, "GetPanelCrcMode"},
|
||||
{204, nullptr, "SetPanelCrcMode"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -190,10 +190,11 @@ SM::SM(std::shared_ptr<ServiceManager> service_manager_, Core::System& system_)
|
||||
: ServiceFramework{system_, "sm:", 4},
|
||||
service_manager{std::move(service_manager_)}, kernel{system_.Kernel()} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &SM::Initialize, "Initialize"},
|
||||
{0x00000001, &SM::GetService, "GetService"},
|
||||
{0x00000002, &SM::RegisterService, "RegisterService"},
|
||||
{0x00000003, &SM::UnregisterService, "UnregisterService"},
|
||||
{0, &SM::Initialize, "Initialize"},
|
||||
{1, &SM::GetService, "GetService"},
|
||||
{2, &SM::RegisterService, "RegisterService"},
|
||||
{3, &SM::UnregisterService, "UnregisterService"},
|
||||
{4, nullptr, "DetachClient"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ ETHC_C::ETHC_C(Core::System& system_) : ServiceFramework{system_, "ethc:c"} {
|
||||
{3, nullptr, "GetMediaList"},
|
||||
{4, nullptr, "SetMediaType"},
|
||||
{5, nullptr, "GetMediaType"},
|
||||
{6, nullptr, "Unknown6"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Service::Sockets {
|
||||
NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{5, nullptr, "GetSettingUrl"},
|
||||
{10, nullptr, "GetSettingName"},
|
||||
{11, nullptr, "GetEnvironmentIdentifier"},
|
||||
{12, nullptr, "GetDeviceId"},
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace Service::Sockets {
|
||||
|
||||
SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "SetDnsAddressesPrivate"},
|
||||
{1, nullptr, "GetDnsAddressPrivate"},
|
||||
{0, nullptr, "SetDnsAddressesPrivateRequest"},
|
||||
{1, nullptr, "GetDnsAddressPrivateRequest"},
|
||||
{2, nullptr, "GetHostByNameRequest"},
|
||||
{3, nullptr, "GetHostByAddrRequest"},
|
||||
{4, nullptr, "GetHostStringErrorRequest"},
|
||||
|
||||
@@ -60,6 +60,8 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
{4, nullptr, "GenerateAesKey"},
|
||||
{5, nullptr, "SetConfig"},
|
||||
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
|
||||
{9, nullptr, "ImportLotusKey"},
|
||||
{10, nullptr, "DecryptLotusMessage"},
|
||||
{11, nullptr, "IsDevelopment"},
|
||||
{12, nullptr, "GenerateSpecificAesKey"},
|
||||
{14, nullptr, "DecryptAesKey"},
|
||||
@@ -123,6 +125,7 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
{14, nullptr, "DecryptAesKey"},
|
||||
{15, nullptr, "CryptAesCtr"},
|
||||
{16, nullptr, "ComputeCmac"},
|
||||
{17, nullptr, "ImportEsKey"},
|
||||
{18, nullptr, "UnwrapTitleKey"},
|
||||
{20, nullptr, "PrepareEsCommonKey"},
|
||||
{21, nullptr, "AllocateAesKeyslot"},
|
||||
|
||||
@@ -20,6 +20,7 @@ ITimeZoneService ::ITimeZoneService(Core::System& system_,
|
||||
{3, nullptr, "LoadLocationNameList"},
|
||||
{4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"},
|
||||
{5, nullptr, "GetTimeZoneRuleVersion"},
|
||||
{6, nullptr, "GetDeviceLocationNameAndUpdatedTime"},
|
||||
{100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
|
||||
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
|
||||
{201, &ITimeZoneService::ToPosixTime, "ToPosixTime"},
|
||||
|
||||
@@ -69,15 +69,15 @@ public:
|
||||
: ServiceFramework{system_, "IClientEpSession"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Open"},
|
||||
{0, nullptr, "ReOpen"},
|
||||
{1, nullptr, "Close"},
|
||||
{2, nullptr, "Unknown2"},
|
||||
{3, nullptr, "Populate"},
|
||||
{2, nullptr, "GetCompletionEvent"},
|
||||
{3, nullptr, "PopulateRing"},
|
||||
{4, nullptr, "PostBufferAsync"},
|
||||
{5, nullptr, "GetXferReport"},
|
||||
{6, nullptr, "PostBufferMultiAsync"},
|
||||
{7, nullptr, "Unknown7"},
|
||||
{8, nullptr, "Unknown8"},
|
||||
{7, nullptr, "CreateSmmuSpace"},
|
||||
{8, nullptr, "ShareReportRing"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
: ServiceFramework{system_, "IClientIfSession"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Unknown0"},
|
||||
{0, nullptr, "GetStateChangeEvent"},
|
||||
{1, nullptr, "SetInterface"},
|
||||
{2, nullptr, "GetInterface"},
|
||||
{3, nullptr, "GetAlternateInterface"},
|
||||
@@ -176,15 +176,15 @@ public:
|
||||
: ServiceFramework{system_, "IPdCradleSession"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "VdmUserWrite"},
|
||||
{1, nullptr, "VdmUserRead"},
|
||||
{2, nullptr, "Vdm20Init"},
|
||||
{3, nullptr, "GetFwType"},
|
||||
{4, nullptr, "GetFwRevision"},
|
||||
{5, nullptr, "GetManufacturerId"},
|
||||
{6, nullptr, "GetDeviceId"},
|
||||
{7, nullptr, "Unknown7"},
|
||||
{8, nullptr, "Unknown8"},
|
||||
{0, nullptr, "SetCradleVdo"},
|
||||
{1, nullptr, "GetCradleVdo"},
|
||||
{2, nullptr, "ResetCradleUsbHub"},
|
||||
{3, nullptr, "GetHostPdcFirmwareType"},
|
||||
{4, nullptr, "GetHostPdcFirmwareRevision"},
|
||||
{5, nullptr, "GetHostPdcManufactureId"},
|
||||
{6, nullptr, "GetHostPdcDeviceId"},
|
||||
{7, nullptr, "AwakeCradle"},
|
||||
{8, nullptr, "SleepCradle"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -219,12 +219,12 @@ public:
|
||||
explicit USB_PM(Core::System& system_) : ServiceFramework{system_, "usb:pm"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Unknown0"},
|
||||
{1, nullptr, "Unknown1"},
|
||||
{2, nullptr, "Unknown2"},
|
||||
{3, nullptr, "Unknown3"},
|
||||
{4, nullptr, "Unknown4"},
|
||||
{5, nullptr, "Unknown5"},
|
||||
{0, nullptr, "GetPowerEvent"},
|
||||
{1, nullptr, "GetPowerState"},
|
||||
{2, nullptr, "GetDataEvent"},
|
||||
{3, nullptr, "GetDataRole"},
|
||||
{4, nullptr, "SetDiagData"},
|
||||
{5, nullptr, "GetDiagData"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -46,6 +46,13 @@ public:
|
||||
{28, nullptr, "Unknown28"},
|
||||
{29, nullptr, "Unknown29"},
|
||||
{30, nullptr, "Unknown30"},
|
||||
{31, nullptr, "Unknown31"},
|
||||
{32, nullptr, "Unknown32"},
|
||||
{33, nullptr, "Unknown33"},
|
||||
{34, nullptr, "Unknown34"},
|
||||
{35, nullptr, "Unknown35"},
|
||||
{36, nullptr, "Unknown36"},
|
||||
{37, nullptr, "Unknown37"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ struct Values {
|
||||
bool quest_flag;
|
||||
bool disable_macro_jit;
|
||||
bool extended_logging;
|
||||
bool use_auto_stub;
|
||||
|
||||
// Miscellaneous
|
||||
std::string log_filter;
|
||||
|
||||
@@ -27,11 +27,9 @@ class Socket {
|
||||
public:
|
||||
using clock = std::chrono::system_clock;
|
||||
|
||||
explicit Socket(const std::string& host, u16 port, std::size_t pad_index_,
|
||||
SocketCallback callback_)
|
||||
explicit Socket(const std::string& host, u16 port, SocketCallback callback_)
|
||||
: callback(std::move(callback_)), timer(io_service),
|
||||
socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(GenerateRandomClientId()),
|
||||
pad_index(pad_index_) {
|
||||
socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(GenerateRandomClientId()) {
|
||||
boost::system::error_code ec{};
|
||||
auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
|
||||
if (ec.value() != boost::system::errc::success) {
|
||||
@@ -99,15 +97,15 @@ private:
|
||||
void HandleSend(const boost::system::error_code&) {
|
||||
boost::system::error_code _ignored{};
|
||||
// Send a request for getting port info for the pad
|
||||
const Request::PortInfo port_info{1, {static_cast<u8>(pad_index), 0, 0, 0}};
|
||||
const Request::PortInfo port_info{4, {0, 1, 2, 3}};
|
||||
const auto port_message = Request::Create(port_info, client_id);
|
||||
std::memcpy(&send_buffer1, &port_message, PORT_INFO_SIZE);
|
||||
socket.send_to(boost::asio::buffer(send_buffer1), send_endpoint, {}, _ignored);
|
||||
|
||||
// Send a request for getting pad data for the pad
|
||||
const Request::PadData pad_data{
|
||||
Request::PadData::Flags::Id,
|
||||
static_cast<u8>(pad_index),
|
||||
Request::PadData::Flags::AllPorts,
|
||||
0,
|
||||
EMPTY_MAC_ADDRESS,
|
||||
};
|
||||
const auto pad_message = Request::Create(pad_data, client_id);
|
||||
@@ -122,7 +120,6 @@ private:
|
||||
udp::socket socket;
|
||||
|
||||
const u32 client_id;
|
||||
std::size_t pad_index{};
|
||||
|
||||
static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>);
|
||||
static constexpr std::size_t PAD_DATA_SIZE = sizeof(Message<Request::PadData>);
|
||||
@@ -150,34 +147,32 @@ Client::~Client() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
Client::ClientData::ClientData() = default;
|
||||
Client::ClientConnection::ClientConnection() = default;
|
||||
|
||||
Client::ClientData::~ClientData() = default;
|
||||
Client::ClientConnection::~ClientConnection() = default;
|
||||
|
||||
std::vector<Common::ParamPackage> Client::GetInputDevices() const {
|
||||
std::vector<Common::ParamPackage> devices;
|
||||
for (std::size_t client = 0; client < clients.size(); client++) {
|
||||
if (!DeviceConnected(client)) {
|
||||
for (std::size_t pad = 0; pad < pads.size(); pad++) {
|
||||
if (!DeviceConnected(pad)) {
|
||||
continue;
|
||||
}
|
||||
std::string name = fmt::format("UDP Controller {}", client);
|
||||
std::string name = fmt::format("UDP Controller {}", pad);
|
||||
devices.emplace_back(Common::ParamPackage{
|
||||
{"class", "cemuhookudp"},
|
||||
{"display", std::move(name)},
|
||||
{"port", std::to_string(client)},
|
||||
{"port", std::to_string(pad)},
|
||||
});
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
bool Client::DeviceConnected(std::size_t client) const {
|
||||
bool Client::DeviceConnected(std::size_t pad) const {
|
||||
// Use last timestamp to detect if the socket has stopped sending data
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
const auto time_difference =
|
||||
static_cast<u64>(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now - clients[client].last_motion_update)
|
||||
.count());
|
||||
return time_difference < 1000 && clients[client].active == 1;
|
||||
const auto time_difference = static_cast<u64>(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now - pads[pad].last_update).count());
|
||||
return time_difference < 1000 && pads[pad].connected;
|
||||
}
|
||||
|
||||
void Client::ReloadSockets() {
|
||||
@@ -202,25 +197,21 @@ void Client::ReloadSockets() {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (std::size_t pad = 0; pad < 4; ++pad) {
|
||||
const std::size_t client_number =
|
||||
GetClientNumber(udp_input_address, udp_input_port, pad);
|
||||
if (client_number != MAX_UDP_CLIENTS) {
|
||||
LOG_ERROR(Input, "Duplicated UDP servers found");
|
||||
continue;
|
||||
}
|
||||
StartCommunication(client++, udp_input_address, udp_input_port, pad);
|
||||
const std::size_t client_number = GetClientNumber(udp_input_address, udp_input_port);
|
||||
if (client_number != MAX_UDP_CLIENTS) {
|
||||
LOG_ERROR(Input, "Duplicated UDP servers found");
|
||||
continue;
|
||||
}
|
||||
StartCommunication(client++, udp_input_address, udp_input_port);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t Client::GetClientNumber(std::string_view host, u16 port, std::size_t pad) const {
|
||||
std::size_t Client::GetClientNumber(std::string_view host, u16 port) const {
|
||||
for (std::size_t client = 0; client < clients.size(); client++) {
|
||||
if (clients[client].active == -1) {
|
||||
continue;
|
||||
}
|
||||
if (clients[client].host == host && clients[client].port == port &&
|
||||
clients[client].pad_index == pad) {
|
||||
if (clients[client].host == host && clients[client].port == port) {
|
||||
return client;
|
||||
}
|
||||
}
|
||||
@@ -236,69 +227,75 @@ void Client::OnPortInfo([[maybe_unused]] Response::PortInfo data) {
|
||||
}
|
||||
|
||||
void Client::OnPadData(Response::PadData data, std::size_t client) {
|
||||
// Accept packets only for the correct pad
|
||||
if (static_cast<u8>(clients[client].pad_index) != data.info.id) {
|
||||
const std::size_t pad_index = (client * PADS_PER_CLIENT) + data.info.id;
|
||||
|
||||
if (pad_index >= pads.size()) {
|
||||
LOG_ERROR(Input, "Invalid pad id {}", data.info.id);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_TRACE(Input, "PadData packet received");
|
||||
if (data.packet_counter == clients[client].packet_sequence) {
|
||||
if (data.packet_counter == pads[pad_index].packet_sequence) {
|
||||
LOG_WARNING(
|
||||
Input,
|
||||
"PadData packet dropped because its stale info. Current count: {} Packet count: {}",
|
||||
clients[client].packet_sequence, data.packet_counter);
|
||||
pads[pad_index].packet_sequence, data.packet_counter);
|
||||
pads[pad_index].connected = false;
|
||||
return;
|
||||
}
|
||||
clients[client].active = static_cast<s8>(data.info.is_pad_active);
|
||||
clients[client].packet_sequence = data.packet_counter;
|
||||
|
||||
clients[client].active = 1;
|
||||
pads[pad_index].connected = true;
|
||||
pads[pad_index].packet_sequence = data.packet_counter;
|
||||
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
const auto time_difference =
|
||||
static_cast<u64>(std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
now - clients[client].last_motion_update)
|
||||
.count());
|
||||
clients[client].last_motion_update = now;
|
||||
const auto time_difference = static_cast<u64>(
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(now - pads[pad_index].last_update)
|
||||
.count());
|
||||
pads[pad_index].last_update = now;
|
||||
|
||||
const Common::Vec3f raw_gyroscope = {data.gyro.pitch, data.gyro.roll, -data.gyro.yaw};
|
||||
clients[client].motion.SetAcceleration({data.accel.x, -data.accel.z, data.accel.y});
|
||||
pads[pad_index].motion.SetAcceleration({data.accel.x, -data.accel.z, data.accel.y});
|
||||
// Gyroscope values are not it the correct scale from better joy.
|
||||
// Dividing by 312 allows us to make one full turn = 1 turn
|
||||
// This must be a configurable valued called sensitivity
|
||||
clients[client].motion.SetGyroscope(raw_gyroscope / 312.0f);
|
||||
clients[client].motion.UpdateRotation(time_difference);
|
||||
clients[client].motion.UpdateOrientation(time_difference);
|
||||
pads[pad_index].motion.SetGyroscope(raw_gyroscope / 312.0f);
|
||||
pads[pad_index].motion.UpdateRotation(time_difference);
|
||||
pads[pad_index].motion.UpdateOrientation(time_difference);
|
||||
|
||||
{
|
||||
std::lock_guard guard(clients[client].status.update_mutex);
|
||||
clients[client].status.motion_status = clients[client].motion.GetMotion();
|
||||
std::lock_guard guard(pads[pad_index].status.update_mutex);
|
||||
pads[pad_index].status.motion_status = pads[pad_index].motion.GetMotion();
|
||||
|
||||
for (std::size_t id = 0; id < data.touch.size(); ++id) {
|
||||
UpdateTouchInput(data.touch[id], client, id);
|
||||
}
|
||||
|
||||
if (configuring) {
|
||||
const Common::Vec3f gyroscope = clients[client].motion.GetGyroscope();
|
||||
const Common::Vec3f accelerometer = clients[client].motion.GetAcceleration();
|
||||
UpdateYuzuSettings(client, accelerometer, gyroscope);
|
||||
const Common::Vec3f gyroscope = pads[pad_index].motion.GetGyroscope();
|
||||
const Common::Vec3f accelerometer = pads[pad_index].motion.GetAcceleration();
|
||||
UpdateYuzuSettings(client, data.info.id, accelerometer, gyroscope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::StartCommunication(std::size_t client, const std::string& host, u16 port,
|
||||
std::size_t pad_index) {
|
||||
void Client::StartCommunication(std::size_t client, const std::string& host, u16 port) {
|
||||
SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
|
||||
[this](Response::PortInfo info) { OnPortInfo(info); },
|
||||
[this, client](Response::PadData data) { OnPadData(data, client); }};
|
||||
LOG_INFO(Input, "Starting communication with UDP input server on {}:{}:{}", host, port,
|
||||
pad_index);
|
||||
LOG_INFO(Input, "Starting communication with UDP input server on {}:{}", host, port);
|
||||
clients[client].host = host;
|
||||
clients[client].port = port;
|
||||
clients[client].pad_index = pad_index;
|
||||
clients[client].active = 0;
|
||||
clients[client].socket = std::make_unique<Socket>(host, port, pad_index, callback);
|
||||
clients[client].socket = std::make_unique<Socket>(host, port, callback);
|
||||
clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
|
||||
|
||||
// Set motion parameters
|
||||
// SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
|
||||
// Real HW values are unknown, 0.0001 is an approximate to Standard
|
||||
clients[client].motion.SetGyroThreshold(0.0001f);
|
||||
for (std::size_t pad = 0; pad < PADS_PER_CLIENT; pad++) {
|
||||
pads[client * PADS_PER_CLIENT + pad].motion.SetGyroThreshold(0.0001f);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::Reset() {
|
||||
@@ -311,8 +308,8 @@ void Client::Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
|
||||
const Common::Vec3<float>& gyro) {
|
||||
void Client::UpdateYuzuSettings(std::size_t client, std::size_t pad_index,
|
||||
const Common::Vec3<float>& acc, const Common::Vec3<float>& gyro) {
|
||||
if (gyro.Length() > 0.2f) {
|
||||
LOG_DEBUG(Input, "UDP Controller {}: gyro=({}, {}, {}), accel=({}, {}, {})", client,
|
||||
gyro[0], gyro[1], gyro[2], acc[0], acc[1], acc[2]);
|
||||
@@ -320,7 +317,7 @@ void Client::UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& a
|
||||
UDPPadStatus pad{
|
||||
.host = clients[client].host,
|
||||
.port = clients[client].port,
|
||||
.pad_index = clients[client].pad_index,
|
||||
.pad_index = pad_index,
|
||||
};
|
||||
for (std::size_t i = 0; i < 3; ++i) {
|
||||
if (gyro[i] > 5.0f || gyro[i] < -5.0f) {
|
||||
@@ -391,19 +388,19 @@ void Client::EndConfiguration() {
|
||||
}
|
||||
|
||||
DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) {
|
||||
const std::size_t client_number = GetClientNumber(host, port, pad);
|
||||
if (client_number == MAX_UDP_CLIENTS) {
|
||||
return clients[0].status;
|
||||
const std::size_t client_number = GetClientNumber(host, port);
|
||||
if (client_number == MAX_UDP_CLIENTS || pad >= PADS_PER_CLIENT) {
|
||||
return pads[0].status;
|
||||
}
|
||||
return clients[client_number].status;
|
||||
return pads[(client_number * PADS_PER_CLIENT) + pad].status;
|
||||
}
|
||||
|
||||
const DeviceStatus& Client::GetPadState(const std::string& host, u16 port, std::size_t pad) const {
|
||||
const std::size_t client_number = GetClientNumber(host, port, pad);
|
||||
if (client_number == MAX_UDP_CLIENTS) {
|
||||
return clients[0].status;
|
||||
const std::size_t client_number = GetClientNumber(host, port);
|
||||
if (client_number == MAX_UDP_CLIENTS || pad >= PADS_PER_CLIENT) {
|
||||
return pads[0].status;
|
||||
}
|
||||
return clients[client_number].status;
|
||||
return pads[(client_number * PADS_PER_CLIENT) + pad].status;
|
||||
}
|
||||
|
||||
Input::TouchStatus& Client::GetTouchState() {
|
||||
@@ -422,7 +419,7 @@ const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const {
|
||||
return pad_queue;
|
||||
}
|
||||
|
||||
void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
|
||||
void TestCommunication(const std::string& host, u16 port,
|
||||
const std::function<void()>& success_callback,
|
||||
const std::function<void()>& failure_callback) {
|
||||
std::thread([=] {
|
||||
@@ -432,9 +429,10 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
|
||||
.port_info = [](Response::PortInfo) {},
|
||||
.pad_data = [&](Response::PadData) { success_event.Set(); },
|
||||
};
|
||||
Socket socket{host, port, pad_index, std::move(callback)};
|
||||
Socket socket{host, port, std::move(callback)};
|
||||
std::thread worker_thread{SocketLoop, &socket};
|
||||
const bool result = success_event.WaitFor(std::chrono::seconds(5));
|
||||
const bool result =
|
||||
success_event.WaitUntil(std::chrono::steady_clock::now() + std::chrono::seconds(10));
|
||||
socket.Stop();
|
||||
worker_thread.join();
|
||||
if (result) {
|
||||
@@ -446,8 +444,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
|
||||
}
|
||||
|
||||
CalibrationConfigurationJob::CalibrationConfigurationJob(
|
||||
const std::string& host, u16 port, std::size_t pad_index,
|
||||
std::function<void(Status)> status_callback,
|
||||
const std::string& host, u16 port, std::function<void(Status)> status_callback,
|
||||
std::function<void(u16, u16, u16, u16)> data_callback) {
|
||||
|
||||
std::thread([=, this] {
|
||||
@@ -491,7 +488,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
|
||||
complete_event.Set();
|
||||
}
|
||||
}};
|
||||
Socket socket{host, port, pad_index, std::move(callback)};
|
||||
Socket socket{host, port, std::move(callback)};
|
||||
std::thread worker_thread{SocketLoop, &socket};
|
||||
complete_event.Wait();
|
||||
socket.Stop();
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
|
||||
std::vector<Common::ParamPackage> GetInputDevices() const;
|
||||
|
||||
bool DeviceConnected(std::size_t client) const;
|
||||
bool DeviceConnected(std::size_t pad) const;
|
||||
void ReloadSockets();
|
||||
|
||||
Common::SPSCQueue<UDPPadStatus>& GetPadQueue();
|
||||
@@ -97,38 +97,40 @@ public:
|
||||
const Input::TouchStatus& GetTouchState() const;
|
||||
|
||||
private:
|
||||
struct ClientData {
|
||||
ClientData();
|
||||
~ClientData();
|
||||
|
||||
std::string host{"127.0.0.1"};
|
||||
u16 port{26760};
|
||||
struct PadData {
|
||||
std::size_t pad_index{};
|
||||
std::unique_ptr<Socket> socket;
|
||||
bool connected{};
|
||||
DeviceStatus status;
|
||||
std::thread thread;
|
||||
u64 packet_sequence{};
|
||||
s8 active{-1};
|
||||
|
||||
// Realtime values
|
||||
// motion is initalized with PID values for drift correction on joycons
|
||||
InputCommon::MotionInput motion{0.3f, 0.005f, 0.0f};
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_motion_update;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update;
|
||||
};
|
||||
|
||||
struct ClientConnection {
|
||||
ClientConnection();
|
||||
~ClientConnection();
|
||||
std::string host{"127.0.0.1"};
|
||||
u16 port{26760};
|
||||
s8 active{-1};
|
||||
std::unique_ptr<Socket> socket;
|
||||
std::thread thread;
|
||||
};
|
||||
|
||||
// For shutting down, clear all data, join all threads, release usb
|
||||
void Reset();
|
||||
|
||||
// Translates configuration to client number
|
||||
std::size_t GetClientNumber(std::string_view host, u16 port, std::size_t pad) const;
|
||||
std::size_t GetClientNumber(std::string_view host, u16 port) const;
|
||||
|
||||
void OnVersion(Response::Version);
|
||||
void OnPortInfo(Response::PortInfo);
|
||||
void OnPadData(Response::PadData, std::size_t client);
|
||||
void StartCommunication(std::size_t client, const std::string& host, u16 port,
|
||||
std::size_t pad_index);
|
||||
void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
|
||||
const Common::Vec3<float>& gyro);
|
||||
void StartCommunication(std::size_t client, const std::string& host, u16 port);
|
||||
void UpdateYuzuSettings(std::size_t client, std::size_t pad_index,
|
||||
const Common::Vec3<float>& acc, const Common::Vec3<float>& gyro);
|
||||
|
||||
// Returns an unused finger id, if there is no fingers available std::nullopt will be
|
||||
// returned
|
||||
@@ -140,10 +142,12 @@ private:
|
||||
bool configuring = false;
|
||||
|
||||
// Allocate clients for 8 udp servers
|
||||
static constexpr std::size_t MAX_UDP_CLIENTS = 4 * 8;
|
||||
static constexpr std::size_t MAX_UDP_CLIENTS = 8;
|
||||
static constexpr std::size_t PADS_PER_CLIENT = 4;
|
||||
// Each client can have up 2 touch inputs
|
||||
static constexpr std::size_t MAX_TOUCH_FINGERS = MAX_UDP_CLIENTS * 2;
|
||||
std::array<ClientData, MAX_UDP_CLIENTS> clients{};
|
||||
std::array<PadData, MAX_UDP_CLIENTS * PADS_PER_CLIENT> pads{};
|
||||
std::array<ClientConnection, MAX_UDP_CLIENTS> clients{};
|
||||
Common::SPSCQueue<UDPPadStatus> pad_queue{};
|
||||
Input::TouchStatus touch_status{};
|
||||
std::array<std::size_t, MAX_TOUCH_FINGERS> finger_id{};
|
||||
@@ -164,7 +168,7 @@ public:
|
||||
* @param status_callback Callback for job status updates
|
||||
* @param data_callback Called when calibration data is ready
|
||||
*/
|
||||
explicit CalibrationConfigurationJob(const std::string& host, u16 port, std::size_t pad_index,
|
||||
explicit CalibrationConfigurationJob(const std::string& host, u16 port,
|
||||
std::function<void(Status)> status_callback,
|
||||
std::function<void(u16, u16, u16, u16)> data_callback);
|
||||
~CalibrationConfigurationJob();
|
||||
@@ -174,7 +178,7 @@ private:
|
||||
Common::Event complete_event;
|
||||
};
|
||||
|
||||
void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
|
||||
void TestCommunication(const std::string& host, u16 port,
|
||||
const std::function<void()>& success_callback,
|
||||
const std::function<void()>& failure_callback);
|
||||
|
||||
|
||||
@@ -236,7 +236,6 @@ add_library(video_core STATIC
|
||||
texture_cache/types.h
|
||||
texture_cache/util.cpp
|
||||
texture_cache/util.h
|
||||
textures/astc.cpp
|
||||
textures/astc.h
|
||||
textures/decoders.cpp
|
||||
textures/decoders.h
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring> // for std::memcpy
|
||||
#include <algorithm> // for std::copy
|
||||
#include <numeric>
|
||||
#include "common/assert.h"
|
||||
#include "video_core/command_classes/codecs/vp9.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/memory_manager.h"
|
||||
@@ -362,7 +363,8 @@ Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state)
|
||||
// surface_luma_offset[0:3] contains the address of the reference frame offsets in the following
|
||||
// order: last, golden, altref, current. It may be worthwhile to track the updates done here
|
||||
// to avoid buffering frame data needed for reference frame updating in the header composition.
|
||||
std::memcpy(vp9_info.frame_offsets.data(), state.surface_luma_offset.data(), 4 * sizeof(u64));
|
||||
std::copy(state.surface_luma_offset.begin(), state.surface_luma_offset.begin() + 4,
|
||||
vp9_info.frame_offsets.begin());
|
||||
|
||||
return vp9_info;
|
||||
}
|
||||
@@ -821,11 +823,11 @@ const std::vector<u8>& VP9::ComposeFrameHeader(const NvdecCommon::NvdecRegisters
|
||||
|
||||
// Write headers and frame to buffer
|
||||
frame.resize(uncompressed_header.size() + compressed_header.size() + bitstream.size());
|
||||
std::memcpy(frame.data(), uncompressed_header.data(), uncompressed_header.size());
|
||||
std::memcpy(frame.data() + uncompressed_header.size(), compressed_header.data(),
|
||||
compressed_header.size());
|
||||
std::memcpy(frame.data() + uncompressed_header.size() + compressed_header.size(),
|
||||
bitstream.data(), bitstream.size());
|
||||
std::copy(uncompressed_header.begin(), uncompressed_header.end(), frame.begin());
|
||||
std::copy(compressed_header.begin(), compressed_header.end(),
|
||||
frame.begin() + uncompressed_header.size());
|
||||
std::copy(bitstream.begin(), bitstream.end(),
|
||||
frame.begin() + uncompressed_header.size() + compressed_header.size());
|
||||
|
||||
// keep track of frame number
|
||||
current_frame_number++;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
set(SHADER_FILES
|
||||
astc_decoder.comp
|
||||
block_linear_unswizzle_2d.comp
|
||||
block_linear_unswizzle_3d.comp
|
||||
convert_depth_to_float.frag
|
||||
|
||||
@@ -6,7 +6,27 @@ get_filename_component(CONTENTS_NAME ${SOURCE_FILE} NAME)
|
||||
string(REPLACE "." "_" CONTENTS_NAME ${CONTENTS_NAME})
|
||||
string(TOUPPER ${CONTENTS_NAME} CONTENTS_NAME)
|
||||
|
||||
file(READ ${SOURCE_FILE} CONTENTS)
|
||||
FILE(READ ${SOURCE_FILE} line_contents)
|
||||
|
||||
# Replace double quotes with single quotes,
|
||||
# as double quotes will be used to wrap the lines
|
||||
STRING(REGEX REPLACE "\"" "'" line_contents "${line_contents}")
|
||||
|
||||
# CMake separates list elements with semicolons, but semicolons
|
||||
# are used extensively in the shader code.
|
||||
# Replace with a temporary marker, to be reverted later.
|
||||
STRING(REGEX REPLACE ";" "{{SEMICOLON}}" line_contents "${line_contents}")
|
||||
|
||||
# Make every line an individual element in the CMake list.
|
||||
STRING(REGEX REPLACE "\n" ";" line_contents "${line_contents}")
|
||||
|
||||
# Build the shader string, wrapping each line in double quotes.
|
||||
foreach(line IN LISTS line_contents)
|
||||
string(CONCAT CONTENTS "${CONTENTS}" \"${line}\\n\"\n)
|
||||
endforeach()
|
||||
|
||||
# Revert the original semicolons in the source.
|
||||
STRING(REGEX REPLACE "{{SEMICOLON}}" ";" CONTENTS "${CONTENTS}")
|
||||
|
||||
get_filename_component(OUTPUT_DIR ${HEADER_FILE} DIRECTORY)
|
||||
make_directory(${OUTPUT_DIR})
|
||||
|
||||
1339
src/video_core/host_shaders/astc_decoder.comp
Normal file
1339
src/video_core/host_shaders/astc_decoder.comp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,8 @@
|
||||
|
||||
namespace HostShaders {
|
||||
|
||||
constexpr std::string_view @CONTENTS_NAME@ = R"(@CONTENTS@)";
|
||||
constexpr std::string_view @CONTENTS_NAME@ = {
|
||||
@CONTENTS@
|
||||
};
|
||||
|
||||
} // namespace HostShaders
|
||||
|
||||
@@ -307,7 +307,8 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
|
||||
|
||||
[[nodiscard]] bool CanBeAccelerated(const TextureCacheRuntime& runtime,
|
||||
const VideoCommon::ImageInfo& info) {
|
||||
// Disable accelerated uploads for now as they don't implement swizzled uploads
|
||||
return !runtime.HasNativeASTC() && IsPixelFormatASTC(info.format);
|
||||
// Disable other accelerated uploads for now as they don't implement swizzled uploads
|
||||
return false;
|
||||
switch (info.type) {
|
||||
case ImageType::e2D:
|
||||
@@ -569,7 +570,11 @@ void TextureCacheRuntime::AccelerateImageUpload(Image& image, const ImageBufferM
|
||||
std::span<const SwizzleParameters> swizzles) {
|
||||
switch (image.info.type) {
|
||||
case ImageType::e2D:
|
||||
return util_shaders.BlockLinearUpload2D(image, map, swizzles);
|
||||
if (IsPixelFormatASTC(image.info.format)) {
|
||||
return util_shaders.ASTCDecode(image, map, swizzles);
|
||||
} else {
|
||||
return util_shaders.BlockLinearUpload2D(image, map, swizzles);
|
||||
}
|
||||
case ImageType::e3D:
|
||||
return util_shaders.BlockLinearUpload3D(image, map, swizzles);
|
||||
case ImageType::Linear:
|
||||
@@ -599,6 +604,10 @@ FormatProperties TextureCacheRuntime::FormatInfo(ImageType type, GLenum internal
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureCacheRuntime::HasNativeASTC() const noexcept {
|
||||
return device.HasASTC();
|
||||
}
|
||||
|
||||
TextureCacheRuntime::StagingBuffers::StagingBuffers(GLenum storage_flags_, GLenum map_flags_)
|
||||
: storage_flags{storage_flags_}, map_flags{map_flags_} {}
|
||||
|
||||
|
||||
@@ -95,6 +95,8 @@ public:
|
||||
return has_broken_texture_view_formats;
|
||||
}
|
||||
|
||||
bool HasNativeASTC() const noexcept;
|
||||
|
||||
private:
|
||||
struct StagingBuffers {
|
||||
explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <bit>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
|
||||
@@ -11,6 +10,7 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/div_ceil.h"
|
||||
#include "video_core/host_shaders/astc_decoder_comp.h"
|
||||
#include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h"
|
||||
#include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h"
|
||||
#include "video_core/host_shaders/opengl_copy_bc4_comp.h"
|
||||
@@ -20,16 +20,18 @@
|
||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||
#include "video_core/renderer_opengl/gl_texture_cache.h"
|
||||
#include "video_core/renderer_opengl/util_shaders.h"
|
||||
#include "video_core/surface.h"
|
||||
#include "video_core/texture_cache/accelerated_swizzle.h"
|
||||
#include "video_core/texture_cache/types.h"
|
||||
#include "video_core/texture_cache/util.h"
|
||||
#include "video_core/textures/astc.h"
|
||||
#include "video_core/textures/decoders.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
using namespace HostShaders;
|
||||
using namespace Tegra::Texture::ASTC;
|
||||
|
||||
using VideoCommon::Extent2D;
|
||||
using VideoCommon::Extent3D;
|
||||
using VideoCommon::ImageCopy;
|
||||
using VideoCommon::ImageType;
|
||||
@@ -57,7 +59,7 @@ size_t NumPixelsInCopy(const VideoCommon::ImageCopy& copy) {
|
||||
} // Anonymous namespace
|
||||
|
||||
UtilShaders::UtilShaders(ProgramManager& program_manager_)
|
||||
: program_manager{program_manager_},
|
||||
: program_manager{program_manager_}, astc_decoder_program(MakeProgram(ASTC_DECODER_COMP)),
|
||||
block_linear_unswizzle_2d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_2D_COMP)),
|
||||
block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
|
||||
pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)),
|
||||
@@ -65,11 +67,79 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
|
||||
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)) {
|
||||
const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
|
||||
swizzle_table_buffer.Create();
|
||||
astc_buffer.Create();
|
||||
glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
|
||||
glNamedBufferStorage(astc_buffer.handle, sizeof(ASTC_BUFFER_DATA), &ASTC_BUFFER_DATA, 0);
|
||||
}
|
||||
|
||||
UtilShaders::~UtilShaders() = default;
|
||||
|
||||
void UtilShaders::ASTCDecode(Image& image, const ImageBufferMap& map,
|
||||
std::span<const VideoCommon::SwizzleParameters> swizzles) {
|
||||
static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0;
|
||||
static constexpr GLuint BINDING_INPUT_BUFFER = 1;
|
||||
static constexpr GLuint BINDING_ENC_BUFFER = 2;
|
||||
|
||||
static constexpr GLuint BINDING_6_TO_8_BUFFER = 3;
|
||||
static constexpr GLuint BINDING_7_TO_8_BUFFER = 4;
|
||||
static constexpr GLuint BINDING_8_TO_8_BUFFER = 5;
|
||||
static constexpr GLuint BINDING_BYTE_TO_16_BUFFER = 6;
|
||||
|
||||
static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
|
||||
|
||||
const Extent2D tile_size{
|
||||
.width = VideoCore::Surface::DefaultBlockWidth(image.info.format),
|
||||
.height = VideoCore::Surface::DefaultBlockHeight(image.info.format),
|
||||
};
|
||||
program_manager.BindHostCompute(astc_decoder_program.handle);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle);
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_ENC_BUFFER, astc_buffer.handle,
|
||||
offsetof(AstcBufferData, encoding_values),
|
||||
sizeof(AstcBufferData::encoding_values));
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_6_TO_8_BUFFER, astc_buffer.handle,
|
||||
offsetof(AstcBufferData, replicate_6_to_8),
|
||||
sizeof(AstcBufferData::replicate_6_to_8));
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_7_TO_8_BUFFER, astc_buffer.handle,
|
||||
offsetof(AstcBufferData, replicate_7_to_8),
|
||||
sizeof(AstcBufferData::replicate_7_to_8));
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_8_TO_8_BUFFER, astc_buffer.handle,
|
||||
offsetof(AstcBufferData, replicate_8_to_8),
|
||||
sizeof(AstcBufferData::replicate_8_to_8));
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_BYTE_TO_16_BUFFER, astc_buffer.handle,
|
||||
offsetof(AstcBufferData, replicate_byte_to_16),
|
||||
sizeof(AstcBufferData::replicate_byte_to_16));
|
||||
|
||||
glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes);
|
||||
glUniform2ui(1, tile_size.width, tile_size.height);
|
||||
// Ensure buffer data is valid before dispatching
|
||||
glFlush();
|
||||
for (const SwizzleParameters& swizzle : swizzles) {
|
||||
const size_t input_offset = swizzle.buffer_offset + map.offset;
|
||||
const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 32U);
|
||||
const u32 num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 32U);
|
||||
|
||||
const auto params = MakeBlockLinearSwizzle2DParams(swizzle, image.info);
|
||||
ASSERT(params.origin == (std::array<u32, 3>{0, 0, 0}));
|
||||
ASSERT(params.destination == (std::array<s32, 3>{0, 0, 0}));
|
||||
|
||||
glUniform1ui(2, params.bytes_per_block_log2);
|
||||
glUniform1ui(3, params.layer_stride);
|
||||
glUniform1ui(4, params.block_size);
|
||||
glUniform1ui(5, params.x_shift);
|
||||
glUniform1ui(6, params.block_height);
|
||||
glUniform1ui(7, params.block_height_mask);
|
||||
|
||||
glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), swizzle.level, GL_TRUE, 0,
|
||||
GL_WRITE_ONLY, GL_RGBA8);
|
||||
// ASTC texture data
|
||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset,
|
||||
image.guest_size_bytes - swizzle.buffer_offset);
|
||||
|
||||
glDispatchCompute(num_dispatches_x, num_dispatches_y, image.info.resources.layers);
|
||||
}
|
||||
program_manager.RestoreGuestCompute();
|
||||
}
|
||||
|
||||
void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
|
||||
std::span<const SwizzleParameters> swizzles) {
|
||||
static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1};
|
||||
|
||||
@@ -40,6 +40,9 @@ public:
|
||||
explicit UtilShaders(ProgramManager& program_manager);
|
||||
~UtilShaders();
|
||||
|
||||
void ASTCDecode(Image& image, const ImageBufferMap& map,
|
||||
std::span<const VideoCommon::SwizzleParameters> swizzles);
|
||||
|
||||
void BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
|
||||
std::span<const VideoCommon::SwizzleParameters> swizzles);
|
||||
|
||||
@@ -59,7 +62,9 @@ private:
|
||||
ProgramManager& program_manager;
|
||||
|
||||
OGLBuffer swizzle_table_buffer;
|
||||
OGLBuffer astc_buffer;
|
||||
|
||||
OGLProgram astc_decoder_program;
|
||||
OGLProgram block_linear_unswizzle_2d_program;
|
||||
OGLProgram block_linear_unswizzle_3d_program;
|
||||
OGLProgram pitch_unswizzle_program;
|
||||
|
||||
@@ -166,7 +166,7 @@ struct FormatTuple {
|
||||
{VK_FORMAT_R16G16_SINT, Attachable | Storage}, // R16G16_SINT
|
||||
{VK_FORMAT_R16G16_SNORM, Attachable | Storage}, // R16G16_SNORM
|
||||
{VK_FORMAT_UNDEFINED}, // R32G32B32_FLOAT
|
||||
{VK_FORMAT_R8G8B8A8_SRGB, Attachable}, // A8B8G8R8_SRGB
|
||||
{VK_FORMAT_A8B8G8R8_SRGB_PACK32, Attachable}, // A8B8G8R8_SRGB
|
||||
{VK_FORMAT_R8G8_UNORM, Attachable | Storage}, // R8G8_UNORM
|
||||
{VK_FORMAT_R8G8_SNORM, Attachable | Storage}, // R8G8_SNORM
|
||||
{VK_FORMAT_R8G8_SINT, Attachable | Storage}, // R8G8_SINT
|
||||
|
||||
@@ -11,18 +11,39 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/div_ceil.h"
|
||||
#include "video_core/host_shaders/astc_decoder_comp_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_quad_indexed_comp_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_uint8_comp_spv.h"
|
||||
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
||||
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
|
||||
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
|
||||
#include "video_core/texture_cache/accelerated_swizzle.h"
|
||||
#include "video_core/texture_cache/types.h"
|
||||
#include "video_core/textures/astc.h"
|
||||
#include "video_core/textures/decoders.h"
|
||||
#include "video_core/vulkan_common/vulkan_device.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
using Tegra::Texture::SWIZZLE_TABLE;
|
||||
using Tegra::Texture::ASTC::EncodingsValues;
|
||||
using namespace Tegra::Texture::ASTC;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr u32 ASTC_BINDING_INPUT_BUFFER = 0;
|
||||
constexpr u32 ASTC_BINDING_ENC_BUFFER = 1;
|
||||
constexpr u32 ASTC_BINDING_6_TO_8_BUFFER = 2;
|
||||
constexpr u32 ASTC_BINDING_7_TO_8_BUFFER = 3;
|
||||
constexpr u32 ASTC_BINDING_8_TO_8_BUFFER = 4;
|
||||
constexpr u32 ASTC_BINDING_BYTE_TO_16_BUFFER = 5;
|
||||
constexpr u32 ASTC_BINDING_SWIZZLE_BUFFER = 6;
|
||||
constexpr u32 ASTC_BINDING_OUTPUT_IMAGE = 7;
|
||||
|
||||
VkPushConstantRange BuildComputePushConstantRange(std::size_t size) {
|
||||
return {
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
@@ -50,6 +71,67 @@ std::array<VkDescriptorSetLayoutBinding, 2> BuildInputOutputDescriptorSetBinding
|
||||
}};
|
||||
}
|
||||
|
||||
std::array<VkDescriptorSetLayoutBinding, 8> BuildASTCDescriptorSetBindings() {
|
||||
return {{
|
||||
{
|
||||
.binding = ASTC_BINDING_INPUT_BUFFER,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
{
|
||||
.binding = ASTC_BINDING_ENC_BUFFER,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
{
|
||||
.binding = ASTC_BINDING_6_TO_8_BUFFER,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
{
|
||||
.binding = ASTC_BINDING_7_TO_8_BUFFER,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
{
|
||||
.binding = ASTC_BINDING_8_TO_8_BUFFER,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
{
|
||||
.binding = ASTC_BINDING_BYTE_TO_16_BUFFER,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
{
|
||||
.binding = ASTC_BINDING_SWIZZLE_BUFFER,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
{
|
||||
.binding = ASTC_BINDING_OUTPUT_IMAGE,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.pImmutableSamplers = nullptr,
|
||||
},
|
||||
}};
|
||||
}
|
||||
|
||||
VkDescriptorUpdateTemplateEntryKHR BuildInputOutputDescriptorUpdateTemplate() {
|
||||
return {
|
||||
.dstBinding = 0,
|
||||
@@ -61,6 +143,94 @@ VkDescriptorUpdateTemplateEntryKHR BuildInputOutputDescriptorUpdateTemplate() {
|
||||
};
|
||||
}
|
||||
|
||||
std::array<VkDescriptorUpdateTemplateEntryKHR, 8> BuildASTCPassDescriptorUpdateTemplateEntry() {
|
||||
return {{
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_INPUT_BUFFER,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.offset = ASTC_BINDING_INPUT_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_ENC_BUFFER,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.offset = ASTC_BINDING_ENC_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_6_TO_8_BUFFER,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.offset = ASTC_BINDING_6_TO_8_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_7_TO_8_BUFFER,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.offset = ASTC_BINDING_7_TO_8_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_8_TO_8_BUFFER,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.offset = ASTC_BINDING_8_TO_8_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_BYTE_TO_16_BUFFER,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.offset = ASTC_BINDING_BYTE_TO_16_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_SWIZZLE_BUFFER,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.offset = ASTC_BINDING_SWIZZLE_BUFFER * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
{
|
||||
.dstBinding = ASTC_BINDING_OUTPUT_IMAGE,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.offset = ASTC_BINDING_OUTPUT_IMAGE * sizeof(DescriptorUpdateEntry),
|
||||
.stride = sizeof(DescriptorUpdateEntry),
|
||||
},
|
||||
}};
|
||||
}
|
||||
|
||||
struct AstcPushConstants {
|
||||
std::array<u32, 2> blocks_dims;
|
||||
u32 bytes_per_block_log2;
|
||||
u32 layer_stride;
|
||||
u32 block_size;
|
||||
u32 x_shift;
|
||||
u32 block_height;
|
||||
u32 block_height_mask;
|
||||
};
|
||||
|
||||
struct AstcBufferData {
|
||||
decltype(SWIZZLE_TABLE) swizzle_table_buffer = SWIZZLE_TABLE;
|
||||
decltype(EncodingsValues) encoding_values = EncodingsValues;
|
||||
decltype(REPLICATE_6_BIT_TO_8_TABLE) replicate_6_to_8 = REPLICATE_6_BIT_TO_8_TABLE;
|
||||
decltype(REPLICATE_7_BIT_TO_8_TABLE) replicate_7_to_8 = REPLICATE_7_BIT_TO_8_TABLE;
|
||||
decltype(REPLICATE_8_BIT_TO_8_TABLE) replicate_8_to_8 = REPLICATE_8_BIT_TO_8_TABLE;
|
||||
decltype(REPLICATE_BYTE_TO_16_TABLE) replicate_byte_to_16 = REPLICATE_BYTE_TO_16_TABLE;
|
||||
} constexpr ASTC_BUFFER_DATA;
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
VKComputePass::VKComputePass(const Device& device, VKDescriptorPool& descriptor_pool,
|
||||
@@ -238,4 +408,167 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble(
|
||||
return {staging.buffer, staging.offset};
|
||||
}
|
||||
|
||||
ASTCDecoderPass::ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_,
|
||||
VKDescriptorPool& descriptor_pool_,
|
||||
StagingBufferPool& staging_buffer_pool_,
|
||||
VKUpdateDescriptorQueue& update_descriptor_queue_,
|
||||
MemoryAllocator& memory_allocator_)
|
||||
: VKComputePass(device_, descriptor_pool_, BuildASTCDescriptorSetBindings(),
|
||||
BuildASTCPassDescriptorUpdateTemplateEntry(),
|
||||
BuildComputePushConstantRange(sizeof(AstcPushConstants)),
|
||||
ASTC_DECODER_COMP_SPV),
|
||||
device{device_}, scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
|
||||
update_descriptor_queue{update_descriptor_queue_}, memory_allocator{memory_allocator_} {}
|
||||
|
||||
ASTCDecoderPass::~ASTCDecoderPass() = default;
|
||||
|
||||
void ASTCDecoderPass::MakeDataBuffer() {
|
||||
constexpr size_t TOTAL_BUFFER_SIZE = sizeof(ASTC_BUFFER_DATA) + sizeof(SWIZZLE_TABLE);
|
||||
data_buffer = device.GetLogical().CreateBuffer(VkBufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = TOTAL_BUFFER_SIZE,
|
||||
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = nullptr,
|
||||
});
|
||||
data_buffer_commit = memory_allocator.Commit(data_buffer, MemoryUsage::Upload);
|
||||
|
||||
const auto staging_ref = staging_buffer_pool.Request(TOTAL_BUFFER_SIZE, MemoryUsage::Upload);
|
||||
std::memcpy(staging_ref.mapped_span.data(), &ASTC_BUFFER_DATA, sizeof(ASTC_BUFFER_DATA));
|
||||
// Tack on the swizzle table at the end of the buffer
|
||||
std::memcpy(staging_ref.mapped_span.data() + sizeof(ASTC_BUFFER_DATA), &SWIZZLE_TABLE,
|
||||
sizeof(SWIZZLE_TABLE));
|
||||
|
||||
scheduler.Record([src = staging_ref.buffer, offset = staging_ref.offset, dst = *data_buffer,
|
||||
TOTAL_BUFFER_SIZE](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.CopyBuffer(src, dst,
|
||||
VkBufferCopy{
|
||||
.srcOffset = offset,
|
||||
.dstOffset = 0,
|
||||
.size = TOTAL_BUFFER_SIZE,
|
||||
});
|
||||
cmdbuf.PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
|
||||
VkMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map,
|
||||
std::span<const VideoCommon::SwizzleParameters> swizzles) {
|
||||
using namespace VideoCommon::Accelerated;
|
||||
const std::array<u32, 2> block_dims{
|
||||
VideoCore::Surface::DefaultBlockWidth(image.info.format),
|
||||
VideoCore::Surface::DefaultBlockHeight(image.info.format),
|
||||
};
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
if (!data_buffer) {
|
||||
MakeDataBuffer();
|
||||
}
|
||||
const VkPipeline vk_pipeline = *pipeline;
|
||||
const VkImageAspectFlags aspect_mask = image.AspectMask();
|
||||
const VkImage vk_image = image.Handle();
|
||||
const bool is_initialized = image.ExchangeInitialization();
|
||||
scheduler.Record(
|
||||
[vk_pipeline, vk_image, aspect_mask, is_initialized](vk::CommandBuffer cmdbuf) {
|
||||
const VkImageMemoryBarrier image_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
||||
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = vk_image,
|
||||
.subresourceRange{
|
||||
.aspectMask = aspect_mask,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
};
|
||||
cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT : 0,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline);
|
||||
});
|
||||
for (const VideoCommon::SwizzleParameters& swizzle : swizzles) {
|
||||
const size_t input_offset = swizzle.buffer_offset + map.offset;
|
||||
const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 32U);
|
||||
const u32 num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 32U);
|
||||
const u32 num_dispatches_z = image.info.resources.layers;
|
||||
|
||||
update_descriptor_queue.Acquire();
|
||||
update_descriptor_queue.AddBuffer(map.buffer, input_offset,
|
||||
image.guest_size_bytes - swizzle.buffer_offset);
|
||||
update_descriptor_queue.AddBuffer(*data_buffer, offsetof(AstcBufferData, encoding_values),
|
||||
sizeof(AstcBufferData::encoding_values));
|
||||
update_descriptor_queue.AddBuffer(*data_buffer, offsetof(AstcBufferData, replicate_6_to_8),
|
||||
sizeof(AstcBufferData::replicate_6_to_8));
|
||||
update_descriptor_queue.AddBuffer(*data_buffer, offsetof(AstcBufferData, replicate_7_to_8),
|
||||
sizeof(AstcBufferData::replicate_7_to_8));
|
||||
update_descriptor_queue.AddBuffer(*data_buffer, offsetof(AstcBufferData, replicate_8_to_8),
|
||||
sizeof(AstcBufferData::replicate_8_to_8));
|
||||
update_descriptor_queue.AddBuffer(*data_buffer,
|
||||
offsetof(AstcBufferData, replicate_byte_to_16),
|
||||
sizeof(AstcBufferData::replicate_byte_to_16));
|
||||
update_descriptor_queue.AddBuffer(*data_buffer, sizeof(AstcBufferData),
|
||||
sizeof(SWIZZLE_TABLE));
|
||||
update_descriptor_queue.AddImage(image.StorageImageView(swizzle.level));
|
||||
|
||||
const VkDescriptorSet set = CommitDescriptorSet(update_descriptor_queue);
|
||||
const VkPipelineLayout vk_layout = *layout;
|
||||
|
||||
// To unswizzle the ASTC data
|
||||
const auto params = MakeBlockLinearSwizzle2DParams(swizzle, image.info);
|
||||
ASSERT(params.origin == (std::array<u32, 3>{0, 0, 0}));
|
||||
ASSERT(params.destination == (std::array<s32, 3>{0, 0, 0}));
|
||||
scheduler.Record([vk_layout, num_dispatches_x, num_dispatches_y, num_dispatches_z,
|
||||
block_dims, params, set](vk::CommandBuffer cmdbuf) {
|
||||
const AstcPushConstants uniforms{
|
||||
.blocks_dims = block_dims,
|
||||
.bytes_per_block_log2 = params.bytes_per_block_log2,
|
||||
.layer_stride = params.layer_stride,
|
||||
.block_size = params.block_size,
|
||||
.x_shift = params.x_shift,
|
||||
.block_height = params.block_height,
|
||||
.block_height_mask = params.block_height_mask,
|
||||
};
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, vk_layout, 0, set, {});
|
||||
cmdbuf.PushConstants(vk_layout, VK_SHADER_STAGE_COMPUTE_BIT, uniforms);
|
||||
cmdbuf.Dispatch(num_dispatches_x, num_dispatches_y, num_dispatches_z);
|
||||
});
|
||||
}
|
||||
scheduler.Record([vk_image, aspect_mask](vk::CommandBuffer cmdbuf) {
|
||||
const VkImageMemoryBarrier image_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = vk_image,
|
||||
.subresourceRange{
|
||||
.aspectMask = aspect_mask,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
};
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, image_barrier);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -11,14 +11,21 @@
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/engines/maxwell_3d.h"
|
||||
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
||||
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
|
||||
namespace VideoCommon {
|
||||
struct SwizzleParameters;
|
||||
}
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
class Device;
|
||||
class StagingBufferPool;
|
||||
class VKScheduler;
|
||||
class VKUpdateDescriptorQueue;
|
||||
class Image;
|
||||
struct StagingBufferRef;
|
||||
|
||||
class VKComputePass {
|
||||
public:
|
||||
@@ -77,4 +84,29 @@ private:
|
||||
VKUpdateDescriptorQueue& update_descriptor_queue;
|
||||
};
|
||||
|
||||
class ASTCDecoderPass final : public VKComputePass {
|
||||
public:
|
||||
explicit ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_,
|
||||
VKDescriptorPool& descriptor_pool_,
|
||||
StagingBufferPool& staging_buffer_pool_,
|
||||
VKUpdateDescriptorQueue& update_descriptor_queue_,
|
||||
MemoryAllocator& memory_allocator_);
|
||||
~ASTCDecoderPass();
|
||||
|
||||
void Assemble(Image& image, const StagingBufferRef& map,
|
||||
std::span<const VideoCommon::SwizzleParameters> swizzles);
|
||||
|
||||
private:
|
||||
void MakeDataBuffer();
|
||||
|
||||
const Device& device;
|
||||
VKScheduler& scheduler;
|
||||
StagingBufferPool& staging_buffer_pool;
|
||||
VKUpdateDescriptorQueue& update_descriptor_queue;
|
||||
MemoryAllocator& memory_allocator;
|
||||
|
||||
vk::Buffer data_buffer;
|
||||
MemoryCommit data_buffer_commit;
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -241,7 +241,10 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra
|
||||
staging_pool(device, memory_allocator, scheduler), descriptor_pool(device, scheduler),
|
||||
update_descriptor_queue(device, scheduler),
|
||||
blit_image(device, scheduler, state_tracker, descriptor_pool),
|
||||
texture_cache_runtime{device, scheduler, memory_allocator, staging_pool, blit_image},
|
||||
astc_decoder_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue,
|
||||
memory_allocator),
|
||||
texture_cache_runtime{device, scheduler, memory_allocator,
|
||||
staging_pool, blit_image, astc_decoder_pass},
|
||||
texture_cache(texture_cache_runtime, *this, maxwell3d, kepler_compute, gpu_memory),
|
||||
buffer_cache_runtime(device, memory_allocator, scheduler, staging_pool,
|
||||
update_descriptor_queue, descriptor_pool),
|
||||
|
||||
@@ -173,6 +173,7 @@ private:
|
||||
VKDescriptorPool descriptor_pool;
|
||||
VKUpdateDescriptorQueue update_descriptor_queue;
|
||||
BlitImageHelper blit_image;
|
||||
ASTCDecoderPass astc_decoder_pass;
|
||||
|
||||
GraphicsPipelineCacheKey graphics_key;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "video_core/engines/fermi_2d.h"
|
||||
#include "video_core/renderer_vulkan/blit_image.h"
|
||||
#include "video_core/renderer_vulkan/maxwell_to_vk.h"
|
||||
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
||||
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||
#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
|
||||
@@ -807,7 +808,7 @@ Image::Image(TextureCacheRuntime& runtime, const ImageInfo& info_, GPUVAddr gpu_
|
||||
commit = runtime.memory_allocator.Commit(buffer, MemoryUsage::DeviceLocal);
|
||||
}
|
||||
if (IsPixelFormatASTC(info.format) && !runtime.device.IsOptimalAstcSupported()) {
|
||||
flags |= VideoCommon::ImageFlagBits::Converted;
|
||||
flags |= VideoCommon::ImageFlagBits::AcceleratedUpload;
|
||||
}
|
||||
if (runtime.device.HasDebuggingToolAttached()) {
|
||||
if (image) {
|
||||
@@ -816,6 +817,38 @@ Image::Image(TextureCacheRuntime& runtime, const ImageInfo& info_, GPUVAddr gpu_
|
||||
buffer.SetObjectNameEXT(VideoCommon::Name(*this).c_str());
|
||||
}
|
||||
}
|
||||
static constexpr VkImageViewUsageCreateInfo storage_image_view_usage_create_info{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.usage = VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
};
|
||||
if (IsPixelFormatASTC(info.format) && !runtime.device.IsOptimalAstcSupported()) {
|
||||
const auto& device = runtime.device.GetLogical();
|
||||
storage_image_views.reserve(info.resources.levels);
|
||||
for (s32 level = 0; level < info.resources.levels; ++level) {
|
||||
storage_image_views.push_back(device.CreateImageView(VkImageViewCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.pNext = &storage_image_view_usage_create_info,
|
||||
.flags = 0,
|
||||
.image = *image,
|
||||
.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32,
|
||||
.components{
|
||||
.r = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.g = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.b = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
.a = VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
},
|
||||
.subresourceRange{
|
||||
.aspectMask = aspect_mask,
|
||||
.baseMipLevel = static_cast<u32>(level),
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||
},
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) {
|
||||
@@ -918,7 +951,6 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
}
|
||||
}
|
||||
const auto format_info = MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
|
||||
const VkFormat vk_format = format_info.format;
|
||||
const VkImageViewUsageCreateInfo image_view_usage{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -930,7 +962,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
.flags = 0,
|
||||
.image = image.Handle(),
|
||||
.viewType = VkImageViewType{},
|
||||
.format = vk_format,
|
||||
.format = format_info.format,
|
||||
.components{
|
||||
.r = ComponentSwizzle(swizzle[0]),
|
||||
.g = ComponentSwizzle(swizzle[1]),
|
||||
@@ -982,7 +1014,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.buffer = image.Buffer(),
|
||||
.format = vk_format,
|
||||
.format = format_info.format,
|
||||
.offset = 0, // TODO: Redesign buffer cache to support this
|
||||
.range = image.guest_size_bytes,
|
||||
});
|
||||
@@ -1167,4 +1199,13 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCacheRuntime::AccelerateImageUpload(
|
||||
Image& image, const StagingBufferRef& map,
|
||||
std::span<const VideoCommon::SwizzleParameters> swizzles) {
|
||||
if (IsPixelFormatASTC(image.info.format)) {
|
||||
return astc_decoder_pass.Assemble(image, map, swizzles);
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -20,6 +20,7 @@ using VideoCommon::Offset2D;
|
||||
using VideoCommon::RenderTargets;
|
||||
using VideoCore::Surface::PixelFormat;
|
||||
|
||||
class ASTCDecoderPass;
|
||||
class BlitImageHelper;
|
||||
class Device;
|
||||
class Image;
|
||||
@@ -60,6 +61,7 @@ struct TextureCacheRuntime {
|
||||
MemoryAllocator& memory_allocator;
|
||||
StagingBufferPool& staging_buffer_pool;
|
||||
BlitImageHelper& blit_image_helper;
|
||||
ASTCDecoderPass& astc_decoder_pass;
|
||||
std::unordered_map<RenderPassKey, vk::RenderPass> renderpass_cache{};
|
||||
|
||||
void Finish();
|
||||
@@ -83,9 +85,7 @@ struct TextureCacheRuntime {
|
||||
}
|
||||
|
||||
void AccelerateImageUpload(Image&, const StagingBufferRef&,
|
||||
std::span<const VideoCommon::SwizzleParameters>) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
std::span<const VideoCommon::SwizzleParameters>);
|
||||
|
||||
void InsertUploadMemoryBarrier() {}
|
||||
|
||||
@@ -121,15 +121,26 @@ public:
|
||||
return *buffer;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageCreateFlags AspectMask() const noexcept {
|
||||
[[nodiscard]] VkImageAspectFlags AspectMask() const noexcept {
|
||||
return aspect_mask;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageView StorageImageView(s32 level) const noexcept {
|
||||
return *storage_image_views[level];
|
||||
}
|
||||
|
||||
/// Returns true when the image is already initialized and mark it as initialized
|
||||
[[nodiscard]] bool ExchangeInitialization() noexcept {
|
||||
return std::exchange(initialized, true);
|
||||
}
|
||||
|
||||
private:
|
||||
VKScheduler* scheduler;
|
||||
vk::Image image;
|
||||
vk::Buffer buffer;
|
||||
MemoryCommit commit;
|
||||
vk::ImageView image_view;
|
||||
std::vector<vk::ImageView> storage_image_views;
|
||||
VkImageAspectFlags aspect_mask = 0;
|
||||
bool initialized = false;
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user