Compare commits

..

101 Commits

Author SHA1 Message Date
german77
09a8e08109 wlan: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
ac14ef70b5 usb: Use proper names 2021-04-08 19:40:25 -06:00
german77
35abd560c4 ITimeZoneService: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
e7530b341e spl: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
01928b1d17 sfdnsres: Use proper names 2021-04-08 19:40:25 -06:00
german77
ff1201210c nsd: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
f90041a2d4 ethc: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
6c81332ca7 sm: Use proper names, update to 12.x 2021-04-08 19:40:25 -06:00
german77
7133bfdd2c set_sys: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
556c5df745 pctl_module: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
4530b58eb0 pcie: Use proper names 2021-04-08 19:40:25 -06:00
german77
53f1560a24 olsc: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
c37b8a1028 pl_u: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
278c38aa4a ldr: Use proper names 2021-04-08 19:40:25 -06:00
german77
a4e2821530 arp: Use proper names, update to 12.x 2021-04-08 19:40:25 -06:00
german77
a83f0f7154 caps_u: Update to 12.x 2021-04-08 19:40:25 -06:00
german77
dbc4c8e314 caps_a: Update to 12.x 2021-04-08 19:40:24 -06:00
german77
03790771a6 bpc: Use proper names 2021-04-08 19:40:24 -06:00
german77
0377618288 bcat_module: Update to 12.x 2021-04-08 19:40:24 -06:00
german77
247b1c14d2 codecctl: Use proper names 2021-04-08 19:40:24 -06:00
german77
ec0e644fb0 audren_u: Use proper names 2021-04-08 19:40:24 -06:00
german77
8f1300cd31 audren_a: Use proper names 2021-04-08 19:40:24 -06:00
german77
6219da627b audrec_u: Use proper names, update to 12.x 2021-04-08 19:40:24 -06:00
german77
5ce97bf0a0 audrec_a: Use proper names 2021-04-08 19:40:24 -06:00
german77
b059db74c5 audout_u: Use proper names 2021-04-08 19:40:24 -06:00
german77
c51d9e0b0a audout_a: Use proper names 2021-04-08 19:40:24 -06:00
german77
d7f2078e7b audin_u: Use proper names 2021-04-08 19:40:24 -06:00
german77
b6bbc0d483 audin_a: Use proper names 2021-04-08 19:40:24 -06:00
bunnei
d894818bb3 Merge pull request #6157 from Morph1984/am-update-12.x
service: am: Update service function tables
2021-04-08 16:37:59 -07:00
bunnei
1744fa6ecf Merge pull request #6062 from ameerj/auto-stub
service: Add a toggle for auto stub fallback
2021-04-08 15:32:41 -07:00
bunnei
dfac2e2d25 Merge pull request #6145 from lat9nq/nvhost_empty_memcpy
nvhost_nvdec_common: Avoid memcpy with null pointers
2021-04-08 13:23:05 -07:00
bunnei
415dfb6cd3 Merge pull request #6154 from lioncash/svcrange2
svc: Expand SVC tables
2021-04-08 09:21:55 -07:00
bunnei
15a07f0282 Merge pull request #6160 from Morph1984/fs-update-12.x
service: fs: Update service function tables
2021-04-07 20:54:42 -07:00
bunnei
262a70223f Merge pull request #6143 from lat9nq/nvhost_null_memcpy
nvhost_ctrl_gpu: Avoid sending null pointer to memcpy
2021-04-07 16:50:22 -07:00
bunnei
535e50db1c Merge pull request #6159 from Morph1984/acc-update-12.x
service: acc: Update service function tables
2021-04-07 14:37:59 -07:00
bunnei
3173a53db9 Merge pull request #6130 from degasus/better_assert_handling
common: Move assert failure handling into a cpp file.
2021-04-07 13:35:41 -07:00
bunnei
d490f6dcf8 Merge pull request #6153 from lioncash/svcrange
process_capability: Handle extended SVC range
2021-04-07 13:01:40 -07:00
bunnei
6dc35caad1 Merge pull request #6161 from Morph1984/audio-update-12.x
service: audio: Update service function tables
2021-04-07 10:39:05 -07:00
Morph
a2d40b8185 hwopus: Update to 12.x 2021-04-07 02:57:39 -04:00
Morph
1ad4c98a5c IFile: Update to 12.x 2021-04-07 02:49:19 -04:00
Morph
c44db90ad1 fsp-srv: Update to 12.x 2021-04-07 02:46:29 -04:00
Morph
531e797795 dauth_o: Update to 11.x 2021-04-07 02:15:55 -04:00
Morph
ded420cfeb acc_u1: Update to 12.x 2021-04-07 02:15:55 -04:00
Morph
63caeca6ba acc_su: Update to 12.x 2021-04-07 02:15:55 -04:00
Morph
63ebf2a328 ISelfController: Update to 11.x 2021-04-07 02:00:19 -04:00
Morph
d04120169d IApplicationFunctions: Update to 11.x 2021-04-07 01:59:35 -04:00
Morph
ad0d5818a6 IDebugFunctions: Update to 12.x 2021-04-07 01:53:04 -04:00
Morph
49ec5784b0 ICommonStateGetter: Update to 12.x 2021-04-07 01:53:04 -04:00
Morph
4cdc701fd3 IGlobalStateController: Update to 12.x 2021-04-07 01:53:04 -04:00
Morph
95fa89da27 IHomeMenuFunctions: Update to 12.x 2021-04-07 01:53:04 -04:00
bunnei
068b2ffbcc Merge pull request #6146 from lat9nq/vp9_empty_memcpy
vp9: Avoid memcpy with null pointers
2021-04-06 21:57:43 -07:00
Lioncash
55fc808d64 svc: Expand SVC tables
12.x expanded the range of SVC entries from 0x7F to 0xBF (with all new
entries being unused), so we can expand it to also match.
2021-04-07 00:55:33 -04:00
Lioncash
03dda80e2b process_capability: Handle extended SVC range
12.x extended the range of SVC IDs, so we need to expand the range of
bits that need to be tested.

