summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.ci/scripts/windows/docker.sh5
-rw-r--r--.gitmodules6
-rw-r--r--CMakeLists.txt218
-rw-r--r--dist/yuzu.desktop2
-rw-r--r--dist/yuzu.xml15
-rw-r--r--externals/CMakeLists.txt16
m---------externals/SDL0
m---------externals/ffmpeg0
-rw-r--r--externals/ffmpeg/CMakeLists.txt214
m---------externals/ffmpeg/ffmpeg0
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hid/emulated_console.cpp3
-rw-r--r--src/core/hid/emulated_console.h2
-rw-r--r--src/core/hid/emulated_controller.cpp19
-rw-r--r--src/core/hid/hid_types.h7
-rw-r--r--src/core/hid/motion_input.cpp12
-rw-r--r--src/core/hid/motion_input.h5
-rw-r--r--src/core/hle/kernel/k_process.cpp2
-rw-r--r--src/core/hle/kernel/kernel.cpp5
-rw-r--r--src/core/hle/kernel/svc.cpp9
-rw-r--r--src/core/hle/lock.cpp9
-rw-r--r--src/core/hle/lock.h18
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp12
-rw-r--r--src/core/hle/service/bcat/backend/backend.h5
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.cpp20
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.h10
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp7
-rw-r--r--src/core/hle/service/hid/controllers/npad.h7
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/core/hle/service/nfp/nfp.cpp2
-rw-r--r--src/core/loader/kip.cpp8
-rw-r--r--src/input_common/drivers/udp_client.cpp74
-rw-r--r--src/input_common/helpers/udp_protocol.h21
-rw-r--r--src/tests/CMakeLists.txt3
-rw-r--r--src/tests/input_common/calibration_configuration_job.cpp136
-rw-r--r--src/video_core/command_classes/codecs/codec.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h2
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp50
-rw-r--r--src/video_core/renderer_vulkan/blit_image.cpp123
-rw-r--r--src/video_core/renderer_vulkan/blit_image.h30
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp37
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp34
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h8
-rw-r--r--src/video_core/texture_cache/texture_cache.h15
-rw-r--r--src/yuzu/applets/qt_controller.cpp3
-rw-r--r--src/yuzu/applets/qt_error.cpp3
-rw-r--r--src/yuzu/applets/qt_profile_select.cpp3
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/game_list.cpp19
-rw-r--r--src/yuzu/uisettings.h3
50 files changed, 673 insertions, 541 deletions
diff --git a/.ci/scripts/windows/docker.sh b/.ci/scripts/windows/docker.sh
index 155d8a5c8..584b9b39f 100755
--- a/.ci/scripts/windows/docker.sh
+++ b/.ci/scripts/windows/docker.sh
@@ -41,12 +41,11 @@ for i in package/*.exe; do
done
pip3 install pefile
-python3 .ci/scripts/windows/scan_dll.py package/*.exe "package/"
-python3 .ci/scripts/windows/scan_dll.py package/imageformats/*.dll "package/"
+python3 .ci/scripts/windows/scan_dll.py package/*.exe package/imageformats/*.dll "package/"
# copy FFmpeg libraries
EXTERNALS_PATH="$(pwd)/build/externals"
-FFMPEG_DLL_PATH="$(find ${EXTERNALS_PATH} -maxdepth 1 -type d | grep ffmpeg)/bin"
+FFMPEG_DLL_PATH="$(find "${EXTERNALS_PATH}" -maxdepth 1 -type d | grep 'ffmpeg-')/bin"
find ${FFMPEG_DLL_PATH} -type f -regex ".*\.dll" -exec cp -v {} package/ ';'
# copy libraries from yuzu.exe path
diff --git a/.gitmodules b/.gitmodules
index dc6ed500f..a9cf9a24a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -34,12 +34,12 @@
[submodule "opus"]
path = externals/opus/opus
url = https://github.com/xiph/opus.git
-[submodule "ffmpeg"]
- path = externals/ffmpeg
- url = https://git.ffmpeg.org/ffmpeg.git
[submodule "SDL"]
path = externals/SDL
url = https://github.com/libsdl-org/SDL.git
[submodule "externals/cpp-httplib"]
path = externals/cpp-httplib
url = https://github.com/yhirose/cpp-httplib.git
+[submodule "externals/ffmpeg/ffmpeg"]
+ path = externals/ffmpeg/ffmpeg
+ url = https://git.ffmpeg.org/ffmpeg.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a810e11c2..18d553f4d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -514,7 +514,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
endif()
if (NOT YUZU_USE_BUNDLED_FFMPEG)
# Use system installed FFmpeg
- find_package(FFmpeg QUIET COMPONENTS ${FFmpeg_COMPONENTS})
+ find_package(FFmpeg 4.3 QUIET COMPONENTS ${FFmpeg_COMPONENTS})
if (FFmpeg_FOUND)
# Overwrite aggregate defines from FFmpeg module to avoid over-linking libraries.
@@ -527,225 +527,11 @@ if (NOT YUZU_USE_BUNDLED_FFMPEG)
set(FFmpeg_INCLUDE_DIR ${FFmpeg_INCLUDE_DIR} ${FFmpeg_INCLUDE_${COMPONENT}} CACHE PATH "Path to FFmpeg headers" FORCE)
endforeach()
else()
- message(WARNING "FFmpeg not found, falling back to externals")
+ message(WARNING "FFmpeg not found or too old, falling back to externals")
set(YUZU_USE_BUNDLED_FFMPEG ON)
endif()
endif()
-if (YUZU_USE_BUNDLED_FFMPEG)
- if (NOT WIN32)
- # TODO(lat9nq): Move this to externals/ffmpeg/CMakeLists.txt (and move externals/ffmpeg to
- # externals/ffmpeg/ffmpeg)
-
- # Build FFmpeg from externals
- message(STATUS "Using FFmpeg from externals")
-
- # FFmpeg has source that requires one of nasm or yasm to assemble it.
- # REQUIRED throws an error if not found here during configuration rather than during compilation.
- find_program(ASSEMBLER NAMES nasm yasm)
- if ("${ASSEMBLER}" STREQUAL "ASSEMBLER-NOTFOUND")
- message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.")
- endif()
-
- find_program(AUTOCONF autoconf)
- if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND")
- message(FATAL_ERROR "Required program `autoconf` not found.")
- endif()
-
- set(FFmpeg_PREFIX ${PROJECT_SOURCE_DIR}/externals/ffmpeg)
- set(FFmpeg_BUILD_DIR ${PROJECT_BINARY_DIR}/externals/ffmpeg)
- set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile)
- make_directory(${FFmpeg_BUILD_DIR})
-
- # Read version string from external
- file(READ ${FFmpeg_PREFIX}/RELEASE FFmpeg_VERSION)
- set(FFmpeg_FOUND NO)
- if (NOT FFmpeg_VERSION STREQUAL "")
- set(FFmpeg_FOUND YES)
- endif()
-
- unset(FFmpeg_LIBRARIES CACHE)
- foreach(COMPONENT ${FFmpeg_COMPONENTS})
- set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}")
- set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a")
- set(FFmpeg_${COMPONENT}_LIBRARY "${FFmpeg_${COMPONENT}_PREFIX}/${FFmpeg_${COMPONENT}_LIB_NAME}")
-
- set(FFmpeg_LIBRARIES
- ${FFmpeg_LIBRARIES}
- ${FFmpeg_${COMPONENT}_LIBRARY}
- CACHE PATH "Paths to FFmpeg libraries" FORCE)
- endforeach()
-
- Include(FindPkgConfig REQUIRED)
- pkg_check_modules(LIBVA libva)
- pkg_check_modules(CUDA cuda)
- pkg_check_modules(FFNVCODEC ffnvcodec)
- pkg_check_modules(VDPAU vdpau)
-
- set(FFmpeg_HWACCEL_LIBRARIES)
- set(FFmpeg_HWACCEL_FLAGS)
- set(FFmpeg_HWACCEL_INCLUDE_DIRS)
- set(FFmpeg_HWACCEL_LDFLAGS)
-
- if(LIBVA_FOUND)
- pkg_check_modules(LIBDRM libdrm REQUIRED)
- find_package(X11 REQUIRED)
- pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
- pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
- list(APPEND FFmpeg_HWACCEL_LIBRARIES
- ${LIBDRM_LIBRARIES}
- ${X11_LIBRARIES}
- ${LIBVA-DRM_LIBRARIES}
- ${LIBVA-X11_LIBRARIES}
- ${LIBVA_LIBRARIES})
- set(FFmpeg_HWACCEL_FLAGS
- --enable-hwaccel=h264_vaapi
- --enable-hwaccel=vp8_vaapi
- --enable-hwaccel=vp9_vaapi
- --enable-libdrm)
- list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
- ${LIBDRM_INCLUDE_DIRS}
- ${X11_INCLUDE_DIRS}
- ${LIBVA-DRM_INCLUDE_DIRS}
- ${LIBVA-X11_INCLUDE_DIRS}
- ${LIBVA_INCLUDE_DIRS}
- )
- message(STATUS "VA-API found")
- else()
- set(FFmpeg_HWACCEL_FLAGS --disable-vaapi)
- endif()
-
- if (FFNVCODEC_FOUND AND CUDA_FOUND)
- list(APPEND FFmpeg_HWACCEL_FLAGS
- --enable-cuvid
- --enable-ffnvcodec
- --enable-nvdec
- --enable-hwaccel=h264_nvdec
- --enable-hwaccel=vp8_nvdec
- --enable-hwaccel=vp9_nvdec
- --extra-cflags=-I${CUDA_INCLUDE_DIRS}
- )
- list(APPEND FFmpeg_HWACCEL_LIBRARIES
- ${FFNVCODEC_LIBRARIES}
- ${CUDA_LIBRARIES}
- )
- list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
- ${FFNVCODEC_INCLUDE_DIRS}
- ${CUDA_INCLUDE_DIRS}
- )
- list(APPEND FFmpeg_HWACCEL_LDFLAGS
- ${FFNVCODEC_LDFLAGS}
- ${CUDA_LDFLAGS}
- )
- message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
- endif()
-
- if (VDPAU_FOUND)
- list(APPEND FFmpeg_HWACCEL_FLAGS
- --enable-vdpau
- --enable-hwaccel=h264_vdpau
- --enable-hwaccel=vp9_vdpau
- )
- list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES})
- list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS})
- list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS})
- message(STATUS "vdpau libraries version ${VDPAU_VERSION} found")
- else()
- list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
- endif()
-
- # `configure` parameters builds only exactly what yuzu needs from FFmpeg
- # `--disable-vdpau` is needed to avoid linking issues
- add_custom_command(
- OUTPUT
- ${FFmpeg_MAKEFILE}
- COMMAND
- /bin/bash ${FFmpeg_PREFIX}/configure
- --disable-avdevice
- --disable-avfilter
- --disable-avformat
- --disable-doc
- --disable-everything
- --disable-ffmpeg
- --disable-ffprobe
- --disable-network
- --disable-postproc
- --disable-swresample
- --enable-decoder=h264
- --enable-decoder=vp8
- --enable-decoder=vp9
- --cc="${CMAKE_C_COMPILER}"
- --cxx="${CMAKE_CXX_COMPILER}"
- ${FFmpeg_HWACCEL_FLAGS}
- WORKING_DIRECTORY
- ${FFmpeg_BUILD_DIR}
- )
- unset(FFmpeg_HWACCEL_FLAGS)
-
- # Workaround for Ubuntu 18.04's older version of make not being able to call make as a child
- # with context of the jobserver. Also helps ninja users.
- execute_process(
- COMMAND
- nproc
- OUTPUT_VARIABLE
- SYSTEM_THREADS)
-
- set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES})
- add_custom_command(
- OUTPUT
- ${FFmpeg_BUILD_LIBRARIES}
- COMMAND
- make -j${SYSTEM_THREADS}
- WORKING_DIRECTORY
- ${FFmpeg_BUILD_DIR}
- )
-
- set(FFmpeg_INCLUDE_DIR
- "${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR};${FFmpeg_HWACCEL_INCLUDE_DIRS}"
- CACHE PATH "Path to FFmpeg headers" FORCE)
-
- set(FFmpeg_LDFLAGS
- "${FFmpeg_HWACCEL_LDFLAGS}"
- CACHE STRING "FFmpeg linker flags" FORCE)
-
- # ALL makes this custom target build every time
- # but it won't actually build if the DEPENDS parameter is up to date
- add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE})
- add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_BUILD_LIBRARIES} ffmpeg-configure)
- link_libraries(${FFmpeg_LIBVA_LIBRARIES})
- set(FFmpeg_LIBRARIES ${FFmpeg_BUILD_LIBRARIES} ${FFmpeg_HWACCEL_LIBRARIES}
- CACHE PATH "Paths to FFmpeg libraries" FORCE)
- unset(FFmpeg_BUILD_LIBRARIES)
- unset(FFmpeg_HWACCEL_FLAGS)
- unset(FFmpeg_HWACCEL_INCLUDE_DIRS)
- unset(FFmpeg_HWACCEL_LDFLAGS)
- unset(FFmpeg_HWACCEL_LIBRARIES)
-
- if (FFmpeg_FOUND)
- message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}")
- else()
- message(FATAL_ERROR "FFmpeg not found")
- endif()
- else() # WIN32
- # Use yuzu FFmpeg binaries
- set(FFmpeg_EXT_NAME "ffmpeg-4.4")
- set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
- download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
- set(FFmpeg_FOUND YES)
- set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE)
- set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE)
- set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE)
- set(FFmpeg_DLL_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE)
- set(FFmpeg_LIBRARIES
- ${FFmpeg_LIBRARY_DIR}/swscale.lib
- ${FFmpeg_LIBRARY_DIR}/avcodec.lib
- ${FFmpeg_LIBRARY_DIR}/avutil.lib
- CACHE PATH "Paths to FFmpeg libraries" FORCE)
- endif()
-endif()
-
-unset(FFmpeg_COMPONENTS)
-
# Prefer the -pthread flag on Linux.
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
diff --git a/dist/yuzu.desktop b/dist/yuzu.desktop
index 105080c73..6cc0704d2 100644
--- a/dist/yuzu.desktop
+++ b/dist/yuzu.desktop
@@ -8,5 +8,5 @@ Icon=yuzu
TryExec=yuzu
Exec=yuzu %f
Categories=Game;Emulator;Qt;
-MimeType=application/x-nx-nro;application/x-nx-nso;
+MimeType=application/x-nx-nro;application/x-nx-nso;application/x-nx-nsp;application/x-nx-xci;
Keywords=Switch;Nintendo; \ No newline at end of file
diff --git a/dist/yuzu.xml b/dist/yuzu.xml
index f6e408321..dd1e30a6b 100644
--- a/dist/yuzu.xml
+++ b/dist/yuzu.xml
@@ -15,4 +15,19 @@
<glob pattern="*.nso"/>
<magic><match value="NSO" type="string" offset="0"/></magic>
</mime-type>
+
+ <mime-type type="application/x-nx-nsp">
+ <comment>Nintendo Switch Package</comment>
+ <acronym>NSP</acronym>
+ <icon name="yuzu"/>
+ <glob pattern="*.nsp"/>
+ <magic><match value="PFS" type="string" offset="0"/></magic>
+ </mime-type>
+
+ <mime-type type="application/x-nx-xci">
+ <comment>Nintendo Switch Card Image</comment>
+ <acronym>XCI</acronym>
+ <icon name="yuzu"/>
+ <glob pattern="*.xci"/>
+ </mime-type>
</mime-info> \ No newline at end of file
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index 64d1e6aec..e9095b123 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -52,11 +52,12 @@ endif()
# SDL2
if (YUZU_USE_EXTERNAL_SDL2)
if (NOT WIN32)
- # Yuzu itself needs: Events Joystick Haptic Sensor Timers Audio
+ # Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers
+ # Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095)
# Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
set(SDL_UNUSED_SUBSYSTEMS
- Atomic Render Power Threads
- File CPUinfo Filesystem Locale)
+ CPUinfo File Filesystem
+ Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
option(SDL_${_OPT} "" OFF)
@@ -121,3 +122,12 @@ if (NOT opus_FOUND)
message(STATUS "opus 1.3 or newer not found, falling back to externals")
add_subdirectory(opus EXCLUDE_FROM_ALL)
endif()
+
+# FFMpeg
+if (YUZU_USE_BUNDLED_FFMPEG)
+ add_subdirectory(ffmpeg)
+ set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE)
+ set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE)
+ set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE)
+ set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
+endif()
diff --git a/externals/SDL b/externals/SDL
-Subproject 2e9821423a237a1206e3c09020778faacfe430b
+Subproject e2ade2bfc46d915cd306c63c830b81d800b2575
diff --git a/externals/ffmpeg b/externals/ffmpeg
deleted file mode 160000
-Subproject 79e8d17024e6c6328a40fcee191ffd70798a9c6
diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt
new file mode 100644
index 000000000..c57b54f77
--- /dev/null
+++ b/externals/ffmpeg/CMakeLists.txt
@@ -0,0 +1,214 @@
+if (NOT WIN32)
+ # Build FFmpeg from externals
+ message(STATUS "Using FFmpeg from externals")
+
+ if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64)")
+ # FFmpeg has source that requires one of nasm or yasm to assemble it.
+ # REQUIRED throws an error if not found here during configuration rather than during compilation.
+ find_program(ASSEMBLER NAMES nasm yasm)
+ if ("${ASSEMBLER}" STREQUAL "ASSEMBLER-NOTFOUND")
+ message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.")
+ endif()
+ endif()
+
+ find_program(AUTOCONF autoconf)
+ if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND")
+ message(FATAL_ERROR "Required program `autoconf` not found.")
+ endif()
+
+ set(FFmpeg_PREFIX ${PROJECT_SOURCE_DIR}/externals/ffmpeg/ffmpeg)
+ set(FFmpeg_BUILD_DIR ${PROJECT_BINARY_DIR}/externals/ffmpeg-build)
+ set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile)
+ make_directory(${FFmpeg_BUILD_DIR})
+
+ # Read version string from external
+ file(READ ${FFmpeg_PREFIX}/RELEASE FFmpeg_VERSION)
+ set(FFmpeg_FOUND NO)
+ if (NOT FFmpeg_VERSION STREQUAL "")
+ set(FFmpeg_FOUND YES)
+ endif()
+
+ unset(FFmpeg_LIBRARIES CACHE)
+ foreach(COMPONENT ${FFmpeg_COMPONENTS})
+ set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}")
+ set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a")
+ set(FFmpeg_${COMPONENT}_LIBRARY "${FFmpeg_${COMPONENT}_PREFIX}/${FFmpeg_${COMPONENT}_LIB_NAME}")
+
+ set(FFmpeg_LIBRARIES
+ ${FFmpeg_LIBRARIES}
+ ${FFmpeg_${COMPONENT}_LIBRARY}
+ CACHE PATH "Paths to FFmpeg libraries" FORCE)
+ endforeach()
+
+ Include(FindPkgConfig REQUIRED)
+ pkg_check_modules(LIBVA libva)
+ pkg_check_modules(CUDA cuda)
+ pkg_check_modules(FFNVCODEC ffnvcodec)
+ pkg_check_modules(VDPAU vdpau)
+
+ set(FFmpeg_HWACCEL_LIBRARIES)
+ set(FFmpeg_HWACCEL_FLAGS)
+ set(FFmpeg_HWACCEL_INCLUDE_DIRS)
+ set(FFmpeg_HWACCEL_LDFLAGS)
+
+ if(LIBVA_FOUND)
+ pkg_check_modules(LIBDRM libdrm REQUIRED)
+ find_package(X11 REQUIRED)
+ pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
+ pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
+ list(APPEND FFmpeg_HWACCEL_LIBRARIES
+ ${LIBDRM_LIBRARIES}
+ ${X11_LIBRARIES}
+ ${LIBVA-DRM_LIBRARIES}
+ ${LIBVA-X11_LIBRARIES}
+ ${LIBVA_LIBRARIES})
+ set(FFmpeg_HWACCEL_FLAGS
+ --enable-hwaccel=h264_vaapi
+ --enable-hwaccel=vp8_vaapi
+ --enable-hwaccel=vp9_vaapi
+ --enable-libdrm)
+ list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
+ ${LIBDRM_INCLUDE_DIRS}
+ ${X11_INCLUDE_DIRS}
+ ${LIBVA-DRM_INCLUDE_DIRS}
+ ${LIBVA-X11_INCLUDE_DIRS}
+ ${LIBVA_INCLUDE_DIRS}
+ )
+ message(STATUS "VA-API found")
+ else()
+ set(FFmpeg_HWACCEL_FLAGS --disable-vaapi)
+ endif()
+
+ if (FFNVCODEC_FOUND)
+ list(APPEND FFmpeg_HWACCEL_FLAGS
+ --enable-cuvid
+ --enable-ffnvcodec
+ --enable-nvdec
+ --enable-hwaccel=h264_nvdec
+ --enable-hwaccel=vp8_nvdec
+ --enable-hwaccel=vp9_nvdec
+ )
+ list(APPEND FFmpeg_HWACCEL_LIBRARIES ${FFNVCODEC_LIBRARIES})
+ list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${FFNVCODEC_INCLUDE_DIRS})
+ list(APPEND FFmpeg_HWACCEL_LDFLAGS ${FFNVCODEC_LDFLAGS})
+ message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
+ # ffnvenc could load CUDA libraries at the runtime using dlopen/dlsym or LoadLibrary/GetProcAddress
+ # here we handle the hard-linking senario where CUDA is linked during compilation
+ if (CUDA_FOUND)
+ list(APPEND FFmpeg_HWACCEL_FLAGS --extra-cflags=-I${CUDA_INCLUDE_DIRS})
+ list(APPEND FFmpeg_HWACCEL_LIBRARIES ${CUDA_LIBRARIES})
+ list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS})
+ list(APPEND FFmpeg_HWACCEL_LDFLAGS ${CUDA_LDFLAGS})
+ message(STATUS "CUDA libraries found, hard-linking will be performed")
+ endif(CUDA_FOUND)
+ endif()
+
+ if (VDPAU_FOUND)
+ list(APPEND FFmpeg_HWACCEL_FLAGS
+ --enable-vdpau
+ --enable-hwaccel=h264_vdpau
+ --enable-hwaccel=vp9_vdpau
+ )
+ list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES})
+ list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS})
+ list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS})
+ message(STATUS "vdpau libraries version ${VDPAU_VERSION} found")
+ else()
+ list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
+ endif()
+
+ # `configure` parameters builds only exactly what yuzu needs from FFmpeg
+ # `--disable-vdpau` is needed to avoid linking issues
+ add_custom_command(
+ OUTPUT
+ ${FFmpeg_MAKEFILE}
+ COMMAND
+ /bin/bash ${FFmpeg_PREFIX}/configure
+ --disable-avdevice
+ --disable-avfilter
+ --disable-avformat
+ --disable-doc
+ --disable-everything
+ --disable-ffmpeg
+ --disable-ffprobe
+ --disable-network
+ --disable-postproc
+ --disable-swresample
+ --enable-decoder=h264
+ --enable-decoder=vp8
+ --enable-decoder=vp9
+ --cc="${CMAKE_C_COMPILER}"
+ --cxx="${CMAKE_CXX_COMPILER}"
+ ${FFmpeg_HWACCEL_FLAGS}
+ WORKING_DIRECTORY
+ ${FFmpeg_BUILD_DIR}
+ )
+ unset(FFmpeg_HWACCEL_FLAGS)
+
+ # Workaround for Ubuntu 18.04's older version of make not being able to call make as a child
+ # with context of the jobserver. Also helps ninja users.
+ execute_process(
+ COMMAND
+ nproc
+ OUTPUT_VARIABLE
+ SYSTEM_THREADS)
+
+ set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES})
+ add_custom_command(
+ OUTPUT
+ ${FFmpeg_BUILD_LIBRARIES}
+ COMMAND
+ make -j${SYSTEM_THREADS}
+ WORKING_DIRECTORY
+ ${FFmpeg_BUILD_DIR}
+ )
+
+ set(FFmpeg_INCLUDE_DIR
+ "${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR};${FFmpeg_HWACCEL_INCLUDE_DIRS}"
+ CACHE PATH "Path to FFmpeg headers" FORCE)
+
+ set(FFmpeg_LDFLAGS
+ "${FFmpeg_HWACCEL_LDFLAGS}"
+ CACHE STRING "FFmpeg linker flags" FORCE)
+
+ # ALL makes this custom target build every time
+ # but it won't actually build if the DEPENDS parameter is up to date
+ add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE})
+ add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_BUILD_LIBRARIES} ffmpeg-configure)
+ link_libraries(${FFmpeg_LIBVA_LIBRARIES})
+ set(FFmpeg_LIBRARIES ${FFmpeg_BUILD_LIBRARIES} ${FFmpeg_HWACCEL_LIBRARIES}
+ CACHE PATH "Paths to FFmpeg libraries" FORCE)
+ unset(FFmpeg_BUILD_LIBRARIES)
+ unset(FFmpeg_HWACCEL_FLAGS)
+ unset(FFmpeg_HWACCEL_INCLUDE_DIRS)
+ unset(FFmpeg_HWACCEL_LDFLAGS)
+ unset(FFmpeg_HWACCEL_LIBRARIES)
+
+ if (FFmpeg_FOUND)
+ message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}")
+ else()
+ message(FATAL_ERROR "FFmpeg not found")
+ endif()
+else(WIN32)
+ # Use yuzu FFmpeg binaries
+ set(FFmpeg_EXT_NAME "ffmpeg-4.4")
+ set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
+ download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
+ set(FFmpeg_FOUND YES)
+ set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE)
+ set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE)
+ set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE)
+ set(FFmpeg_DLL_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE)
+ set(FFmpeg_LIBRARIES
+ ${FFmpeg_LIBRARY_DIR}/swscale.lib
+ ${FFmpeg_LIBRARY_DIR}/avcodec.lib
+ ${FFmpeg_LIBRARY_DIR}/avutil.lib
+ CACHE PATH "Paths to FFmpeg libraries" FORCE)
+ # exported variables
+ set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE)
+ set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE)
+ set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE)
+ set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
+endif(WIN32)
+
+unset(FFmpeg_COMPONENTS)
diff --git a/externals/ffmpeg/ffmpeg b/externals/ffmpeg/ffmpeg
new file mode 160000
+Subproject dc91b913b6260e85e1304c74ff7bb3c22a8c9fb
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 49bed614a..698c4f912 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -265,8 +265,6 @@ add_library(core STATIC
hle/kernel/svc_wrap.h
hle/kernel/time_manager.cpp
hle/kernel/time_manager.h
- hle/lock.cpp
- hle/lock.h
hle/result.h
hle/service/acc/acc.cpp
hle/service/acc/acc.h
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index 685ec080c..08f8af551 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -161,7 +161,10 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
motion.rotation = emulated.GetGyroscope();
motion.orientation = emulated.GetOrientation();
motion.quaternion = emulated.GetQuaternion();
+ motion.gyro_bias = emulated.GetGyroBias();
motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
+ // Find what is this value
+ motion.verticalization_error = 0.0f;
TriggerOnChange(ConsoleTriggerType::Motion);
}
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h
index 3afd284d5..707419102 100644
--- a/src/core/hid/emulated_console.h
+++ b/src/core/hid/emulated_console.h
@@ -50,6 +50,8 @@ struct ConsoleMotion {
Common::Vec3f rotation{};
std::array<Common::Vec3f, 3> orientation{};
Common::Quaternion<f32> quaternion{};
+ Common::Vec3f gyro_bias{};
+ f32 verticalization_error{};
bool is_at_rest{};
};
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 93372445b..ff9d7a7e3 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -843,23 +843,18 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
}
bool EmulatedController::TestVibration(std::size_t device_index) {
- if (device_index >= output_devices.size()) {
- return false;
- }
- if (!output_devices[device_index]) {
- return false;
- }
-
- // Send a slight vibration to test for rumble support
- constexpr Common::Input::VibrationStatus status = {
+ static constexpr VibrationValue test_vibration = {
.low_amplitude = 0.001f,
.low_frequency = 160.0f,
.high_amplitude = 0.001f,
.high_frequency = 320.0f,
- .type = Common::Input::VibrationAmplificationType::Linear,
};
- return output_devices[device_index]->SetVibration(status) ==
- Common::Input::VibrationError::None;
+
+ // Send a slight vibration to test for rumble support
+ SetVibration(device_index, test_vibration);
+
+ // Stop any vibration and return the result
+ return SetVibration(device_index, DEFAULT_VIBRATION_VALUE);
}
void EmulatedController::SetLedPattern() {
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 7c12f01fc..4eca68533 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -496,6 +496,13 @@ struct VibrationValue {
};
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
+constexpr VibrationValue DEFAULT_VIBRATION_VALUE{
+ .low_amplitude = 0.0f,
+ .low_frequency = 160.0f,
+ .high_amplitude = 0.0f,
+ .high_frequency = 320.0f,
+};
+
// This is nn::hid::VibrationDeviceInfo
struct VibrationDeviceInfo {
VibrationDeviceType type{};
diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp
index c25fea966..a23f192d7 100644
--- a/src/core/hid/motion_input.cpp
+++ b/src/core/hid/motion_input.cpp
@@ -23,11 +23,11 @@ void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
}
void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
- gyro = gyroscope - gyro_drift;
+ gyro = gyroscope - gyro_bias;
// Auto adjust drift to minimize drift
if (!IsMoving(0.1f)) {
- gyro_drift = (gyro_drift * 0.9999f) + (gyroscope * 0.0001f);
+ gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
}
if (gyro.Length2() < gyro_threshold) {
@@ -41,8 +41,8 @@ void MotionInput::SetQuaternion(const Common::Quaternion<f32>& quaternion) {
quat = quaternion;
}
-void MotionInput::SetGyroDrift(const Common::Vec3f& drift) {
- gyro_drift = drift;
+void MotionInput::SetGyroBias(const Common::Vec3f& bias) {
+ gyro_bias = bias;
}
void MotionInput::SetGyroThreshold(f32 threshold) {
@@ -192,6 +192,10 @@ Common::Vec3f MotionInput::GetGyroscope() const {
return gyro;
}
+Common::Vec3f MotionInput::GetGyroBias() const {
+ return gyro_bias;
+}
+
Common::Quaternion<f32> MotionInput::GetQuaternion() const {
return quat;
}
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h
index 5b5b420bb..bca4520fa 100644
--- a/src/core/hid/motion_input.h
+++ b/src/core/hid/motion_input.h
@@ -24,7 +24,7 @@ public:
void SetAcceleration(const Common::Vec3f& acceleration);
void SetGyroscope(const Common::Vec3f& gyroscope);
void SetQuaternion(const Common::Quaternion<f32>& quaternion);
- void SetGyroDrift(const Common::Vec3f& drift);
+ void SetGyroBias(const Common::Vec3f& bias);
void SetGyroThreshold(f32 threshold);
void EnableReset(bool reset);
@@ -36,6 +36,7 @@ public:
[[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const;
[[nodiscard]] Common::Vec3f GetAcceleration() const;
[[nodiscard]] Common::Vec3f GetGyroscope() const;
+ [[nodiscard]] Common::Vec3f GetGyroBias() const;
[[nodiscard]] Common::Vec3f GetRotations() const;
[[nodiscard]] Common::Quaternion<f32> GetQuaternion() const;
@@ -69,7 +70,7 @@ private:
Common::Vec3f gyro;
// Vector to be substracted from gyro measurements
- Common::Vec3f gyro_drift;
+ Common::Vec3f gyro_bias;
// Minimum gyro amplitude to detect if the device is moving
f32 gyro_threshold = 0.0f;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 90dda40dc..aee313995 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -28,7 +28,6 @@
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h"
-#include "core/hle/lock.h"
#include "core/memory.h"
namespace Kernel {
@@ -543,7 +542,6 @@ void KProcess::FreeTLSRegion(VAddr tls_address) {
}
void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) {
- std::lock_guard lock{HLE::g_hle_lock};
const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
KMemoryPermission permission) {
page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 2e4e4cb1c..1225e1fba 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -182,7 +182,10 @@ struct KernelCore::Impl {
// Shutdown all processes.
if (current_process) {
current_process->Finalize();
- current_process->Close();
+ // current_process->Close();
+ // TODO: The current process should be destroyed based on accurate ref counting after
+ // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
+ current_process->Destroy();
current_process = nullptr;
}
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index a9f7438ea..bb9475c56 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -41,7 +41,6 @@
#include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/svc_types.h"
#include "core/hle/kernel/svc_wrap.h"
-#include "core/hle/lock.h"
#include "core/hle/result.h"
#include "core/memory.h"
#include "core/reporter.h"
@@ -137,7 +136,6 @@ enum class ResourceLimitValueType {
/// Set the process heap to a given Size. It can both extend and shrink the heap.
static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
// Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB.
@@ -168,7 +166,6 @@ static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_s
static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask,
u32 attribute) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_DEBUG(Kernel_SVC,
"called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
size, mask, attribute);
@@ -212,7 +209,6 @@ static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 si
/// Maps a memory range into a different range.
static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size);
@@ -232,7 +228,6 @@ static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr,
/// Unmaps a region that was previously mapped with svcMapMemory
static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size);
@@ -642,7 +637,6 @@ static void OutputDebugString(Core::System& system, VAddr address, u64 len) {
/// Gets system/memory information for the current process
static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle,
u64 info_sub_id) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
info_sub_id, handle);
@@ -924,7 +918,6 @@ static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_h
/// Maps memory at a desired address
static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
if (!Common::Is4KBAligned(addr)) {
@@ -978,7 +971,6 @@ static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size)
/// Unmaps memory previously mapped via MapPhysicalMemory
static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
if (!Common::Is4KBAligned(addr)) {
@@ -1520,7 +1512,6 @@ static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_han
static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,
VAddr page_info_address, Handle process_handle,
VAddr address) {
- std::lock_guard lock{HLE::g_hle_lock};
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
diff --git a/src/core/hle/lock.cpp b/src/core/hle/lock.cpp
deleted file mode 100644
index be4bfce3b..000000000
--- a/src/core/hle/lock.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <core/hle/lock.h>
-
-namespace HLE {
-std::recursive_mutex g_hle_lock;
-}
diff --git a/src/core/hle/lock.h b/src/core/hle/lock.h
deleted file mode 100644
index 5c99fe996..000000000
--- a/src/core/hle/lock.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <mutex>
-
-namespace HLE {
-/*
- * Synchronizes access to the internal HLE kernel structures, it is acquired when a guest
- * application thread performs a syscall. It should be acquired by any host threads that read or
- * modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes
- * to the emulated memory is not protected by this mutex, and should be avoided in any threads other
- * than the CPU thread.
- */
-extern std::recursive_mutex g_hle_lock;
-} // namespace HLE
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index 4c7d3bb6e..ee49edbb9 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -6,7 +6,6 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
-#include "core/hle/lock.h"
#include "core/hle/service/bcat/backend/backend.h"
namespace Service::BCAT {
@@ -29,10 +28,6 @@ DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() {
return impl;
}
-void ProgressServiceBackend::SetNeedHLELock(bool need) {
- need_hle_lock = need;
-}
-
void ProgressServiceBackend::SetTotalSize(u64 size) {
impl.total_bytes = size;
SignalUpdate();
@@ -88,12 +83,7 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) {
}
void ProgressServiceBackend::SignalUpdate() {
- if (need_hle_lock) {
- std::lock_guard lock(HLE::g_hle_lock);
- update_event->GetWritableEvent().Signal();
- } else {
- update_event->GetWritableEvent().Signal();
- }
+ update_event->GetWritableEvent().Signal();
}
Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {}
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h
index 59c6d4740..63833c927 100644
--- a/src/core/hle/service/bcat/backend/backend.h
+++ b/src/core/hle/service/bcat/backend/backend.h
@@ -71,10 +71,6 @@ class ProgressServiceBackend {
public:
~ProgressServiceBackend();
- // Clients should call this with true if any of the functions are going to be called from a
- // non-HLE thread and this class need to lock the hle mutex. (default is false)
- void SetNeedHLELock(bool need);
-
// Sets the number of bytes total in the entire download.
void SetTotalSize(u64 size);
@@ -109,7 +105,6 @@ private:
DeliveryCacheProgressImpl impl{};
Kernel::KEvent* update_event;
- bool need_hle_lock = false;
};
// A class representing an abstract backend for BCAT functionality.
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
index f0f3105dc..a727b3582 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
@@ -33,15 +33,14 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
const auto& last_entry = seven_sixaxis_lifo.ReadCurrentEntry().state;
next_seven_sixaxis_state.sampling_number = last_entry.sampling_number + 1;
- // Try to read sixaxis sensor states
const auto motion_status = console->GetMotion();
+ last_global_timestamp = core_timing.GetGlobalTimeNs().count();
- console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
-
+ // This value increments every time the switch goes to sleep
+ next_seven_sixaxis_state.unknown = 1;
+ next_seven_sixaxis_state.timestamp = last_global_timestamp - last_saved_timestamp;
next_seven_sixaxis_state.accel = motion_status.accel;
- // Zero gyro values as they just mess up with the camera
- // Note: Probably a correct sensivity setting must be set
- next_seven_sixaxis_state.gyro = {};
+ next_seven_sixaxis_state.gyro = motion_status.gyro;
next_seven_sixaxis_state.quaternion = {
{
motion_status.quaternion.xyz.y,
@@ -52,9 +51,9 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
};
console_six_axis.sampling_number++;
- // TODO(German77): Find the purpose of those values
- console_six_axis.verticalization_error = 0.0f;
- console_six_axis.gyro_bias = {0.0f, 0.0f, 0.0f};
+ console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
+ console_six_axis.verticalization_error = motion_status.verticalization_error;
+ console_six_axis.gyro_bias = motion_status.gyro_bias;
// Update console six axis shared memory
std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis));
@@ -69,7 +68,6 @@ void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem) {
}
void Controller_ConsoleSixAxis::ResetTimestamp() {
- seven_sixaxis_lifo.buffer_count = 0;
- seven_sixaxis_lifo.buffer_tail = 0;
+ last_saved_timestamp = last_global_timestamp;
}
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h
index 279241858..26d153f0c 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.h
@@ -39,8 +39,9 @@ public:
private:
struct SevenSixAxisState {
- INSERT_PADDING_WORDS(4); // unused
- s64 sampling_number{};
+ INSERT_PADDING_WORDS(2); // unused
+ u64 timestamp{};
+ u64 sampling_number{};
u64 unknown{};
Common::Vec3f accel{};
Common::Vec3f gyro{};
@@ -52,9 +53,10 @@ private:
struct ConsoleSharedMemory {
u64 sampling_number{};
bool is_seven_six_axis_sensor_at_rest{};
- INSERT_PADDING_BYTES(4); // padding
+ INSERT_PADDING_BYTES(3); // padding
f32 verticalization_error{};
Common::Vec3f gyro_bias{};
+ INSERT_PADDING_BYTES(4); // padding
};
static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
@@ -64,6 +66,8 @@ private:
Core::HID::EmulatedConsole* console;
u8* transfer_memory = nullptr;
bool is_transfer_memory_set = false;
+ u64 last_saved_timestamp{};
+ u64 last_global_timestamp{};
ConsoleSharedMemory console_six_axis{};
SevenSixAxisState next_seven_sixaxis_state{};
};
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 2705e9dcb..e5c951e06 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -66,9 +66,9 @@ Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_,
auto& controller = controller_data[i];
controller.device = hid_core.GetEmulatedControllerByIndex(i);
controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
- DEFAULT_VIBRATION_VALUE;
+ Core::HID::DEFAULT_VIBRATION_VALUE;
controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex].latest_vibration_value =
- DEFAULT_VIBRATION_VALUE;
+ Core::HID::DEFAULT_VIBRATION_VALUE;
Core::HID::ControllerUpdateCallback engine_callback{
.on_change = [this,
i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); },
@@ -781,7 +781,8 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f};
controller.device->SetVibration(device_index, vibration);
// Then reset the vibration value to its default value.
- controller.vibration[device_index].latest_vibration_value = DEFAULT_VIBRATION_VALUE;
+ controller.vibration[device_index].latest_vibration_value =
+ Core::HID::DEFAULT_VIBRATION_VALUE;
}
return false;
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 63281cb35..6b2872bad 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -90,13 +90,6 @@ public:
Default = 3,
};
- static constexpr Core::HID::VibrationValue DEFAULT_VIBRATION_VALUE{
- .low_amplitude = 0.0f,
- .low_frequency = 160.0f,
- .high_amplitude = 0.0f,
- .high_frequency = 320.0f,
- };
-
void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
Core::HID::NpadStyleTag GetSupportedStyleSet() const;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 7163e1a4e..6e12381fb 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -1404,7 +1404,7 @@ void Hid::SendVibrationGcErmCommand(Kernel::HLERequestContext& ctx) {
.high_frequency = 0.0f,
};
default:
- return Controller_NPad::DEFAULT_VIBRATION_VALUE;
+ return Core::HID::DEFAULT_VIBRATION_VALUE;
}
}();
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 693ffc71a..761d0d3c6 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -9,7 +9,6 @@
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
-#include "core/hle/lock.h"
#include "core/hle/service/nfp/nfp.h"
#include "core/hle/service/nfp/nfp_user.h"
@@ -337,7 +336,6 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
}
bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
- std::lock_guard lock{HLE::g_hle_lock};
if (buffer.size() < sizeof(AmiiboFile)) {
return false;
}
diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp
index 3ae9e6e0e..99ed34b00 100644
--- a/src/core/loader/kip.cpp
+++ b/src/core/loader/kip.cpp
@@ -71,7 +71,6 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, 0x1FE00000,
kip->GetKernelCapabilities());
- const VAddr base_address = process.PageTable().GetCodeRegionStart();
Kernel::CodeSet codeset;
Kernel::PhysicalMemory program_image;
@@ -91,7 +90,14 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize());
codeset.DataSegment().size += kip->GetBSSSize();
+ // Setup the process code layout
+ if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size())
+ .IsError()) {
+ return {ResultStatus::ErrorNotInitialized, {}};
+ }
+
codeset.memory = std::move(program_image);
+ const VAddr base_address = process.PageTable().GetCodeRegionStart();
process.LoadModule(std::move(codeset), base_address);
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);
diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp
index 4ab991a7d..a1ce4525d 100644
--- a/src/input_common/drivers/udp_client.cpp
+++ b/src/input_common/drivers/udp_client.cpp
@@ -536,42 +536,46 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
std::function<void(u16, u16, u16, u16)> data_callback) {
std::thread([=, this] {
+ u16 min_x{UINT16_MAX};
+ u16 min_y{UINT16_MAX};
+ u16 max_x{};
+ u16 max_y{};
+
Status current_status{Status::Initialized};
- SocketCallback callback{
- [](Response::Version) {}, [](Response::PortInfo) {},
- [&](Response::PadData data) {
- static constexpr u16 CALIBRATION_THRESHOLD = 100;
- static constexpr u16 MAX_VALUE = UINT16_MAX;
-
- if (current_status == Status::Initialized) {
- // Receiving data means the communication is ready now
- current_status = Status::Ready;
- status_callback(current_status);
- }
- const auto& touchpad_0 = data.touch[0];
- if (touchpad_0.is_active == 0) {
- return;
- }
- LOG_DEBUG(Input, "Current touch: {} {}", touchpad_0.x, touchpad_0.y);
- const u16 min_x = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.x));
- const u16 min_y = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.y));
- if (current_status == Status::Ready) {
- // First touch - min data (min_x/min_y)
- current_status = Status::Stage1Completed;
- status_callback(current_status);
- }
- if (touchpad_0.x - min_x > CALIBRATION_THRESHOLD &&
- touchpad_0.y - min_y > CALIBRATION_THRESHOLD) {
- // Set the current position as max value and finishes configuration
- const u16 max_x = touchpad_0.x;
- const u16 max_y = touchpad_0.y;
- current_status = Status::Completed;
- data_callback(min_x, min_y, max_x, max_y);
- status_callback(current_status);
-
- complete_event.Set();
- }
- }};
+ SocketCallback callback{[](Response::Version) {}, [](Response::PortInfo) {},
+ [&](Response::PadData data) {
+ constexpr u16 CALIBRATION_THRESHOLD = 100;
+
+ if (current_status == Status::Initialized) {
+ // Receiving data means the communication is ready now
+ current_status = Status::Ready;
+ status_callback(current_status);
+ }
+ if (data.touch[0].is_active == 0) {
+ return;
+ }
+ LOG_DEBUG(Input, "Current touch: {} {}", data.touch[0].x,
+ data.touch[0].y);
+ min_x = std::min(min_x, static_cast<u16>(data.touch[0].x));
+ min_y = std::min(min_y, static_cast<u16>(data.touch[0].y));
+ if (current_status == Status::Ready) {
+ // First touch - min data (min_x/min_y)
+ current_status = Status::Stage1Completed;
+ status_callback(current_status);
+ }
+ if (data.touch[0].x - min_x > CALIBRATION_THRESHOLD &&
+ data.touch[0].y - min_y > CALIBRATION_THRESHOLD) {
+ // Set the current position as max value and finishes
+ // configuration
+ max_x = data.touch[0].x;
+ max_y = data.touch[0].y;
+ current_status = Status::Completed;
+ data_callback(min_x, min_y, max_x, max_y);
+ status_callback(current_status);
+
+ complete_event.Set();
+ }
+ }};
Socket socket{host, port, std::move(callback)};
std::thread worker_thread{SocketLoop, &socket};
complete_event.Wait();
diff --git a/src/input_common/helpers/udp_protocol.h b/src/input_common/helpers/udp_protocol.h
index bcba12c58..2d5d54ddb 100644
--- a/src/input_common/helpers/udp_protocol.h
+++ b/src/input_common/helpers/udp_protocol.h
@@ -54,6 +54,18 @@ struct Message {
template <typename T>
constexpr Type GetMessageType();
+template <typename T>
+Message<T> CreateMessage(const u32 magic, const T data, const u32 sender_id) {
+ boost::crc_32_type crc;
+ Header header{
+ magic, PROTOCOL_VERSION, sizeof(T) + sizeof(Type), 0, sender_id, GetMessageType<T>(),
+ };
+ Message<T> message{header, data};
+ crc.process_bytes(&message, sizeof(Message<T>));
+ message.header.crc = crc.checksum();
+ return message;
+}
+
namespace Request {
enum RegisterFlags : u8 {
@@ -101,14 +113,7 @@ static_assert(std::is_trivially_copyable_v<PadData>,
*/
template <typename T>
Message<T> Create(const T data, const u32 client_id = 0) {
- boost::crc_32_type crc;
- Header header{
- CLIENT_MAGIC, PROTOCOL_VERSION, sizeof(T) + sizeof(Type), 0, client_id, GetMessageType<T>(),
- };
- Message<T> message{header, data};
- crc.process_bytes(&message, sizeof(Message<T>));
- message.header.crc = crc.checksum();
- return message;
+ return CreateMessage(CLIENT_MAGIC, data, client_id);
}
} // namespace Request
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index c4c012f3d..4a20c0768 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -10,11 +10,12 @@ add_executable(tests
core/network/network.cpp
tests.cpp
video_core/buffer_base.cpp
+ input_common/calibration_configuration_job.cpp
)
create_target_directory_groups(tests)
-target_link_libraries(tests PRIVATE common core)
+target_link_libraries(tests PRIVATE common core input_common)
target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads)
add_test(NAME tests COMMAND tests)
diff --git a/src/tests/input_common/calibration_configuration_job.cpp b/src/tests/input_common/calibration_configuration_job.cpp
new file mode 100644
index 000000000..8c77d81e9
--- /dev/null
+++ b/src/tests/input_common/calibration_configuration_job.cpp
@@ -0,0 +1,136 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <array>
+#include <string>
+#include <thread>
+#include <boost/asio.hpp>
+#include <boost/crc.hpp>
+#include <catch2/catch.hpp>
+
+#include "input_common/drivers/udp_client.h"
+#include "input_common/helpers/udp_protocol.h"
+
+class FakeCemuhookServer {
+public:
+ FakeCemuhookServer()
+ : socket(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) {}
+
+ ~FakeCemuhookServer() {
+ is_running = false;
+ boost::system::error_code error_code;
+ socket.shutdown(boost::asio::socket_base::shutdown_both, error_code);
+ socket.close();
+ if (handler.joinable()) {
+ handler.join();
+ }
+ }
+
+ u16 GetPort() {
+ return socket.local_endpoint().port();
+ }
+
+ std::string GetHost() {
+ return socket.local_endpoint().address().to_string();
+ }
+
+ void Run(const std::vector<InputCommon::CemuhookUDP::Response::TouchPad> touch_movement_path) {
+ constexpr size_t HeaderSize = sizeof(InputCommon::CemuhookUDP::Header);
+ constexpr size_t PadDataSize =
+ sizeof(InputCommon::CemuhookUDP::Message<InputCommon::CemuhookUDP::Response::PadData>);
+
+ REQUIRE(touch_movement_path.size() > 0);
+ is_running = true;
+ handler = std::thread([touch_movement_path, this]() {
+ auto current_touch_position = touch_movement_path.begin();
+ while (is_running) {
+ boost::asio::ip::udp::endpoint sender_endpoint;
+ boost::system::error_code error_code;
+ auto received_size = socket.receive_from(boost::asio::buffer(receive_buffer),
+ sender_endpoint, 0, error_code);
+
+ if (received_size < HeaderSize) {
+ continue;
+ }
+
+ InputCommon::CemuhookUDP::Header header{};
+ std::memcpy(&header, receive_buffer.data(), HeaderSize);
+ switch (header.type) {
+ case InputCommon::CemuhookUDP::Type::PadData: {
+ InputCommon::CemuhookUDP::Response::PadData pad_data{};
+ pad_data.touch[0] = *current_touch_position;
+ const auto pad_message = InputCommon::CemuhookUDP::CreateMessage(
+ InputCommon::CemuhookUDP::SERVER_MAGIC, pad_data, 0);
+ std::memcpy(send_buffer.data(), &pad_message, PadDataSize);
+ socket.send_to(boost::asio::buffer(send_buffer, PadDataSize), sender_endpoint,
+ 0, error_code);
+
+ bool can_advance =
+ std::next(current_touch_position) != touch_movement_path.end();
+ if (can_advance) {
+ std::advance(current_touch_position, 1);
+ }
+ break;
+ }
+ case InputCommon::CemuhookUDP::Type::PortInfo:
+ case InputCommon::CemuhookUDP::Type::Version:
+ default:
+ break;
+ }
+ }
+ });
+ }
+
+private:
+ boost::asio::io_service io_service;
+ boost::asio::ip::udp::socket socket;
+ std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> send_buffer;
+ std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> receive_buffer;
+ bool is_running = false;
+ std::thread handler;
+};
+
+TEST_CASE("CalibrationConfigurationJob completed", "[input_common]") {
+ Common::Event complete_event;
+ FakeCemuhookServer server;
+ server.Run({{
+ .is_active = 1,
+ .x = 0,
+ .y = 0,
+ },
+ {
+ .is_active = 1,
+ .x = 200,
+ .y = 200,
+ }});
+
+ InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status{};
+ u16 min_x{};
+ u16 min_y{};
+ u16 max_x{};
+ u16 max_y{};
+ InputCommon::CemuhookUDP::CalibrationConfigurationJob job(
+ server.GetHost(), server.GetPort(),
+ [&status,
+ &complete_event](InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status_) {
+ status = status_;
+ if (status ==
+ InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed) {
+ complete_event.Set();
+ }
+ },
+ [&](u16 min_x_, u16 min_y_, u16 max_x_, u16 max_y_) {
+ min_x = min_x_;
+ min_y = min_y_;
+ max_x = max_x_;
+ max_y = max_y_;
+ });
+
+ complete_event.WaitUntil(std::chrono::system_clock::now() + std::chrono::seconds(10));
+ REQUIRE(status == InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed);
+ REQUIRE(min_x == 0);
+ REQUIRE(min_y == 0);
+ REQUIRE(max_x == 200);
+ REQUIRE(max_y == 200);
+}
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp
index 2a532b883..868b82f9b 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/command_classes/codecs/codec.cpp
@@ -130,6 +130,12 @@ bool Codec::CreateGpuAvDevice() {
}
if (config->methods & HW_CONFIG_METHOD && config->device_type == type) {
av_codec_ctx->pix_fmt = config->pix_fmt;
+ if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) {
+ // skip zero-copy decoders, we don't currently support them
+ LOG_DEBUG(Service_NVDRV, "Skipping decoder {} with unsupported capability {}.",
+ av_hwdevice_get_type_name(type), config->methods);
+ continue;
+ }
LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type));
return true;
}
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 37d5e6a6b..dbf1df79c 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -92,7 +92,7 @@ public:
void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
- void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled) {
+ void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
UNIMPLEMENTED();
}
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 28daacd82..f81c1b233 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -437,39 +437,29 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
glBindTextureUnit(0, fxaa_texture.handle);
}
-
- // Set projection matrix
const std::array ortho_matrix =
MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
- GLuint fragment_handle;
- const auto filter = Settings::values.scaling_filter.GetValue();
- switch (filter) {
- case Settings::ScalingFilter::NearestNeighbor:
- fragment_handle = present_bilinear_fragment.handle;
- break;
- case Settings::ScalingFilter::Bilinear:
- fragment_handle = present_bilinear_fragment.handle;
- break;
- case Settings::ScalingFilter::Bicubic:
- fragment_handle = present_bicubic_fragment.handle;
- break;
- case Settings::ScalingFilter::Gaussian:
- fragment_handle = present_gaussian_fragment.handle;
- break;
- case Settings::ScalingFilter::ScaleForce:
- fragment_handle = present_scaleforce_fragment.handle;
- break;
- case Settings::ScalingFilter::Fsr:
- LOG_WARNING(
- Render_OpenGL,
- "FidelityFX FSR Super Sampling is not supported in OpenGL, changing to ScaleForce");
- fragment_handle = present_scaleforce_fragment.handle;
- break;
- default:
- fragment_handle = present_bilinear_fragment.handle;
- break;
- }
+ const auto fragment_handle = [this]() {
+ switch (Settings::values.scaling_filter.GetValue()) {
+ case Settings::ScalingFilter::NearestNeighbor:
+ case Settings::ScalingFilter::Bilinear:
+ return present_bilinear_fragment.handle;
+ case Settings::ScalingFilter::Bicubic:
+ return present_bicubic_fragment.handle;
+ case Settings::ScalingFilter::Gaussian:
+ return present_gaussian_fragment.handle;
+ case Settings::ScalingFilter::ScaleForce:
+ return present_scaleforce_fragment.handle;
+ case Settings::ScalingFilter::Fsr:
+ LOG_WARNING(
+ Render_OpenGL,
+ "FidelityFX Super Resolution is not supported in OpenGL, changing to ScaleForce");
+ return present_scaleforce_fragment.handle;
+ default:
+ return present_bilinear_fragment.handle;
+ }
+ }();
program_manager.BindPresentPrograms(present_vertex.handle, fragment_handle);
glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE,
ortho_matrix.data());
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp
index 9a38b6b34..cd5995897 100644
--- a/src/video_core/renderer_vulkan/blit_image.cpp
+++ b/src/video_core/renderer_vulkan/blit_image.cpp
@@ -4,6 +4,7 @@
#include <algorithm>
+#include "common/settings.h"
#include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h"
#include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h"
#include "video_core/host_shaders/convert_depth_to_float_frag_spv.h"
@@ -335,6 +336,17 @@ void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Regi
cmdbuf.SetScissor(0, scissor);
cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants);
}
+
+VkExtent2D GetConversionExtent(const ImageView& src_image_view) {
+ const auto& resolution = Settings::values.resolution_info;
+ const bool is_rescaled = src_image_view.IsRescaled();
+ u32 width = src_image_view.size.width;
+ u32 height = src_image_view.size.height;
+ return VkExtent2D{
+ .width = is_rescaled ? resolution.ScaleUp(width) : width,
+ .height = is_rescaled ? resolution.ScaleUp(height) : height,
+ };
+}
} // Anonymous namespace
BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_,
@@ -425,61 +437,52 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
}
void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view, u32 up_scale,
- u32 down_shift) {
+ const ImageView& src_image_view) {
ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift);
+ Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view);
}
void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view, u32 up_scale,
- u32 down_shift) {
+ const ImageView& src_image_view) {
ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift);
+ Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view);
}
void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view, u32 up_scale,
- u32 down_shift) {
+ const ImageView& src_image_view) {
ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift);
+ Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view);
}
void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view, u32 up_scale,
- u32 down_shift) {
+ const ImageView& src_image_view) {
ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift);
+ Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view);
}
void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
- ImageView& src_image_view, u32 up_scale, u32 down_shift) {
+ const ImageView& src_image_view) {
ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
- convert_abgr8_to_d24s8_frag, true);
- ConvertColor(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale,
- down_shift);
+ convert_abgr8_to_d24s8_frag);
+ Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
}
void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
- ImageView& src_image_view, u32 up_scale, u32 down_shift) {
+ ImageView& src_image_view) {
ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
- convert_d24s8_to_abgr8_frag, false);
- ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view, up_scale,
- down_shift);
+ convert_d24s8_to_abgr8_frag);
+ ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view);
}
void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view, u32 up_scale, u32 down_shift) {
+ const ImageView& src_image_view) {
const VkPipelineLayout layout = *one_texture_pipeline_layout;
const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
const VkSampler sampler = *nearest_sampler;
- const VkExtent2D extent{
- .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U),
- .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U),
- };
+ const VkExtent2D extent = GetConversionExtent(src_image_view);
+
scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift,
- this](vk::CommandBuffer cmdbuf) {
+ scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) {
const VkOffset2D offset{
.x = 0,
.y = 0,
@@ -563,18 +566,16 @@ void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_f
}
void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
- ImageView& src_image_view, u32 up_scale, u32 down_shift) {
+ ImageView& src_image_view) {
const VkPipelineLayout layout = *two_textures_pipeline_layout;
const VkImageView src_depth_view = src_image_view.DepthView();
const VkImageView src_stencil_view = src_image_view.StencilView();
const VkSampler sampler = *nearest_sampler;
- const VkExtent2D extent{
- .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U),
- .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U),
- };
+ const VkExtent2D extent = GetConversionExtent(src_image_view);
+
scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, up_scale,
- down_shift, this](vk::CommandBuffer cmdbuf) {
+ scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent,
+ this](vk::CommandBuffer cmdbuf) {
const VkOffset2D offset{
.x = 0,
.y = 0,
@@ -695,11 +696,14 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip
return *blit_depth_stencil_pipelines.back();
}
-void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
+void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass,
+ bool is_target_depth) {
if (pipeline) {
return;
}
- const std::array stages = MakeStages(*full_screen_vert, *convert_depth_to_float_frag);
+ VkShaderModule frag_shader =
+ is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag;
+ const std::array stages = MakeStages(*full_screen_vert, frag_shader);
pipeline = device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
@@ -712,8 +716,9 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend
.pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pDepthStencilState = nullptr,
- .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
+ .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr,
+ .pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO
+ : &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.layout = *one_texture_pipeline_layout,
.renderPass = renderpass,
@@ -723,37 +728,17 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend
});
}
+void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
+ ConvertPipeline(pipeline, renderpass, false);
+}
+
void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
- if (pipeline) {
- return;
- }
- const std::array stages = MakeStages(*full_screen_vert, *convert_float_to_depth_frag);
- pipeline = device.GetLogical().CreateGraphicsPipeline({
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .stageCount = static_cast<u32>(stages.size()),
- .pStages = stages.data(),
- .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pTessellationState = nullptr,
- .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
- .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO,
- .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .layout = *one_texture_pipeline_layout,
- .renderPass = renderpass,
- .subpass = 0,
- .basePipelineHandle = VK_NULL_HANDLE,
- .basePipelineIndex = 0,
- });
+ ConvertPipeline(pipeline, renderpass, true);
}
void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module, bool is_target_depth,
- bool single_texture) {
+ vk::ShaderModule& module, bool single_texture,
+ bool is_target_depth) {
if (pipeline) {
return;
}
@@ -782,13 +767,13 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren
}
void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module, bool single_texture) {
- ConvertPipelineEx(pipeline, renderpass, module, false, single_texture);
+ vk::ShaderModule& module) {
+ ConvertPipelineEx(pipeline, renderpass, module, false, false);
}
void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module, bool single_texture) {
- ConvertPipelineEx(pipeline, renderpass, module, true, single_texture);
+ vk::ShaderModule& module) {
+ ConvertPipelineEx(pipeline, renderpass, module, true, true);
}
} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h
index b1a717090..1d9f61a52 100644
--- a/src/video_core/renderer_vulkan/blit_image.h
+++ b/src/video_core/renderer_vulkan/blit_image.h
@@ -44,50 +44,46 @@ public:
const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter,
Tegra::Engines::Fermi2D::Operation operation);
- void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
- u32 up_scale, u32 down_shift);
+ void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
- void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
- u32 up_scale, u32 down_shift);
+ void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
- void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
- u32 up_scale, u32 down_shift);
+ void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
- void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
- u32 up_scale, u32 down_shift);
+ void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
- void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
- u32 up_scale, u32 down_shift);
+ void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view);
- void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
- u32 up_scale, u32 down_shift);
+ void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view);
private:
void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view, u32 up_scale, u32 down_shift);
+ const ImageView& src_image_view);
void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
ImageView& src_image_view, u32 up_scale, u32 down_shift);
void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
- ImageView& src_image_view, u32 up_scale, u32 down_shift);
+ ImageView& src_image_view);
[[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key);
[[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key);
+ void ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, bool is_target_depth);
+
void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass);
void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass);
void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module, bool is_target_depth, bool single_texture);
+ vk::ShaderModule& module, bool single_texture, bool is_target_depth);
void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module, bool single_texture);
+ vk::ShaderModule& module);
void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module, bool single_texture);
+ vk::ShaderModule& module);
const Device& device;
VKScheduler& scheduler;
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 1e447e621..c71a1f44d 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -391,28 +391,23 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
.offset = {0, 0},
.extent = size,
};
- const auto filter = Settings::values.scaling_filter.GetValue();
cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
- switch (filter) {
- case Settings::ScalingFilter::NearestNeighbor:
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline);
- break;
- case Settings::ScalingFilter::Bilinear:
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline);
- break;
- case Settings::ScalingFilter::Bicubic:
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bicubic_pipeline);
- break;
- case Settings::ScalingFilter::Gaussian:
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *gaussian_pipeline);
- break;
- case Settings::ScalingFilter::ScaleForce:
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *scaleforce_pipeline);
- break;
- default:
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline);
- break;
- }
+ auto graphics_pipeline = [this]() {
+ switch (Settings::values.scaling_filter.GetValue()) {
+ case Settings::ScalingFilter::NearestNeighbor:
+ case Settings::ScalingFilter::Bilinear:
+ return *bilinear_pipeline;
+ case Settings::ScalingFilter::Bicubic:
+ return *bicubic_pipeline;
+ case Settings::ScalingFilter::Gaussian:
+ return *gaussian_pipeline;
+ case Settings::ScalingFilter::ScaleForce:
+ return *scaleforce_pipeline;
+ default:
+ return *bilinear_pipeline;
+ }
+ }();
+ cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline);
cmdbuf.SetViewport(0, viewport);
cmdbuf.SetScissor(0, scissor);
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 197cba8e3..1941170cb 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1057,37 +1057,37 @@ void TextureCacheRuntime::BlitImage(Framebuffer* dst_framebuffer, ImageView& dst
});
}
-void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view,
- bool rescaled) {
- const u32 up_scale = rescaled ? resolution.up_scale : 1;
- const u32 down_shift = rescaled ? resolution.down_shift : 0;
+void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
switch (dst_view.format) {
case PixelFormat::R16_UNORM:
if (src_view.format == PixelFormat::D16_UNORM) {
- return blit_image_helper.ConvertD16ToR16(dst, src_view, up_scale, down_shift);
+ return blit_image_helper.ConvertD16ToR16(dst, src_view);
}
break;
case PixelFormat::A8B8G8R8_UNORM:
if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) {
- return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift);
+ return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view);
}
break;
case PixelFormat::R32_FLOAT:
if (src_view.format == PixelFormat::D32_FLOAT) {
- return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift);
+ return blit_image_helper.ConvertD32ToR32(dst, src_view);
}
break;
case PixelFormat::D16_UNORM:
if (src_view.format == PixelFormat::R16_UNORM) {
- return blit_image_helper.ConvertR16ToD16(dst, src_view, up_scale, down_shift);
+ return blit_image_helper.ConvertR16ToD16(dst, src_view);
}
break;
case PixelFormat::S8_UINT_D24_UNORM:
- return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift);
+ if (src_view.format == PixelFormat::A8B8G8R8_UNORM ||
+ src_view.format == PixelFormat::B8G8R8A8_UNORM) {
+ return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view);
+ }
break;
case PixelFormat::D32_FLOAT:
if (src_view.format == PixelFormat::R32_FLOAT) {
- return blit_image_helper.ConvertR32ToD32(dst, src_view, up_scale, down_shift);
+ return blit_image_helper.ConvertR32ToD32(dst, src_view);
}
break;
default:
@@ -1329,6 +1329,10 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
}
}
+bool Image::IsRescaled() const noexcept {
+ return True(flags & ImageFlagBits::Rescaled);
+}
+
bool Image::ScaleUp(bool ignore) {
if (True(flags & ImageFlagBits::Rescaled)) {
return false;
@@ -1469,7 +1473,8 @@ bool Image::BlitScaleHelper(bool scale_up) {
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info,
ImageId image_id_, Image& image)
: VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device},
- image_handle{image.Handle()}, samples{ConvertSampleCount(image.info.num_samples)} {
+ src_image{&image}, image_handle{image.Handle()},
+ samples(ConvertSampleCount(image.info.num_samples)) {
using Shader::TextureType;
const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info);
@@ -1607,6 +1612,13 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
return *view;
}
+bool ImageView::IsRescaled() const noexcept {
+ if (!src_image) {
+ return false;
+ }
+ return src_image->IsRescaled();
+}
+
vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) {
return device->GetLogical().CreateImageView({
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 753e3e8a1..c592f2666 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -65,7 +65,7 @@ public:
void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
- void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled);
+ void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view);
bool CanAccelerateImageUpload(Image&) const noexcept {
return false;
@@ -139,6 +139,8 @@ public:
return std::exchange(initialized, true);
}
+ bool IsRescaled() const noexcept;
+
bool ScaleUp(bool ignore = false);
bool ScaleDown(bool ignore = false);
@@ -189,6 +191,8 @@ public:
[[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type,
Shader::ImageFormat image_format);
+ [[nodiscard]] bool IsRescaled() const noexcept;
+
[[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept {
return *image_views[static_cast<size_t>(texture_type)];
}
@@ -222,6 +226,8 @@ private:
[[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask);
const Device* device = nullptr;
+ const Image* src_image{};
+
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views;
std::unique_ptr<StorageViews> storage_views;
vk::ImageView depth_view;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 5aaeb16ca..2e19fced2 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1855,9 +1855,20 @@ void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<Imag
.height = std::min(dst_view.size.height, src_view.size.height),
.depth = std::min(dst_view.size.depth, src_view.size.depth),
};
- UNIMPLEMENTED_IF(copy.extent != expected_size);
+ const Extent3D scaled_extent = [is_rescaled, expected_size]() {
+ if (!is_rescaled) {
+ return expected_size;
+ }
+ const auto& resolution = Settings::values.resolution_info;
+ return Extent3D{
+ .width = resolution.ScaleUp(expected_size.width),
+ .height = resolution.ScaleUp(expected_size.height),
+ .depth = expected_size.depth,
+ };
+ }();
+ UNIMPLEMENTED_IF(copy.extent != scaled_extent);
- runtime.ConvertImage(dst_framebuffer, dst_view, src_view, is_rescaled);
+ runtime.ConvertImage(dst_framebuffer, dst_view, src_view);
}
}
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index c5685db2e..c6222b571 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -12,7 +12,6 @@
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hid/hid_types.h"
-#include "core/hle/lock.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/sm/sm.h"
@@ -664,7 +663,5 @@ void QtControllerSelector::ReconfigureControllers(
}
void QtControllerSelector::MainWindowReconfigureFinished() {
- // Acquire the HLE mutex
- std::lock_guard lock(HLE::g_hle_lock);
callback();
}
diff --git a/src/yuzu/applets/qt_error.cpp b/src/yuzu/applets/qt_error.cpp
index 45cf64603..879e73660 100644
--- a/src/yuzu/applets/qt_error.cpp
+++ b/src/yuzu/applets/qt_error.cpp
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include <QDateTime>
-#include "core/hle/lock.h"
#include "yuzu/applets/qt_error.h"
#include "yuzu/main.h"
@@ -57,7 +56,5 @@ void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_te
}
void QtErrorDisplay::MainWindowFinishedError() {
- // Acquire the HLE mutex
- std::lock_guard lock{HLE::g_hle_lock};
callback();
}
diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp
index 7b19f1f8d..5b32da923 100644
--- a/src/yuzu/applets/qt_profile_select.cpp
+++ b/src/yuzu/applets/qt_profile_select.cpp
@@ -14,7 +14,6 @@
#include "common/fs/path_util.h"
#include "common/string_util.h"
#include "core/constants.h"
-#include "core/hle/lock.h"
#include "yuzu/applets/qt_profile_select.h"
#include "yuzu/main.h"
#include "yuzu/util/controller_navigation.h"
@@ -170,7 +169,5 @@ void QtProfileSelector::SelectProfile(
}
void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) {
- // Acquire the HLE mutex
- std::lock_guard lock{HLE::g_hle_lock};
callback(uuid);
}
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 463d500c2..0f679c37e 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -776,6 +776,7 @@ void Config::ReadUIGamelistValues() {
ReadBasicSetting(UISettings::values.row_1_text_id);
ReadBasicSetting(UISettings::values.row_2_text_id);
ReadBasicSetting(UISettings::values.cache_game_list);
+ ReadBasicSetting(UISettings::values.favorites_expanded);
const int favorites_size = qt_config->beginReadArray(QStringLiteral("favorites"));
for (int i = 0; i < favorites_size; i++) {
qt_config->setArrayIndex(i);
@@ -1300,6 +1301,7 @@ void Config::SaveUIGamelistValues() {
WriteBasicSetting(UISettings::values.row_1_text_id);
WriteBasicSetting(UISettings::values.row_2_text_id);
WriteBasicSetting(UISettings::values.cache_game_list);
+ WriteBasicSetting(UISettings::values.favorites_expanded);
qt_config->beginWriteArray(QStringLiteral("favorites"));
for (int i = 0; i < UISettings::values.favorited_ids.size(); i++) {
qt_config->setArrayIndex(i);
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 1a5e41588..8b5c4a10a 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -173,13 +173,17 @@ void GameList::OnItemExpanded(const QModelIndex& item) {
const bool is_dir = type == GameListItemType::CustomDir || type == GameListItemType::SdmcDir ||
type == GameListItemType::UserNandDir ||
type == GameListItemType::SysNandDir;
-
- if (!is_dir) {
+ const bool is_fave = type == GameListItemType::Favorites;
+ if (!is_dir && !is_fave) {
return;
}
-
- UISettings::values.game_dirs[item.data(GameListDir::GameDirRole).toInt()].expanded =
- tree_view->isExpanded(item);
+ const bool is_expanded = tree_view->isExpanded(item);
+ if (is_fave) {
+ UISettings::values.favorites_expanded = is_expanded;
+ return;
+ }
+ const int item_dir_index = item.data(GameListDir::GameDirRole).toInt();
+ UISettings::values.game_dirs[item_dir_index].expanded = is_expanded;
}
// Event in order to filter the gamelist after editing the searchfield
@@ -458,10 +462,13 @@ void GameList::DonePopulating(const QStringList& watch_list) {
emit ShowList(!IsEmpty());
item_model->invisibleRootItem()->appendRow(new GameListAddDir());
+
+ // Add favorites row
item_model->invisibleRootItem()->insertRow(0, new GameListFavorites());
tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(),
UISettings::values.favorited_ids.size() == 0);
- tree_view->expand(item_model->invisibleRootItem()->child(0)->index());
+ tree_view->setExpanded(item_model->invisibleRootItem()->child(0)->index(),
+ UISettings::values.favorites_expanded.GetValue());
for (const auto id : UISettings::values.favorited_ids) {
AddFavorite(id);
}
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index 936914ef3..a610e7e25 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -74,7 +74,6 @@ struct Values {
QString game_dir_deprecated;
bool game_dir_deprecated_deepscan;
QVector<UISettings::GameDir> game_dirs;
- QVector<u64> favorited_ids;
QStringList recent_files;
QString language;
@@ -96,6 +95,8 @@ struct Values {
Settings::BasicSetting<uint8_t> row_2_text_id{2, "row_2_text_id"};
std::atomic_bool is_game_list_reload_pending{false};
Settings::BasicSetting<bool> cache_game_list{true, "cache_game_list"};
+ Settings::BasicSetting<bool> favorites_expanded{true, "favorites_expanded"};
+ QVector<u64> favorited_ids;
bool configuration_applied;
bool reset_to_defaults;