The upside of this is that we can eliminate a range check, given the
whole range is used.
2021-04-07 00:35:49 -04:00
lat9nq
2cc42e40c5 nvhost_nvdec_common: Avoid memcpy with null pointers
Avoid sending null pointer to memcpy as reported by Undefined Behavious
Sanitizer.

Co-authored-by: LC <mathew1800@gmail.com>
2021-04-05 16:40:03 -04:00
lat9nq
638c892edf nvhost_ctrl_gpu: Avoid sending null pointer to memcpy
Undefined Behaviour Sanitizer reports a null pointer is being sent to
memcpy, thought it's "guaranteed to never be null". Guard it with an if
statement, and log when the action has been averted.
2021-04-05 00:49:09 -04:00
lat9nq
a60653dcd3 vp9: Avoid memcpy with null pointers
Avoid sending null pointer to memcpy as reported by Undefined Behaviour
Sanitizer. Replaces the std::memcpy calls in SpliceVectors with
std::copy calls. Opting to replace all the memcpy's with copy's.

Co-authored-by: LC <mathew1800@gmail.com>
2021-04-05 00:44:38 -04:00
LC
7feb490f83 Merge pull request #6141 from lat9nq/cfg_gphcs_stack_use
configure_graphics: Prevent stack-use-after-scope
2021-04-04 18:16:50 -04:00
Markus Wick
9be819faaf common: Move assert failure handling into a cpp file.
Advantage: Altering the handler does not need a full recompilation.
Disadvantage: noreturn is droped, so the caller is a bit slower.

We quite often run yuzu with a YOLO assertion handler. In fact, only very few
games run at all with asserts. This patch allows developers to patch the handler
without recompiling everything. The overhead of the missing "noreturn" attribute
shoul be negletable.
2021-04-04 21:19:33 +02:00
lat9nq
33ed02a239 configure_graphics: Prevent stack-use-after-scope
Address Sanitizer reports stack-use-after-scope on line 231
`vulkan_devices.push_back(QString::fromStdString(name));`. Instead of
using a pointer, copy the string into a std::string and use that,
instead.
2021-04-04 15:05:22 -04:00
Morph
69b2dbdffd Merge pull request #6139 from Morph1984/cmake-fix-build
ci: Fix MSVC build with CMake 3.20.0
2021-04-04 07:54:38 -04:00
Morph
17ad323b36 ci: Fix MSVC build with CMake 3.20.0 2021-04-04 07:49:21 -04:00
bunnei
c92a211e7c Merge pull request #6127 from german77/udpSingleConnection
InputCommon: Improve UDP communications
2021-04-03 23:14:23 -07:00
bunnei
c5ca8675c8 Merge pull request #6132 from MerryMage/code_size
arm_dynarmic: Increase size of code cache
2021-04-02 18:47:04 -07:00
Morph
aca6ab6417 Merge pull request #6131 from german77/rightjoyconSLSR
HID: Fix SL and SR buttons for right joycon
2021-04-02 15:48:04 -04:00
MerryMage
0fbd7752c3 arm_dynarmic: Increase size of code cache 2021-04-02 18:09:15 +01:00
german77
eaf0c4af11 HID: Fix SL and SR buttons for right joycon 2021-04-02 09:03:11 -05:00
bunnei
94d77d0e39 Merge pull request #6129 from degasus/cmake_libzip
externals/cmake: Fix case spelling of libzip.
2021-04-01 23:06:36 -07:00
bunnei
824adb44fa Merge pull request #6128 from bunnei/update-dynarmic-2
externals: dynarmic: Update to latest rev. to increase code size.
2021-04-01 21:02:51 -07:00
Markus Wick
d3e87d70ec externals: Fix case spelling of libzip.
CMake is case senstive, so Libzip vs LIBZIP was a bug.
Upstream calls themself libzip, so let's pick this naming.
2021-04-02 00:30:13 +02:00
bunnei
7ff7e65926 externals: dynarmic: Update to latest rev. to increase code size.
- The current limits are being hit in yuzu with some games.
- This should fix the slowdowns in newer updates for Super Smash Bros. Ultimate.
2021-04-01 13:23:12 -07:00
bunnei
d69421b1db Merge pull request #6106 from MerryMage/nullptr-jit
[test] arm_dynarmic: Always have a 'valid' jit instance
2021-04-01 09:50:00 -07:00
bunnei
e44622860a Merge pull request #6126 from Morph1984/stub-SetAlbumImageTakenNotificationEnabled
ISelfController: Stub SetAlbumImageTakenNotificationEnabled
2021-03-30 21:32:01 -07:00
german77
bb3dce9363 Use a single connection for UDP server, make connection test longer and check all pads instead of only the first one 2021-03-30 22:17:08 -05:00
Rodrigo Locatti
5ee669466f Merge pull request #5927 from ameerj/astc-compute
video_core: Accelerate ASTC texture decoding using compute shaders
2021-03-30 19:31:52 -03:00
bunnei
eeea426c74 Merge pull request #6116 from german77/userArgument
yuzu/main: Add user command line argument
2021-03-30 15:01:33 -07:00
Morph
ca30190fad ISelfController: Stub SetAlbumImageTakenNotificationEnabled
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.
2021-03-30 13:45:00 -04:00
ameerj
54c1e0897d configuration: Add auto stub toggle that resets on boot
Auto-stub is an experimental debugging feature that may cause unforseen bugs. This adds a toggle to only allow auto-stubbing unimplemented functions when explicitly enabled when yuzu is launched.
2021-03-30 13:40:31 -04:00
ameerj
e6e61424d4 service: Auto stub fallback
For simple services we can implement an automatic stub fallback to help with compatibility until a proper implementation is done.

Co-Authored-By: Chloe <25727384+ognik5377@users.noreply.github.com>
2021-03-30 13:40:31 -04:00
bunnei
b3f68098d5 Merge pull request #6124 from jbeich/vulkan+opengl
vulkan_common: enable OpenGL interop on other Unices
2021-03-30 09:37:00 -07:00
bunnei
f234531f92 Merge pull request #6109 from german77/gestureID
HID: Initialize correctly the gesture finger_id and filter invalid inputs
2021-03-29 18:00:47 -07:00
Jan Beich
9b50b23a50 vulkan_common: enable OpenGL interop on other Unices 2021-03-30 00:25:25 +00:00
bunnei
fb7dcbf7af Merge pull request #6102 from ogniK5377/fd-pass
nvdrv: Pass device fd and handle device create methods for device opening and closing
2021-03-29 12:53:55 -07:00
bunnei
a63dcb6d56 Merge pull request #6118 from MerryMage/dynarmic
externals: Update dynarmic to c28f13af
2021-03-28 13:59:05 -07:00
bunnei
f8561c7a65 Merge pull request #6115 from bunnei/fix-kernel-init
hle: kernel: Initialize preemption task after schedulers.
2021-03-28 12:13:39 -07:00
MerryMage
a527e5f0cd externals: Update dynarmic to c28f13af
AVX-512 bugfixes
2021-03-27 21:34:20 +00:00
german77
9cebde760f yuzu/main: Add user command line argument 2021-03-27 12:34:48 -05:00
bunnei
8a5794c4db Merge pull request #6114 from Morph1984/friend-log
service: friend: Change logging class from ACC to Friend
2021-03-27 10:29:43 -07:00
bunnei
cb7f2e5616 hle: kernel: Initialize preemption task after schedulers.
- Fixes a startup crash that occurs if CoreTiming tries to preempt before kernel initialization completes.
2021-03-27 10:04:13 -07:00
Morph
3b98fab850 service: friend: Change logging class from ACC to Friend 2021-03-27 11:11:07 -04:00
Narr the Reg
7c26a9aefe HID: Initialize correctly the gesture finger_id and filter invalid results 2021-03-26 11:13:18 -06:00
ameerj
2f83d9a61b astc_decoder: Refactor for style and more efficient memory use 2021-03-25 16:53:51 -04:00
Chloe Marcec
99fdfa1fcd nvdrv: Pass device fd and handle device create methods for device opening and closing
We pass the fd to the ioctl as well as alert the device when it's opened or closed to allow for fd unique actions to take place
2021-03-25 12:56:42 +11:00
bunnei
65774084fd Merge pull request #6101 from ogniK5377/alloc-as-ex
nvdrv: Change InitializeEx to AllocAsEx
2021-03-24 17:37:01 -07:00
bunnei
b83eb4dd18 Merge pull request #6108 from jbeich/freebsd-async-shaders
gl_device: unblock async shaders on other Unix systems
2021-03-24 16:52:27 -07:00
MerryMage
52dae41d7f arm_dynarmic: Always have a 'valid' jit instance 2021-03-24 18:47:17 +00:00
Chloe Marcec
875183e7c5 nvdrv: Change InitializeEx to AllocAsEx
Wee also report the correct "big page size" now in GetVARegions & fix up the struct for IoctlAllocAsEx
2021-03-22 19:59:30 +11:00
Rodrigo Locatti
2f30c10584 astc_decoder: Reimplement Layers
Reimplements the approach to decoding layers in the compute shader. Fixes multilayer astc decoding when using Vulkan.
2021-03-13 12:16:03 -05:00
ameerj
c7553abe89 astc_decoder: Fix out of bounds memory access
resolves a crash with some anamolous textures found in Astral Chain.
2021-03-13 12:16:03 -05:00
ameerj
20eb368e14 renderer_vulkan: Accelerate ASTC decoding
Co-Authored-By: Rodrigo Locatti <reinuseslisp@airmail.cc>
2021-03-13 12:16:03 -05:00
ameerj
f6566338eb host_shaders: Modify shader cmake integration to allow for larger shaders
using a raw string to encapsulate the entire shader code limits us to shaders of size less than 2KB. This change overcomes this limitation.
2021-03-13 12:16:03 -05:00
ameerj
2985e5e94c renderer_opengl: Accelerate ASTC texture decoding with a compute shader
ASTC texture decoding is currently handled by a CPU decoder for GPU's without native ASTC decoding support (most desktop GPUs). This is the cause for noticeable performance degradation in titles which use the format extensively.

This commit adds support to accelerate ASTC decoding using a compute shader on OpenGL for GPUs without native support.
2021-03-13 12:16:03 -05:00
115 changed files with 2966 additions and 2295 deletions

View File

@@ -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'

View File

@@ -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()

View File

@@ -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
View 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
)

View File

@@ -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
View 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();
}

View File

@@ -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_) \

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -68,9 +68,9 @@ struct KernelCore::Impl {
InitializePhysicalCores();
InitializeSystemResourceLimit(kernel, system);
InitializeMemoryLayout();
InitializePreemption(kernel);
InitializeSchedulers();
InitializeSuspendThreads();
InitializePreemption(kernel);
}
void InitializeCores() {

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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

View File

@@ -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"},
};

View File

@@ -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"},
};

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"},

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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"},

View File

@@ -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

View File

@@ -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};

View File

@@ -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;

View File

@@ -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);

View File

@@ -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>();

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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};

View File

@@ -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"},
};

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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(&params, 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(), &params, output.size());
std::memcpy(inline_output.data(), &params.regions, inline_output.size());
std::memcpy(inline_output.data(), &params.small, sizeof(IoctlVaRegion));
std::memcpy(inline_output.data() + sizeof(IoctlVaRegion), &params.big, sizeof(IoctlVaRegion));
return NvResult::Success;
}

View File

@@ -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);

View File

@@ -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(&params, input.data(), sizeof(params));

View File

@@ -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 {

View File

@@ -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(&params, input.data(), input.size());
// TODO(ogniK): What does this even actually do?
std::memcpy(output.data(), &params, 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(), &params, output.size());
}
return NvResult::Success;
}

View File

@@ -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 {

View File

@@ -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(&params, input.data(), input.size());

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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(&params, input.data(), input.size());

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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"},

View File

@@ -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

View File

@@ -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"},

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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"},

View File

@@ -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"},

View File

@@ -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"},

View File

@@ -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"},

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View File

@@ -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++;

View File

@@ -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

View File

@@ -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})

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,8 @@
namespace HostShaders {
constexpr std::string_view @CONTENTS_NAME@ = R"(@CONTENTS@)";
constexpr std::string_view @CONTENTS_NAME@ = {
@CONTENTS@
};
} // namespace HostShaders

View File

@@ -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_} {}

View File

@@ -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_);

View File

@@ -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};

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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),

View File

@@ -173,6 +173,7 @@ private:
VKDescriptorPool descriptor_pool;
VKUpdateDescriptorQueue update_descriptor_queue;
BlitImageHelper blit_image;
ASTCDecoderPass astc_decoder_pass;
GraphicsPipelineCacheKey graphics_key;

View File

@@ -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

View File

@@ -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