diff options
54 files changed, 738 insertions, 569 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 | |||
| 41 | done | 41 | done |
| 42 | 42 | ||
| 43 | pip3 install pefile | 43 | pip3 install pefile |
| 44 | python3 .ci/scripts/windows/scan_dll.py package/*.exe "package/" | 44 | python3 .ci/scripts/windows/scan_dll.py package/*.exe package/imageformats/*.dll "package/" |
| 45 | python3 .ci/scripts/windows/scan_dll.py package/imageformats/*.dll "package/" | ||
| 46 | 45 | ||
| 47 | # copy FFmpeg libraries | 46 | # copy FFmpeg libraries |
| 48 | EXTERNALS_PATH="$(pwd)/build/externals" | 47 | EXTERNALS_PATH="$(pwd)/build/externals" |
| 49 | FFMPEG_DLL_PATH="$(find ${EXTERNALS_PATH} -maxdepth 1 -type d | grep ffmpeg)/bin" | 48 | FFMPEG_DLL_PATH="$(find "${EXTERNALS_PATH}" -maxdepth 1 -type d | grep 'ffmpeg-')/bin" |
| 50 | find ${FFMPEG_DLL_PATH} -type f -regex ".*\.dll" -exec cp -v {} package/ ';' | 49 | find ${FFMPEG_DLL_PATH} -type f -regex ".*\.dll" -exec cp -v {} package/ ';' |
| 51 | 50 | ||
| 52 | # copy libraries from yuzu.exe path | 51 | # copy libraries from yuzu.exe path |
diff --git a/.gitmodules b/.gitmodules index dc6ed500f..a9cf9a24a 100644 --- a/.gitmodules +++ b/.gitmodules | |||
| @@ -34,12 +34,12 @@ | |||
| 34 | [submodule "opus"] | 34 | [submodule "opus"] |
| 35 | path = externals/opus/opus | 35 | path = externals/opus/opus |
| 36 | url = https://github.com/xiph/opus.git | 36 | url = https://github.com/xiph/opus.git |
| 37 | [submodule "ffmpeg"] | ||
| 38 | path = externals/ffmpeg | ||
| 39 | url = https://git.ffmpeg.org/ffmpeg.git | ||
| 40 | [submodule "SDL"] | 37 | [submodule "SDL"] |
| 41 | path = externals/SDL | 38 | path = externals/SDL |
| 42 | url = https://github.com/libsdl-org/SDL.git | 39 | url = https://github.com/libsdl-org/SDL.git |
| 43 | [submodule "externals/cpp-httplib"] | 40 | [submodule "externals/cpp-httplib"] |
| 44 | path = externals/cpp-httplib | 41 | path = externals/cpp-httplib |
| 45 | url = https://github.com/yhirose/cpp-httplib.git | 42 | url = https://github.com/yhirose/cpp-httplib.git |
| 43 | [submodule "externals/ffmpeg/ffmpeg"] | ||
| 44 | path = externals/ffmpeg/ffmpeg | ||
| 45 | url = https://git.ffmpeg.org/ffmpeg.git | ||
diff --git a/CMakeLists.txt b/CMakeLists.txt index a810e11c2..7d9056aa3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -508,13 +508,13 @@ set(FFmpeg_COMPONENTS | |||
| 508 | avutil | 508 | avutil |
| 509 | swscale) | 509 | swscale) |
| 510 | 510 | ||
| 511 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") | 511 | if (UNIX AND NOT APPLE) |
| 512 | Include(FindPkgConfig REQUIRED) | 512 | Include(FindPkgConfig REQUIRED) |
| 513 | pkg_check_modules(LIBVA libva) | 513 | pkg_check_modules(LIBVA libva) |
| 514 | endif() | 514 | endif() |
| 515 | if (NOT YUZU_USE_BUNDLED_FFMPEG) | 515 | if (NOT YUZU_USE_BUNDLED_FFMPEG) |
| 516 | # Use system installed FFmpeg | 516 | # Use system installed FFmpeg |
| 517 | find_package(FFmpeg QUIET COMPONENTS ${FFmpeg_COMPONENTS}) | 517 | find_package(FFmpeg 4.3 QUIET COMPONENTS ${FFmpeg_COMPONENTS}) |
| 518 | 518 | ||
| 519 | if (FFmpeg_FOUND) | 519 | if (FFmpeg_FOUND) |
| 520 | # Overwrite aggregate defines from FFmpeg module to avoid over-linking libraries. | 520 | # Overwrite aggregate defines from FFmpeg module to avoid over-linking libraries. |
| @@ -527,225 +527,11 @@ if (NOT YUZU_USE_BUNDLED_FFMPEG) | |||
| 527 | set(FFmpeg_INCLUDE_DIR ${FFmpeg_INCLUDE_DIR} ${FFmpeg_INCLUDE_${COMPONENT}} CACHE PATH "Path to FFmpeg headers" FORCE) | 527 | set(FFmpeg_INCLUDE_DIR ${FFmpeg_INCLUDE_DIR} ${FFmpeg_INCLUDE_${COMPONENT}} CACHE PATH "Path to FFmpeg headers" FORCE) |
| 528 | endforeach() | 528 | endforeach() |
| 529 | else() | 529 | else() |
| 530 | message(WARNING "FFmpeg not found, falling back to externals") | 530 | message(WARNING "FFmpeg not found or too old, falling back to externals") |
| 531 | set(YUZU_USE_BUNDLED_FFMPEG ON) | 531 | set(YUZU_USE_BUNDLED_FFMPEG ON) |
| 532 | endif() | 532 | endif() |
| 533 | endif() | 533 | endif() |
| 534 | 534 | ||
| 535 | if (YUZU_USE_BUNDLED_FFMPEG) | ||
| 536 | if (NOT WIN32) | ||
| 537 | # TODO(lat9nq): Move this to externals/ffmpeg/CMakeLists.txt (and move externals/ffmpeg to | ||
| 538 | # externals/ffmpeg/ffmpeg) | ||
| 539 | |||
| 540 | # Build FFmpeg from externals | ||
| 541 | message(STATUS "Using FFmpeg from externals") | ||
| 542 | |||
| 543 | # FFmpeg has source that requires one of nasm or yasm to assemble it. | ||
| 544 | # REQUIRED throws an error if not found here during configuration rather than during compilation. | ||
| 545 | find_program(ASSEMBLER NAMES nasm yasm) | ||
| 546 | if ("${ASSEMBLER}" STREQUAL "ASSEMBLER-NOTFOUND") | ||
| 547 | message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.") | ||
| 548 | endif() | ||
| 549 | |||
| 550 | find_program(AUTOCONF autoconf) | ||
| 551 | if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND") | ||
| 552 | message(FATAL_ERROR "Required program `autoconf` not found.") | ||
| 553 | endif() | ||
| 554 | |||
| 555 | set(FFmpeg_PREFIX ${PROJECT_SOURCE_DIR}/externals/ffmpeg) | ||
| 556 | set(FFmpeg_BUILD_DIR ${PROJECT_BINARY_DIR}/externals/ffmpeg) | ||
| 557 | set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile) | ||
| 558 | make_directory(${FFmpeg_BUILD_DIR}) | ||
| 559 | |||
| 560 | # Read version string from external | ||
| 561 | file(READ ${FFmpeg_PREFIX}/RELEASE FFmpeg_VERSION) | ||
| 562 | set(FFmpeg_FOUND NO) | ||
| 563 | if (NOT FFmpeg_VERSION STREQUAL "") | ||
| 564 | set(FFmpeg_FOUND YES) | ||
| 565 | endif() | ||
| 566 | |||
| 567 | unset(FFmpeg_LIBRARIES CACHE) | ||
| 568 | foreach(COMPONENT ${FFmpeg_COMPONENTS}) | ||
| 569 | set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}") | ||
| 570 | set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a") | ||
| 571 | set(FFmpeg_${COMPONENT}_LIBRARY "${FFmpeg_${COMPONENT}_PREFIX}/${FFmpeg_${COMPONENT}_LIB_NAME}") | ||
| 572 | |||
| 573 | set(FFmpeg_LIBRARIES | ||
| 574 | ${FFmpeg_LIBRARIES} | ||
| 575 | ${FFmpeg_${COMPONENT}_LIBRARY} | ||
| 576 | CACHE PATH "Paths to FFmpeg libraries" FORCE) | ||
| 577 | endforeach() | ||
| 578 | |||
| 579 | Include(FindPkgConfig REQUIRED) | ||
| 580 | pkg_check_modules(LIBVA libva) | ||
| 581 | pkg_check_modules(CUDA cuda) | ||
| 582 | pkg_check_modules(FFNVCODEC ffnvcodec) | ||
| 583 | pkg_check_modules(VDPAU vdpau) | ||
| 584 | |||
| 585 | set(FFmpeg_HWACCEL_LIBRARIES) | ||
| 586 | set(FFmpeg_HWACCEL_FLAGS) | ||
| 587 | set(FFmpeg_HWACCEL_INCLUDE_DIRS) | ||
| 588 | set(FFmpeg_HWACCEL_LDFLAGS) | ||
| 589 | |||
| 590 | if(LIBVA_FOUND) | ||
| 591 | pkg_check_modules(LIBDRM libdrm REQUIRED) | ||
| 592 | find_package(X11 REQUIRED) | ||
| 593 | pkg_check_modules(LIBVA-DRM libva-drm REQUIRED) | ||
| 594 | pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED) | ||
| 595 | list(APPEND FFmpeg_HWACCEL_LIBRARIES | ||
| 596 | ${LIBDRM_LIBRARIES} | ||
| 597 | ${X11_LIBRARIES} | ||
| 598 | ${LIBVA-DRM_LIBRARIES} | ||
| 599 | ${LIBVA-X11_LIBRARIES} | ||
| 600 | ${LIBVA_LIBRARIES}) | ||
| 601 | set(FFmpeg_HWACCEL_FLAGS | ||
| 602 | --enable-hwaccel=h264_vaapi | ||
| 603 | --enable-hwaccel=vp8_vaapi | ||
| 604 | --enable-hwaccel=vp9_vaapi | ||
| 605 | --enable-libdrm) | ||
| 606 | list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS | ||
| 607 | ${LIBDRM_INCLUDE_DIRS} | ||
| 608 | ${X11_INCLUDE_DIRS} | ||
| 609 | ${LIBVA-DRM_INCLUDE_DIRS} | ||
| 610 | ${LIBVA-X11_INCLUDE_DIRS} | ||
| 611 | ${LIBVA_INCLUDE_DIRS} | ||
| 612 | ) | ||
| 613 | message(STATUS "VA-API found") | ||
| 614 | else() | ||
| 615 | set(FFmpeg_HWACCEL_FLAGS --disable-vaapi) | ||
| 616 | endif() | ||
| 617 | |||
| 618 | if (FFNVCODEC_FOUND AND CUDA_FOUND) | ||
| 619 | list(APPEND FFmpeg_HWACCEL_FLAGS | ||
| 620 | --enable-cuvid | ||
| 621 | --enable-ffnvcodec | ||
| 622 | --enable-nvdec | ||
| 623 | --enable-hwaccel=h264_nvdec | ||
| 624 | --enable-hwaccel=vp8_nvdec | ||
| 625 | --enable-hwaccel=vp9_nvdec | ||
| 626 | --extra-cflags=-I${CUDA_INCLUDE_DIRS} | ||
| 627 | ) | ||
| 628 | list(APPEND FFmpeg_HWACCEL_LIBRARIES | ||
| 629 | ${FFNVCODEC_LIBRARIES} | ||
| 630 | ${CUDA_LIBRARIES} | ||
| 631 | ) | ||
| 632 | list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS | ||
| 633 | ${FFNVCODEC_INCLUDE_DIRS} | ||
| 634 | ${CUDA_INCLUDE_DIRS} | ||
| 635 | ) | ||
| 636 | list(APPEND FFmpeg_HWACCEL_LDFLAGS | ||
| 637 | ${FFNVCODEC_LDFLAGS} | ||
| 638 | ${CUDA_LDFLAGS} | ||
| 639 | ) | ||
| 640 | message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found") | ||
| 641 | endif() | ||
| 642 | |||
| 643 | if (VDPAU_FOUND) | ||
| 644 | list(APPEND FFmpeg_HWACCEL_FLAGS | ||
| 645 | --enable-vdpau | ||
| 646 | --enable-hwaccel=h264_vdpau | ||
| 647 | --enable-hwaccel=vp9_vdpau | ||
| 648 | ) | ||
| 649 | list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES}) | ||
| 650 | list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS}) | ||
| 651 | list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS}) | ||
| 652 | message(STATUS "vdpau libraries version ${VDPAU_VERSION} found") | ||
| 653 | else() | ||
| 654 | list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau) | ||
| 655 | endif() | ||
| 656 | |||
| 657 | # `configure` parameters builds only exactly what yuzu needs from FFmpeg | ||
| 658 | # `--disable-vdpau` is needed to avoid linking issues | ||
| 659 | add_custom_command( | ||
| 660 | OUTPUT | ||
| 661 | ${FFmpeg_MAKEFILE} | ||
| 662 | COMMAND | ||
| 663 | /bin/bash ${FFmpeg_PREFIX}/configure | ||
| 664 | --disable-avdevice | ||
| 665 | --disable-avfilter | ||
| 666 | --disable-avformat | ||
| 667 | --disable-doc | ||
| 668 | --disable-everything | ||
| 669 | --disable-ffmpeg | ||
| 670 | --disable-ffprobe | ||
| 671 | --disable-network | ||
| 672 | --disable-postproc | ||
| 673 | --disable-swresample | ||
| 674 | --enable-decoder=h264 | ||
| 675 | --enable-decoder=vp8 | ||
| 676 | --enable-decoder=vp9 | ||
| 677 | --cc="${CMAKE_C_COMPILER}" | ||
| 678 | --cxx="${CMAKE_CXX_COMPILER}" | ||
| 679 | ${FFmpeg_HWACCEL_FLAGS} | ||
| 680 | WORKING_DIRECTORY | ||
| 681 | ${FFmpeg_BUILD_DIR} | ||
| 682 | ) | ||
| 683 | unset(FFmpeg_HWACCEL_FLAGS) | ||
| 684 | |||
| 685 | # Workaround for Ubuntu 18.04's older version of make not being able to call make as a child | ||
| 686 | # with context of the jobserver. Also helps ninja users. | ||
| 687 | execute_process( | ||
| 688 | COMMAND | ||
| 689 | nproc | ||
| 690 | OUTPUT_VARIABLE | ||
| 691 | SYSTEM_THREADS) | ||
| 692 | |||
| 693 | set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES}) | ||
| 694 | add_custom_command( | ||
| 695 | OUTPUT | ||
| 696 | ${FFmpeg_BUILD_LIBRARIES} | ||
| 697 | COMMAND | ||
| 698 | make -j${SYSTEM_THREADS} | ||
| 699 | WORKING_DIRECTORY | ||
| 700 | ${FFmpeg_BUILD_DIR} | ||
| 701 | ) | ||
| 702 | |||
| 703 | set(FFmpeg_INCLUDE_DIR | ||
| 704 | "${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR};${FFmpeg_HWACCEL_INCLUDE_DIRS}" | ||
| 705 | CACHE PATH "Path to FFmpeg headers" FORCE) | ||
| 706 | |||
| 707 | set(FFmpeg_LDFLAGS | ||
| 708 | "${FFmpeg_HWACCEL_LDFLAGS}" | ||
| 709 | CACHE STRING "FFmpeg linker flags" FORCE) | ||
| 710 | |||
| 711 | # ALL makes this custom target build every time | ||
| 712 | # but it won't actually build if the DEPENDS parameter is up to date | ||
| 713 | add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE}) | ||
| 714 | add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_BUILD_LIBRARIES} ffmpeg-configure) | ||
| 715 | link_libraries(${FFmpeg_LIBVA_LIBRARIES}) | ||
| 716 | set(FFmpeg_LIBRARIES ${FFmpeg_BUILD_LIBRARIES} ${FFmpeg_HWACCEL_LIBRARIES} | ||
| 717 | CACHE PATH "Paths to FFmpeg libraries" FORCE) | ||
| 718 | unset(FFmpeg_BUILD_LIBRARIES) | ||
| 719 | unset(FFmpeg_HWACCEL_FLAGS) | ||
| 720 | unset(FFmpeg_HWACCEL_INCLUDE_DIRS) | ||
| 721 | unset(FFmpeg_HWACCEL_LDFLAGS) | ||
| 722 | unset(FFmpeg_HWACCEL_LIBRARIES) | ||
| 723 | |||
| 724 | if (FFmpeg_FOUND) | ||
| 725 | message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}") | ||
| 726 | else() | ||
| 727 | message(FATAL_ERROR "FFmpeg not found") | ||
| 728 | endif() | ||
| 729 | else() # WIN32 | ||
| 730 | # Use yuzu FFmpeg binaries | ||
| 731 | set(FFmpeg_EXT_NAME "ffmpeg-4.4") | ||
| 732 | set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}") | ||
| 733 | download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "") | ||
| 734 | set(FFmpeg_FOUND YES) | ||
| 735 | set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE) | ||
| 736 | set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE) | ||
| 737 | set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE) | ||
| 738 | set(FFmpeg_DLL_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE) | ||
| 739 | set(FFmpeg_LIBRARIES | ||
| 740 | ${FFmpeg_LIBRARY_DIR}/swscale.lib | ||
| 741 | ${FFmpeg_LIBRARY_DIR}/avcodec.lib | ||
| 742 | ${FFmpeg_LIBRARY_DIR}/avutil.lib | ||
| 743 | CACHE PATH "Paths to FFmpeg libraries" FORCE) | ||
| 744 | endif() | ||
| 745 | endif() | ||
| 746 | |||
| 747 | unset(FFmpeg_COMPONENTS) | ||
| 748 | |||
| 749 | # Prefer the -pthread flag on Linux. | 535 | # Prefer the -pthread flag on Linux. |
| 750 | set(THREADS_PREFER_PTHREAD_FLAG ON) | 536 | set(THREADS_PREFER_PTHREAD_FLAG ON) |
| 751 | find_package(Threads REQUIRED) | 537 | find_package(Threads REQUIRED) |
diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake index 43ca730ec..c7da2b91d 100644 --- a/CMakeModules/GenerateSCMRev.cmake +++ b/CMakeModules/GenerateSCMRev.cmake | |||
| @@ -11,9 +11,15 @@ find_package(Git QUIET PATHS "${GIT_EXECUTABLE}") | |||
| 11 | 11 | ||
| 12 | # generate git/build information | 12 | # generate git/build information |
| 13 | include(GetGitRevisionDescription) | 13 | include(GetGitRevisionDescription) |
| 14 | get_git_head_revision(GIT_REF_SPEC GIT_REV) | 14 | if(NOT GIT_REF_SPEC) |
| 15 | git_describe(GIT_DESC --always --long --dirty) | 15 | get_git_head_revision(GIT_REF_SPEC GIT_REV) |
| 16 | git_branch_name(GIT_BRANCH) | 16 | endif() |
| 17 | if(NOT GIT_DESC) | ||
| 18 | git_describe(GIT_DESC --always --long --dirty) | ||
| 19 | endif() | ||
| 20 | if (NOT GIT_BRANCH) | ||
| 21 | git_branch_name(GIT_BRANCH) | ||
| 22 | endif() | ||
| 17 | get_timestamp(BUILD_DATE) | 23 | get_timestamp(BUILD_DATE) |
| 18 | 24 | ||
| 19 | # Generate cpp with Git revision from template | 25 | # Generate cpp with Git revision from template |
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 | |||
| 8 | TryExec=yuzu | 8 | TryExec=yuzu |
| 9 | Exec=yuzu %f | 9 | Exec=yuzu %f |
| 10 | Categories=Game;Emulator;Qt; | 10 | Categories=Game;Emulator;Qt; |
| 11 | MimeType=application/x-nx-nro;application/x-nx-nso; | 11 | MimeType=application/x-nx-nro;application/x-nx-nso;application/x-nx-nsp;application/x-nx-xci; |
| 12 | Keywords=Switch;Nintendo; \ No newline at end of file | 12 | 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 @@ | |||
| 15 | <glob pattern="*.nso"/> | 15 | <glob pattern="*.nso"/> |
| 16 | <magic><match value="NSO" type="string" offset="0"/></magic> | 16 | <magic><match value="NSO" type="string" offset="0"/></magic> |
| 17 | </mime-type> | 17 | </mime-type> |
| 18 | |||
| 19 | <mime-type type="application/x-nx-nsp"> | ||
| 20 | <comment>Nintendo Switch Package</comment> | ||
| 21 | <acronym>NSP</acronym> | ||
| 22 | <icon name="yuzu"/> | ||
| 23 | <glob pattern="*.nsp"/> | ||
| 24 | <magic><match value="PFS" type="string" offset="0"/></magic> | ||
| 25 | </mime-type> | ||
| 26 | |||
| 27 | <mime-type type="application/x-nx-xci"> | ||
| 28 | <comment>Nintendo Switch Card Image</comment> | ||
| 29 | <acronym>XCI</acronym> | ||
| 30 | <icon name="yuzu"/> | ||
| 31 | <glob pattern="*.xci"/> | ||
| 32 | </mime-type> | ||
| 18 | </mime-info> \ No newline at end of file | 33 | </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() | |||
| 52 | # SDL2 | 52 | # SDL2 |
| 53 | if (YUZU_USE_EXTERNAL_SDL2) | 53 | if (YUZU_USE_EXTERNAL_SDL2) |
| 54 | if (NOT WIN32) | 54 | if (NOT WIN32) |
| 55 | # Yuzu itself needs: Events Joystick Haptic Sensor Timers Audio | 55 | # Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers |
| 56 | # Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095) | ||
| 56 | # Yuzu-cmd also needs: Video (depends on Loadso/Dlopen) | 57 | # Yuzu-cmd also needs: Video (depends on Loadso/Dlopen) |
| 57 | set(SDL_UNUSED_SUBSYSTEMS | 58 | set(SDL_UNUSED_SUBSYSTEMS |
| 58 | Atomic Render Power Threads | 59 | CPUinfo File Filesystem |
| 59 | File CPUinfo Filesystem Locale) | 60 | Locale Power Render) |
| 60 | foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS}) | 61 | foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS}) |
| 61 | string(TOUPPER ${_SUB} _OPT) | 62 | string(TOUPPER ${_SUB} _OPT) |
| 62 | option(SDL_${_OPT} "" OFF) | 63 | option(SDL_${_OPT} "" OFF) |
| @@ -121,3 +122,12 @@ if (NOT opus_FOUND) | |||
| 121 | message(STATUS "opus 1.3 or newer not found, falling back to externals") | 122 | message(STATUS "opus 1.3 or newer not found, falling back to externals") |
| 122 | add_subdirectory(opus EXCLUDE_FROM_ALL) | 123 | add_subdirectory(opus EXCLUDE_FROM_ALL) |
| 123 | endif() | 124 | endif() |
| 125 | |||
| 126 | # FFMpeg | ||
| 127 | if (YUZU_USE_BUNDLED_FFMPEG) | ||
| 128 | add_subdirectory(ffmpeg) | ||
| 129 | set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE) | ||
| 130 | set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE) | ||
| 131 | set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE) | ||
| 132 | set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE) | ||
| 133 | endif() | ||
diff --git a/externals/SDL b/externals/SDL | |||
| Subproject 2e9821423a237a1206e3c09020778faacfe430b | Subproject e2ade2bfc46d915cd306c63c830b81d800b2575 | ||
diff --git a/externals/Vulkan-Headers b/externals/Vulkan-Headers | |||
| Subproject 07c4a37bcf41ea50aef6e98236abdfe8089fb4c | Subproject e005e1f8175d006adc3676b40ac3dd2212961a6 | ||
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 @@ | |||
| 1 | if (NOT WIN32) | ||
| 2 | # Build FFmpeg from externals | ||
| 3 | message(STATUS "Using FFmpeg from externals") | ||
| 4 | |||
| 5 | if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64)") | ||
| 6 | # FFmpeg has source that requires one of nasm or yasm to assemble it. | ||
| 7 | # REQUIRED throws an error if not found here during configuration rather than during compilation. | ||
| 8 | find_program(ASSEMBLER NAMES nasm yasm) | ||
| 9 | if ("${ASSEMBLER}" STREQUAL "ASSEMBLER-NOTFOUND") | ||
| 10 | message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.") | ||
| 11 | endif() | ||
| 12 | endif() | ||
| 13 | |||
| 14 | find_program(AUTOCONF autoconf) | ||
| 15 | if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND") | ||
| 16 | message(FATAL_ERROR "Required program `autoconf` not found.") | ||
| 17 | endif() | ||
| 18 | |||
| 19 | set(FFmpeg_PREFIX ${PROJECT_SOURCE_DIR}/externals/ffmpeg/ffmpeg) | ||
| 20 | set(FFmpeg_BUILD_DIR ${PROJECT_BINARY_DIR}/externals/ffmpeg-build) | ||
| 21 | set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile) | ||
| 22 | make_directory(${FFmpeg_BUILD_DIR}) | ||
| 23 | |||
| 24 | # Read version string from external | ||
| 25 | file(READ ${FFmpeg_PREFIX}/RELEASE FFmpeg_VERSION) | ||
| 26 | set(FFmpeg_FOUND NO) | ||
| 27 | if (NOT FFmpeg_VERSION STREQUAL "") | ||
| 28 | set(FFmpeg_FOUND YES) | ||
| 29 | endif() | ||
| 30 | |||
| 31 | unset(FFmpeg_LIBRARIES CACHE) | ||
| 32 | foreach(COMPONENT ${FFmpeg_COMPONENTS}) | ||
| 33 | set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}") | ||
| 34 | set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a") | ||
| 35 | set(FFmpeg_${COMPONENT}_LIBRARY "${FFmpeg_${COMPONENT}_PREFIX}/${FFmpeg_${COMPONENT}_LIB_NAME}") | ||
| 36 | |||
| 37 | set(FFmpeg_LIBRARIES | ||
| 38 | ${FFmpeg_LIBRARIES} | ||
| 39 | ${FFmpeg_${COMPONENT}_LIBRARY} | ||
| 40 | CACHE PATH "Paths to FFmpeg libraries" FORCE) | ||
| 41 | endforeach() | ||
| 42 | |||
| 43 | Include(FindPkgConfig REQUIRED) | ||
| 44 | pkg_check_modules(LIBVA libva) | ||
| 45 | pkg_check_modules(CUDA cuda) | ||
| 46 | pkg_check_modules(FFNVCODEC ffnvcodec) | ||
| 47 | pkg_check_modules(VDPAU vdpau) | ||
| 48 | |||
| 49 | set(FFmpeg_HWACCEL_LIBRARIES) | ||
| 50 | set(FFmpeg_HWACCEL_FLAGS) | ||
| 51 | set(FFmpeg_HWACCEL_INCLUDE_DIRS) | ||
| 52 | set(FFmpeg_HWACCEL_LDFLAGS) | ||
| 53 | |||
| 54 | if(LIBVA_FOUND) | ||
| 55 | pkg_check_modules(LIBDRM libdrm REQUIRED) | ||
| 56 | find_package(X11 REQUIRED) | ||
| 57 | pkg_check_modules(LIBVA-DRM libva-drm REQUIRED) | ||
| 58 | pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED) | ||
| 59 | list(APPEND FFmpeg_HWACCEL_LIBRARIES | ||
| 60 | ${LIBDRM_LIBRARIES} | ||
| 61 | ${X11_LIBRARIES} | ||
| 62 | ${LIBVA-DRM_LIBRARIES} | ||
| 63 | ${LIBVA-X11_LIBRARIES} | ||
| 64 | ${LIBVA_LIBRARIES}) | ||
| 65 | set(FFmpeg_HWACCEL_FLAGS | ||
| 66 | --enable-hwaccel=h264_vaapi | ||
| 67 | --enable-hwaccel=vp8_vaapi | ||
| 68 | --enable-hwaccel=vp9_vaapi | ||
| 69 | --enable-libdrm) | ||
| 70 | list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS | ||
| 71 | ${LIBDRM_INCLUDE_DIRS} | ||
| 72 | ${X11_INCLUDE_DIRS} | ||
| 73 | ${LIBVA-DRM_INCLUDE_DIRS} | ||
| 74 | ${LIBVA-X11_INCLUDE_DIRS} | ||
| 75 | ${LIBVA_INCLUDE_DIRS} | ||
| 76 | ) | ||
| 77 | message(STATUS "VA-API found") | ||
| 78 | else() | ||
| 79 | set(FFmpeg_HWACCEL_FLAGS --disable-vaapi) | ||
| 80 | endif() | ||
| 81 | |||
| 82 | if (FFNVCODEC_FOUND) | ||
| 83 | list(APPEND FFmpeg_HWACCEL_FLAGS | ||
| 84 | --enable-cuvid | ||
| 85 | --enable-ffnvcodec | ||
| 86 | --enable-nvdec | ||
| 87 | --enable-hwaccel=h264_nvdec | ||
| 88 | --enable-hwaccel=vp8_nvdec | ||
| 89 | --enable-hwaccel=vp9_nvdec | ||
| 90 | ) | ||
| 91 | list(APPEND FFmpeg_HWACCEL_LIBRARIES ${FFNVCODEC_LIBRARIES}) | ||
| 92 | list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${FFNVCODEC_INCLUDE_DIRS}) | ||
| 93 | list(APPEND FFmpeg_HWACCEL_LDFLAGS ${FFNVCODEC_LDFLAGS}) | ||
| 94 | message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found") | ||
| 95 | # ffnvenc could load CUDA libraries at the runtime using dlopen/dlsym or LoadLibrary/GetProcAddress | ||
| 96 | # here we handle the hard-linking senario where CUDA is linked during compilation | ||
| 97 | if (CUDA_FOUND) | ||
| 98 | list(APPEND FFmpeg_HWACCEL_FLAGS --extra-cflags=-I${CUDA_INCLUDE_DIRS}) | ||
| 99 | list(APPEND FFmpeg_HWACCEL_LIBRARIES ${CUDA_LIBRARIES}) | ||
| 100 | list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS}) | ||
| 101 | list(APPEND FFmpeg_HWACCEL_LDFLAGS ${CUDA_LDFLAGS}) | ||
| 102 | message(STATUS "CUDA libraries found, hard-linking will be performed") | ||
| 103 | endif(CUDA_FOUND) | ||
| 104 | endif() | ||
| 105 | |||
| 106 | if (VDPAU_FOUND) | ||
| 107 | list(APPEND FFmpeg_HWACCEL_FLAGS | ||
| 108 | --enable-vdpau | ||
| 109 | --enable-hwaccel=h264_vdpau | ||
| 110 | --enable-hwaccel=vp9_vdpau | ||
| 111 | ) | ||
| 112 | list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES}) | ||
| 113 | list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS}) | ||
| 114 | list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS}) | ||
| 115 | message(STATUS "vdpau libraries version ${VDPAU_VERSION} found") | ||
| 116 | else() | ||
| 117 | list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau) | ||
| 118 | endif() | ||
| 119 | |||
| 120 | # `configure` parameters builds only exactly what yuzu needs from FFmpeg | ||
| 121 | # `--disable-vdpau` is needed to avoid linking issues | ||
| 122 | add_custom_command( | ||
| 123 | OUTPUT | ||
| 124 | ${FFmpeg_MAKEFILE} | ||
| 125 | COMMAND | ||
| 126 | /bin/bash ${FFmpeg_PREFIX}/configure | ||
| 127 | --disable-avdevice | ||
| 128 | --disable-avfilter | ||
| 129 | --disable-avformat | ||
| 130 | --disable-doc | ||
| 131 | --disable-everything | ||
| 132 | --disable-ffmpeg | ||
| 133 | --disable-ffprobe | ||
| 134 | --disable-network | ||
| 135 | --disable-postproc | ||
| 136 | --disable-swresample | ||
| 137 | --enable-decoder=h264 | ||
| 138 | --enable-decoder=vp8 | ||
| 139 | --enable-decoder=vp9 | ||
| 140 | --cc="${CMAKE_C_COMPILER}" | ||
| 141 | --cxx="${CMAKE_CXX_COMPILER}" | ||
| 142 | ${FFmpeg_HWACCEL_FLAGS} | ||
| 143 | WORKING_DIRECTORY | ||
| 144 | ${FFmpeg_BUILD_DIR} | ||
| 145 | ) | ||
| 146 | unset(FFmpeg_HWACCEL_FLAGS) | ||
| 147 | |||
| 148 | # Workaround for Ubuntu 18.04's older version of make not being able to call make as a child | ||
| 149 | # with context of the jobserver. Also helps ninja users. | ||
| 150 | execute_process( | ||
| 151 | COMMAND | ||
| 152 | nproc | ||
| 153 | OUTPUT_VARIABLE | ||
| 154 | SYSTEM_THREADS) | ||
| 155 | |||
| 156 | set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES}) | ||
| 157 | add_custom_command( | ||
| 158 | OUTPUT | ||
| 159 | ${FFmpeg_BUILD_LIBRARIES} | ||
| 160 | COMMAND | ||
| 161 | make -j${SYSTEM_THREADS} | ||
| 162 | WORKING_DIRECTORY | ||
| 163 | ${FFmpeg_BUILD_DIR} | ||
| 164 | ) | ||
| 165 | |||
| 166 | set(FFmpeg_INCLUDE_DIR | ||
| 167 | "${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR};${FFmpeg_HWACCEL_INCLUDE_DIRS}" | ||
| 168 | CACHE PATH "Path to FFmpeg headers" FORCE) | ||
| 169 | |||
| 170 | set(FFmpeg_LDFLAGS | ||
| 171 | "${FFmpeg_HWACCEL_LDFLAGS}" | ||
| 172 | CACHE STRING "FFmpeg linker flags" FORCE) | ||
| 173 | |||
| 174 | # ALL makes this custom target build every time | ||
| 175 | # but it won't actually build if the DEPENDS parameter is up to date | ||
| 176 | add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE}) | ||
| 177 | add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_BUILD_LIBRARIES} ffmpeg-configure) | ||
| 178 | link_libraries(${FFmpeg_LIBVA_LIBRARIES}) | ||
| 179 | set(FFmpeg_LIBRARIES ${FFmpeg_BUILD_LIBRARIES} ${FFmpeg_HWACCEL_LIBRARIES} | ||
| 180 | CACHE PATH "Paths to FFmpeg libraries" FORCE) | ||
| 181 | unset(FFmpeg_BUILD_LIBRARIES) | ||
| 182 | unset(FFmpeg_HWACCEL_FLAGS) | ||
| 183 | unset(FFmpeg_HWACCEL_INCLUDE_DIRS) | ||
| 184 | unset(FFmpeg_HWACCEL_LDFLAGS) | ||
| 185 | unset(FFmpeg_HWACCEL_LIBRARIES) | ||
| 186 | |||
| 187 | if (FFmpeg_FOUND) | ||
| 188 | message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}") | ||
| 189 | else() | ||
| 190 | message(FATAL_ERROR "FFmpeg not found") | ||
| 191 | endif() | ||
| 192 | else(WIN32) | ||
| 193 | # Use yuzu FFmpeg binaries | ||
| 194 | set(FFmpeg_EXT_NAME "ffmpeg-4.4") | ||
| 195 | set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}") | ||
| 196 | download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "") | ||
| 197 | set(FFmpeg_FOUND YES) | ||
| 198 | set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE) | ||
| 199 | set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE) | ||
| 200 | set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE) | ||
| 201 | set(FFmpeg_DLL_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE) | ||
| 202 | set(FFmpeg_LIBRARIES | ||
| 203 | ${FFmpeg_LIBRARY_DIR}/swscale.lib | ||
| 204 | ${FFmpeg_LIBRARY_DIR}/avcodec.lib | ||
| 205 | ${FFmpeg_LIBRARY_DIR}/avutil.lib | ||
| 206 | CACHE PATH "Paths to FFmpeg libraries" FORCE) | ||
| 207 | # exported variables | ||
| 208 | set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE) | ||
| 209 | set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE) | ||
| 210 | set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE) | ||
| 211 | set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE) | ||
| 212 | endif(WIN32) | ||
| 213 | |||
| 214 | unset(FFmpeg_COMPONENTS) | ||
diff --git a/externals/ffmpeg/ffmpeg b/externals/ffmpeg/ffmpeg new file mode 160000 | |||
| Subproject dc91b913b6260e85e1304c74ff7bb3c22a8c9fb | |||
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 919da4a53..790193b00 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -22,6 +22,11 @@ add_custom_command(OUTPUT scm_rev.cpp | |||
| 22 | -DTITLE_BAR_FORMAT_RUNNING=${TITLE_BAR_FORMAT_RUNNING} | 22 | -DTITLE_BAR_FORMAT_RUNNING=${TITLE_BAR_FORMAT_RUNNING} |
| 23 | -DBUILD_TAG=${BUILD_TAG} | 23 | -DBUILD_TAG=${BUILD_TAG} |
| 24 | -DBUILD_ID=${DISPLAY_VERSION} | 24 | -DBUILD_ID=${DISPLAY_VERSION} |
| 25 | -DGIT_REF_SPEC=${GIT_REF_SPEC} | ||
| 26 | -DGIT_REV=${GIT_REV} | ||
| 27 | -DGIT_DESC=${GIT_DESC} | ||
| 28 | -DGIT_BRANCH=${GIT_BRANCH} | ||
| 29 | -DBUILD_FULLNAME=${BUILD_FULLNAME} | ||
| 25 | -DGIT_EXECUTABLE=${GIT_EXECUTABLE} | 30 | -DGIT_EXECUTABLE=${GIT_EXECUTABLE} |
| 26 | -P ${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake | 31 | -P ${CMAKE_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake |
| 27 | DEPENDS | 32 | DEPENDS |
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 | |||
| 265 | hle/kernel/svc_wrap.h | 265 | hle/kernel/svc_wrap.h |
| 266 | hle/kernel/time_manager.cpp | 266 | hle/kernel/time_manager.cpp |
| 267 | hle/kernel/time_manager.h | 267 | hle/kernel/time_manager.h |
| 268 | hle/lock.cpp | ||
| 269 | hle/lock.h | ||
| 270 | hle/result.h | 268 | hle/result.h |
| 271 | hle/service/acc/acc.cpp | 269 | hle/service/acc/acc.cpp |
| 272 | hle/service/acc/acc.h | 270 | 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) { | |||
| 161 | motion.rotation = emulated.GetGyroscope(); | 161 | motion.rotation = emulated.GetGyroscope(); |
| 162 | motion.orientation = emulated.GetOrientation(); | 162 | motion.orientation = emulated.GetOrientation(); |
| 163 | motion.quaternion = emulated.GetQuaternion(); | 163 | motion.quaternion = emulated.GetQuaternion(); |
| 164 | motion.gyro_bias = emulated.GetGyroBias(); | ||
| 164 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); | 165 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); |
| 166 | // Find what is this value | ||
| 167 | motion.verticalization_error = 0.0f; | ||
| 165 | 168 | ||
| 166 | TriggerOnChange(ConsoleTriggerType::Motion); | 169 | TriggerOnChange(ConsoleTriggerType::Motion); |
| 167 | } | 170 | } |
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 { | |||
| 50 | Common::Vec3f rotation{}; | 50 | Common::Vec3f rotation{}; |
| 51 | std::array<Common::Vec3f, 3> orientation{}; | 51 | std::array<Common::Vec3f, 3> orientation{}; |
| 52 | Common::Quaternion<f32> quaternion{}; | 52 | Common::Quaternion<f32> quaternion{}; |
| 53 | Common::Vec3f gyro_bias{}; | ||
| 54 | f32 verticalization_error{}; | ||
| 53 | bool is_at_rest{}; | 55 | bool is_at_rest{}; |
| 54 | }; | 56 | }; |
| 55 | 57 | ||
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 | |||
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | bool EmulatedController::TestVibration(std::size_t device_index) { | 845 | bool EmulatedController::TestVibration(std::size_t device_index) { |
| 846 | if (device_index >= output_devices.size()) { | 846 | static constexpr VibrationValue test_vibration = { |
| 847 | return false; | ||
| 848 | } | ||
| 849 | if (!output_devices[device_index]) { | ||
| 850 | return false; | ||
| 851 | } | ||
| 852 | |||
| 853 | // Send a slight vibration to test for rumble support | ||
| 854 | constexpr Common::Input::VibrationStatus status = { | ||
| 855 | .low_amplitude = 0.001f, | 847 | .low_amplitude = 0.001f, |
| 856 | .low_frequency = 160.0f, | 848 | .low_frequency = 160.0f, |
| 857 | .high_amplitude = 0.001f, | 849 | .high_amplitude = 0.001f, |
| 858 | .high_frequency = 320.0f, | 850 | .high_frequency = 320.0f, |
| 859 | .type = Common::Input::VibrationAmplificationType::Linear, | ||
| 860 | }; | 851 | }; |
| 861 | return output_devices[device_index]->SetVibration(status) == | 852 | |
| 862 | Common::Input::VibrationError::None; | 853 | // Send a slight vibration to test for rumble support |
| 854 | SetVibration(device_index, test_vibration); | ||
| 855 | |||
| 856 | // Stop any vibration and return the result | ||
| 857 | return SetVibration(device_index, DEFAULT_VIBRATION_VALUE); | ||
| 863 | } | 858 | } |
| 864 | 859 | ||
| 865 | void EmulatedController::SetLedPattern() { | 860 | 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 { | |||
| 496 | }; | 496 | }; |
| 497 | static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size."); | 497 | static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size."); |
| 498 | 498 | ||
| 499 | constexpr VibrationValue DEFAULT_VIBRATION_VALUE{ | ||
| 500 | .low_amplitude = 0.0f, | ||
| 501 | .low_frequency = 160.0f, | ||
| 502 | .high_amplitude = 0.0f, | ||
| 503 | .high_frequency = 320.0f, | ||
| 504 | }; | ||
| 505 | |||
| 499 | // This is nn::hid::VibrationDeviceInfo | 506 | // This is nn::hid::VibrationDeviceInfo |
| 500 | struct VibrationDeviceInfo { | 507 | struct VibrationDeviceInfo { |
| 501 | VibrationDeviceType type{}; | 508 | 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) { | |||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { | 25 | void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { |
| 26 | gyro = gyroscope - gyro_drift; | 26 | gyro = gyroscope - gyro_bias; |
| 27 | 27 | ||
| 28 | // Auto adjust drift to minimize drift | 28 | // Auto adjust drift to minimize drift |
| 29 | if (!IsMoving(0.1f)) { | 29 | if (!IsMoving(0.1f)) { |
| 30 | gyro_drift = (gyro_drift * 0.9999f) + (gyroscope * 0.0001f); | 30 | gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | if (gyro.Length2() < gyro_threshold) { | 33 | if (gyro.Length2() < gyro_threshold) { |
| @@ -41,8 +41,8 @@ void MotionInput::SetQuaternion(const Common::Quaternion<f32>& quaternion) { | |||
| 41 | quat = quaternion; | 41 | quat = quaternion; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void MotionInput::SetGyroDrift(const Common::Vec3f& drift) { | 44 | void MotionInput::SetGyroBias(const Common::Vec3f& bias) { |
| 45 | gyro_drift = drift; | 45 | gyro_bias = bias; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | void MotionInput::SetGyroThreshold(f32 threshold) { | 48 | void MotionInput::SetGyroThreshold(f32 threshold) { |
| @@ -192,6 +192,10 @@ Common::Vec3f MotionInput::GetGyroscope() const { | |||
| 192 | return gyro; | 192 | return gyro; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | Common::Vec3f MotionInput::GetGyroBias() const { | ||
| 196 | return gyro_bias; | ||
| 197 | } | ||
| 198 | |||
| 195 | Common::Quaternion<f32> MotionInput::GetQuaternion() const { | 199 | Common::Quaternion<f32> MotionInput::GetQuaternion() const { |
| 196 | return quat; | 200 | return quat; |
| 197 | } | 201 | } |
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: | |||
| 24 | void SetAcceleration(const Common::Vec3f& acceleration); | 24 | void SetAcceleration(const Common::Vec3f& acceleration); |
| 25 | void SetGyroscope(const Common::Vec3f& gyroscope); | 25 | void SetGyroscope(const Common::Vec3f& gyroscope); |
| 26 | void SetQuaternion(const Common::Quaternion<f32>& quaternion); | 26 | void SetQuaternion(const Common::Quaternion<f32>& quaternion); |
| 27 | void SetGyroDrift(const Common::Vec3f& drift); | 27 | void SetGyroBias(const Common::Vec3f& bias); |
| 28 | void SetGyroThreshold(f32 threshold); | 28 | void SetGyroThreshold(f32 threshold); |
| 29 | 29 | ||
| 30 | void EnableReset(bool reset); | 30 | void EnableReset(bool reset); |
| @@ -36,6 +36,7 @@ public: | |||
| 36 | [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const; | 36 | [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const; |
| 37 | [[nodiscard]] Common::Vec3f GetAcceleration() const; | 37 | [[nodiscard]] Common::Vec3f GetAcceleration() const; |
| 38 | [[nodiscard]] Common::Vec3f GetGyroscope() const; | 38 | [[nodiscard]] Common::Vec3f GetGyroscope() const; |
| 39 | [[nodiscard]] Common::Vec3f GetGyroBias() const; | ||
| 39 | [[nodiscard]] Common::Vec3f GetRotations() const; | 40 | [[nodiscard]] Common::Vec3f GetRotations() const; |
| 40 | [[nodiscard]] Common::Quaternion<f32> GetQuaternion() const; | 41 | [[nodiscard]] Common::Quaternion<f32> GetQuaternion() const; |
| 41 | 42 | ||
| @@ -69,7 +70,7 @@ private: | |||
| 69 | Common::Vec3f gyro; | 70 | Common::Vec3f gyro; |
| 70 | 71 | ||
| 71 | // Vector to be substracted from gyro measurements | 72 | // Vector to be substracted from gyro measurements |
| 72 | Common::Vec3f gyro_drift; | 73 | Common::Vec3f gyro_bias; |
| 73 | 74 | ||
| 74 | // Minimum gyro amplitude to detect if the device is moving | 75 | // Minimum gyro amplitude to detect if the device is moving |
| 75 | f32 gyro_threshold = 0.0f; | 76 | 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 @@ | |||
| 28 | #include "core/hle/kernel/k_thread.h" | 28 | #include "core/hle/kernel/k_thread.h" |
| 29 | #include "core/hle/kernel/kernel.h" | 29 | #include "core/hle/kernel/kernel.h" |
| 30 | #include "core/hle/kernel/svc_results.h" | 30 | #include "core/hle/kernel/svc_results.h" |
| 31 | #include "core/hle/lock.h" | ||
| 32 | #include "core/memory.h" | 31 | #include "core/memory.h" |
| 33 | 32 | ||
| 34 | namespace Kernel { | 33 | namespace Kernel { |
| @@ -543,7 +542,6 @@ void KProcess::FreeTLSRegion(VAddr tls_address) { | |||
| 543 | } | 542 | } |
| 544 | 543 | ||
| 545 | void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { | 544 | void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { |
| 546 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 547 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | 545 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, |
| 548 | KMemoryPermission permission) { | 546 | KMemoryPermission permission) { |
| 549 | page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); | 547 | 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 { | |||
| 182 | // Shutdown all processes. | 182 | // Shutdown all processes. |
| 183 | if (current_process) { | 183 | if (current_process) { |
| 184 | current_process->Finalize(); | 184 | current_process->Finalize(); |
| 185 | current_process->Close(); | 185 | // current_process->Close(); |
| 186 | // TODO: The current process should be destroyed based on accurate ref counting after | ||
| 187 | // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak. | ||
| 188 | current_process->Destroy(); | ||
| 186 | current_process = nullptr; | 189 | current_process = nullptr; |
| 187 | } | 190 | } |
| 188 | 191 | ||
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 @@ | |||
| 41 | #include "core/hle/kernel/svc_results.h" | 41 | #include "core/hle/kernel/svc_results.h" |
| 42 | #include "core/hle/kernel/svc_types.h" | 42 | #include "core/hle/kernel/svc_types.h" |
| 43 | #include "core/hle/kernel/svc_wrap.h" | 43 | #include "core/hle/kernel/svc_wrap.h" |
| 44 | #include "core/hle/lock.h" | ||
| 45 | #include "core/hle/result.h" | 44 | #include "core/hle/result.h" |
| 46 | #include "core/memory.h" | 45 | #include "core/memory.h" |
| 47 | #include "core/reporter.h" | 46 | #include "core/reporter.h" |
| @@ -137,7 +136,6 @@ enum class ResourceLimitValueType { | |||
| 137 | 136 | ||
| 138 | /// Set the process heap to a given Size. It can both extend and shrink the heap. | 137 | /// Set the process heap to a given Size. It can both extend and shrink the heap. |
| 139 | static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) { | 138 | static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) { |
| 140 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 141 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); | 139 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); |
| 142 | 140 | ||
| 143 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. | 141 | // 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 | |||
| 168 | 166 | ||
| 169 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, | 167 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, |
| 170 | u32 attribute) { | 168 | u32 attribute) { |
| 171 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 172 | LOG_DEBUG(Kernel_SVC, | 169 | LOG_DEBUG(Kernel_SVC, |
| 173 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, | 170 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, |
| 174 | size, mask, attribute); | 171 | size, mask, attribute); |
| @@ -212,7 +209,6 @@ static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 si | |||
| 212 | 209 | ||
| 213 | /// Maps a memory range into a different range. | 210 | /// Maps a memory range into a different range. |
| 214 | static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 211 | static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 215 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 216 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 212 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 217 | src_addr, size); | 213 | src_addr, size); |
| 218 | 214 | ||
| @@ -232,7 +228,6 @@ static ResultCode MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, | |||
| 232 | 228 | ||
| 233 | /// Unmaps a region that was previously mapped with svcMapMemory | 229 | /// Unmaps a region that was previously mapped with svcMapMemory |
| 234 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 230 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 235 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 236 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 231 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 237 | src_addr, size); | 232 | src_addr, size); |
| 238 | 233 | ||
| @@ -642,7 +637,6 @@ static void OutputDebugString(Core::System& system, VAddr address, u64 len) { | |||
| 642 | /// Gets system/memory information for the current process | 637 | /// Gets system/memory information for the current process |
| 643 | static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, | 638 | static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, |
| 644 | u64 info_sub_id) { | 639 | u64 info_sub_id) { |
| 645 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 646 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, | 640 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, |
| 647 | info_sub_id, handle); | 641 | info_sub_id, handle); |
| 648 | 642 | ||
| @@ -924,7 +918,6 @@ static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_h | |||
| 924 | 918 | ||
| 925 | /// Maps memory at a desired address | 919 | /// Maps memory at a desired address |
| 926 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 920 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 927 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 928 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 921 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 929 | 922 | ||
| 930 | if (!Common::Is4KBAligned(addr)) { | 923 | if (!Common::Is4KBAligned(addr)) { |
| @@ -978,7 +971,6 @@ static ResultCode MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) | |||
| 978 | 971 | ||
| 979 | /// Unmaps memory previously mapped via MapPhysicalMemory | 972 | /// Unmaps memory previously mapped via MapPhysicalMemory |
| 980 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 973 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 981 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 982 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 974 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 983 | 975 | ||
| 984 | if (!Common::Is4KBAligned(addr)) { | 976 | if (!Common::Is4KBAligned(addr)) { |
| @@ -1520,7 +1512,6 @@ static ResultCode ControlCodeMemory(Core::System& system, Handle code_memory_han | |||
| 1520 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1512 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| 1521 | VAddr page_info_address, Handle process_handle, | 1513 | VAddr page_info_address, Handle process_handle, |
| 1522 | VAddr address) { | 1514 | VAddr address) { |
| 1523 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 1524 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); | 1515 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); |
| 1525 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1516 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1526 | KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle); | 1517 | 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 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <core/hle/lock.h> | ||
| 6 | |||
| 7 | namespace HLE { | ||
| 8 | std::recursive_mutex g_hle_lock; | ||
| 9 | } | ||
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 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <mutex> | ||
| 8 | |||
| 9 | namespace HLE { | ||
| 10 | /* | ||
| 11 | * Synchronizes access to the internal HLE kernel structures, it is acquired when a guest | ||
| 12 | * application thread performs a syscall. It should be acquired by any host threads that read or | ||
| 13 | * modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes | ||
| 14 | * to the emulated memory is not protected by this mutex, and should be avoided in any threads other | ||
| 15 | * than the CPU thread. | ||
| 16 | */ | ||
| 17 | extern std::recursive_mutex g_hle_lock; | ||
| 18 | } // 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 @@ | |||
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/k_event.h" | 8 | #include "core/hle/kernel/k_event.h" |
| 9 | #include "core/hle/lock.h" | ||
| 10 | #include "core/hle/service/bcat/backend/backend.h" | 9 | #include "core/hle/service/bcat/backend/backend.h" |
| 11 | 10 | ||
| 12 | namespace Service::BCAT { | 11 | namespace Service::BCAT { |
| @@ -29,10 +28,6 @@ DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { | |||
| 29 | return impl; | 28 | return impl; |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | void ProgressServiceBackend::SetNeedHLELock(bool need) { | ||
| 33 | need_hle_lock = need; | ||
| 34 | } | ||
| 35 | |||
| 36 | void ProgressServiceBackend::SetTotalSize(u64 size) { | 31 | void ProgressServiceBackend::SetTotalSize(u64 size) { |
| 37 | impl.total_bytes = size; | 32 | impl.total_bytes = size; |
| 38 | SignalUpdate(); | 33 | SignalUpdate(); |
| @@ -88,12 +83,7 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) { | |||
| 88 | } | 83 | } |
| 89 | 84 | ||
| 90 | void ProgressServiceBackend::SignalUpdate() { | 85 | void ProgressServiceBackend::SignalUpdate() { |
| 91 | if (need_hle_lock) { | 86 | update_event->GetWritableEvent().Signal(); |
| 92 | std::lock_guard lock(HLE::g_hle_lock); | ||
| 93 | update_event->GetWritableEvent().Signal(); | ||
| 94 | } else { | ||
| 95 | update_event->GetWritableEvent().Signal(); | ||
| 96 | } | ||
| 97 | } | 87 | } |
| 98 | 88 | ||
| 99 | Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} | 89 | 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 { | |||
| 71 | public: | 71 | public: |
| 72 | ~ProgressServiceBackend(); | 72 | ~ProgressServiceBackend(); |
| 73 | 73 | ||
| 74 | // Clients should call this with true if any of the functions are going to be called from a | ||
| 75 | // non-HLE thread and this class need to lock the hle mutex. (default is false) | ||
| 76 | void SetNeedHLELock(bool need); | ||
| 77 | |||
| 78 | // Sets the number of bytes total in the entire download. | 74 | // Sets the number of bytes total in the entire download. |
| 79 | void SetTotalSize(u64 size); | 75 | void SetTotalSize(u64 size); |
| 80 | 76 | ||
| @@ -109,7 +105,6 @@ private: | |||
| 109 | 105 | ||
| 110 | DeliveryCacheProgressImpl impl{}; | 106 | DeliveryCacheProgressImpl impl{}; |
| 111 | Kernel::KEvent* update_event; | 107 | Kernel::KEvent* update_event; |
| 112 | bool need_hle_lock = false; | ||
| 113 | }; | 108 | }; |
| 114 | 109 | ||
| 115 | // A class representing an abstract backend for BCAT functionality. | 110 | // 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 | |||
| 33 | const auto& last_entry = seven_sixaxis_lifo.ReadCurrentEntry().state; | 33 | const auto& last_entry = seven_sixaxis_lifo.ReadCurrentEntry().state; |
| 34 | next_seven_sixaxis_state.sampling_number = last_entry.sampling_number + 1; | 34 | next_seven_sixaxis_state.sampling_number = last_entry.sampling_number + 1; |
| 35 | 35 | ||
| 36 | // Try to read sixaxis sensor states | ||
| 37 | const auto motion_status = console->GetMotion(); | 36 | const auto motion_status = console->GetMotion(); |
| 37 | last_global_timestamp = core_timing.GetGlobalTimeNs().count(); | ||
| 38 | 38 | ||
| 39 | console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | 39 | // This value increments every time the switch goes to sleep |
| 40 | 40 | next_seven_sixaxis_state.unknown = 1; | |
| 41 | next_seven_sixaxis_state.timestamp = last_global_timestamp - last_saved_timestamp; | ||
| 41 | next_seven_sixaxis_state.accel = motion_status.accel; | 42 | next_seven_sixaxis_state.accel = motion_status.accel; |
| 42 | // Zero gyro values as they just mess up with the camera | 43 | next_seven_sixaxis_state.gyro = motion_status.gyro; |
| 43 | // Note: Probably a correct sensivity setting must be set | ||
| 44 | next_seven_sixaxis_state.gyro = {}; | ||
| 45 | next_seven_sixaxis_state.quaternion = { | 44 | next_seven_sixaxis_state.quaternion = { |
| 46 | { | 45 | { |
| 47 | motion_status.quaternion.xyz.y, | 46 | motion_status.quaternion.xyz.y, |
| @@ -52,9 +51,9 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti | |||
| 52 | }; | 51 | }; |
| 53 | 52 | ||
| 54 | console_six_axis.sampling_number++; | 53 | console_six_axis.sampling_number++; |
| 55 | // TODO(German77): Find the purpose of those values | 54 | console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; |
| 56 | console_six_axis.verticalization_error = 0.0f; | 55 | console_six_axis.verticalization_error = motion_status.verticalization_error; |
| 57 | console_six_axis.gyro_bias = {0.0f, 0.0f, 0.0f}; | 56 | console_six_axis.gyro_bias = motion_status.gyro_bias; |
| 58 | 57 | ||
| 59 | // Update console six axis shared memory | 58 | // Update console six axis shared memory |
| 60 | std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis)); | 59 | std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis)); |
| @@ -69,7 +68,6 @@ void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem) { | |||
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | void Controller_ConsoleSixAxis::ResetTimestamp() { | 70 | void Controller_ConsoleSixAxis::ResetTimestamp() { |
| 72 | seven_sixaxis_lifo.buffer_count = 0; | 71 | last_saved_timestamp = last_global_timestamp; |
| 73 | seven_sixaxis_lifo.buffer_tail = 0; | ||
| 74 | } | 72 | } |
| 75 | } // namespace Service::HID | 73 | } // 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: | |||
| 39 | 39 | ||
| 40 | private: | 40 | private: |
| 41 | struct SevenSixAxisState { | 41 | struct SevenSixAxisState { |
| 42 | INSERT_PADDING_WORDS(4); // unused | 42 | INSERT_PADDING_WORDS(2); // unused |
| 43 | s64 sampling_number{}; | 43 | u64 timestamp{}; |
| 44 | u64 sampling_number{}; | ||
| 44 | u64 unknown{}; | 45 | u64 unknown{}; |
| 45 | Common::Vec3f accel{}; | 46 | Common::Vec3f accel{}; |
| 46 | Common::Vec3f gyro{}; | 47 | Common::Vec3f gyro{}; |
| @@ -52,9 +53,10 @@ private: | |||
| 52 | struct ConsoleSharedMemory { | 53 | struct ConsoleSharedMemory { |
| 53 | u64 sampling_number{}; | 54 | u64 sampling_number{}; |
| 54 | bool is_seven_six_axis_sensor_at_rest{}; | 55 | bool is_seven_six_axis_sensor_at_rest{}; |
| 55 | INSERT_PADDING_BYTES(4); // padding | 56 | INSERT_PADDING_BYTES(3); // padding |
| 56 | f32 verticalization_error{}; | 57 | f32 verticalization_error{}; |
| 57 | Common::Vec3f gyro_bias{}; | 58 | Common::Vec3f gyro_bias{}; |
| 59 | INSERT_PADDING_BYTES(4); // padding | ||
| 58 | }; | 60 | }; |
| 59 | static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); | 61 | static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); |
| 60 | 62 | ||
| @@ -64,6 +66,8 @@ private: | |||
| 64 | Core::HID::EmulatedConsole* console; | 66 | Core::HID::EmulatedConsole* console; |
| 65 | u8* transfer_memory = nullptr; | 67 | u8* transfer_memory = nullptr; |
| 66 | bool is_transfer_memory_set = false; | 68 | bool is_transfer_memory_set = false; |
| 69 | u64 last_saved_timestamp{}; | ||
| 70 | u64 last_global_timestamp{}; | ||
| 67 | ConsoleSharedMemory console_six_axis{}; | 71 | ConsoleSharedMemory console_six_axis{}; |
| 68 | SevenSixAxisState next_seven_sixaxis_state{}; | 72 | SevenSixAxisState next_seven_sixaxis_state{}; |
| 69 | }; | 73 | }; |
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_, | |||
| 66 | auto& controller = controller_data[i]; | 66 | auto& controller = controller_data[i]; |
| 67 | controller.device = hid_core.GetEmulatedControllerByIndex(i); | 67 | controller.device = hid_core.GetEmulatedControllerByIndex(i); |
| 68 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = | 68 | controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = |
| 69 | DEFAULT_VIBRATION_VALUE; | 69 | Core::HID::DEFAULT_VIBRATION_VALUE; |
| 70 | controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex].latest_vibration_value = | 70 | controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex].latest_vibration_value = |
| 71 | DEFAULT_VIBRATION_VALUE; | 71 | Core::HID::DEFAULT_VIBRATION_VALUE; |
| 72 | Core::HID::ControllerUpdateCallback engine_callback{ | 72 | Core::HID::ControllerUpdateCallback engine_callback{ |
| 73 | .on_change = [this, | 73 | .on_change = [this, |
| 74 | i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, | 74 | i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, |
| @@ -781,7 +781,8 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | |||
| 781 | Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f}; | 781 | Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f}; |
| 782 | controller.device->SetVibration(device_index, vibration); | 782 | controller.device->SetVibration(device_index, vibration); |
| 783 | // Then reset the vibration value to its default value. | 783 | // Then reset the vibration value to its default value. |
| 784 | controller.vibration[device_index].latest_vibration_value = DEFAULT_VIBRATION_VALUE; | 784 | controller.vibration[device_index].latest_vibration_value = |
| 785 | Core::HID::DEFAULT_VIBRATION_VALUE; | ||
| 785 | } | 786 | } |
| 786 | 787 | ||
| 787 | return false; | 788 | 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: | |||
| 90 | Default = 3, | 90 | Default = 3, |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | static constexpr Core::HID::VibrationValue DEFAULT_VIBRATION_VALUE{ | ||
| 94 | .low_amplitude = 0.0f, | ||
| 95 | .low_frequency = 160.0f, | ||
| 96 | .high_amplitude = 0.0f, | ||
| 97 | .high_frequency = 320.0f, | ||
| 98 | }; | ||
| 99 | |||
| 100 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); | 93 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); |
| 101 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; | 94 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; |
| 102 | 95 | ||
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) { | |||
| 1404 | .high_frequency = 0.0f, | 1404 | .high_frequency = 0.0f, |
| 1405 | }; | 1405 | }; |
| 1406 | default: | 1406 | default: |
| 1407 | return Controller_NPad::DEFAULT_VIBRATION_VALUE; | 1407 | return Core::HID::DEFAULT_VIBRATION_VALUE; |
| 1408 | } | 1408 | } |
| 1409 | }(); | 1409 | }(); |
| 1410 | 1410 | ||
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 @@ | |||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/ipc_helpers.h" | 10 | #include "core/hle/ipc_helpers.h" |
| 11 | #include "core/hle/kernel/k_event.h" | 11 | #include "core/hle/kernel/k_event.h" |
| 12 | #include "core/hle/lock.h" | ||
| 13 | #include "core/hle/service/nfp/nfp.h" | 12 | #include "core/hle/service/nfp/nfp.h" |
| 14 | #include "core/hle/service/nfp/nfp_user.h" | 13 | #include "core/hle/service/nfp/nfp_user.h" |
| 15 | 14 | ||
| @@ -337,7 +336,6 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { | |||
| 337 | } | 336 | } |
| 338 | 337 | ||
| 339 | bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { | 338 | bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { |
| 340 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 341 | if (buffer.size() < sizeof(AmiiboFile)) { | 339 | if (buffer.size() < sizeof(AmiiboFile)) { |
| 342 | return false; | 340 | return false; |
| 343 | } | 341 | } |
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, | |||
| 71 | kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, 0x1FE00000, | 71 | kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, 0x1FE00000, |
| 72 | kip->GetKernelCapabilities()); | 72 | kip->GetKernelCapabilities()); |
| 73 | 73 | ||
| 74 | const VAddr base_address = process.PageTable().GetCodeRegionStart(); | ||
| 75 | Kernel::CodeSet codeset; | 74 | Kernel::CodeSet codeset; |
| 76 | Kernel::PhysicalMemory program_image; | 75 | Kernel::PhysicalMemory program_image; |
| 77 | 76 | ||
| @@ -91,7 +90,14 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, | |||
| 91 | program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize()); | 90 | program_image.resize(PageAlignSize(kip->GetBSSOffset()) + kip->GetBSSSize()); |
| 92 | codeset.DataSegment().size += kip->GetBSSSize(); | 91 | codeset.DataSegment().size += kip->GetBSSSize(); |
| 93 | 92 | ||
| 93 | // Setup the process code layout | ||
| 94 | if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), program_image.size()) | ||
| 95 | .IsError()) { | ||
| 96 | return {ResultStatus::ErrorNotInitialized, {}}; | ||
| 97 | } | ||
| 98 | |||
| 94 | codeset.memory = std::move(program_image); | 99 | codeset.memory = std::move(program_image); |
| 100 | const VAddr base_address = process.PageTable().GetCodeRegionStart(); | ||
| 95 | process.LoadModule(std::move(codeset), base_address); | 101 | process.LoadModule(std::move(codeset), base_address); |
| 96 | 102 | ||
| 97 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); | 103 | 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( | |||
| 536 | std::function<void(u16, u16, u16, u16)> data_callback) { | 536 | std::function<void(u16, u16, u16, u16)> data_callback) { |
| 537 | 537 | ||
| 538 | std::thread([=, this] { | 538 | std::thread([=, this] { |
| 539 | u16 min_x{UINT16_MAX}; | ||
| 540 | u16 min_y{UINT16_MAX}; | ||
| 541 | u16 max_x{}; | ||
| 542 | u16 max_y{}; | ||
| 543 | |||
| 539 | Status current_status{Status::Initialized}; | 544 | Status current_status{Status::Initialized}; |
| 540 | SocketCallback callback{ | 545 | SocketCallback callback{[](Response::Version) {}, [](Response::PortInfo) {}, |
| 541 | [](Response::Version) {}, [](Response::PortInfo) {}, | 546 | [&](Response::PadData data) { |
| 542 | [&](Response::PadData data) { | 547 | constexpr u16 CALIBRATION_THRESHOLD = 100; |
| 543 | static constexpr u16 CALIBRATION_THRESHOLD = 100; | 548 | |
| 544 | static constexpr u16 MAX_VALUE = UINT16_MAX; | 549 | if (current_status == Status::Initialized) { |
| 545 | 550 | // Receiving data means the communication is ready now | |
| 546 | if (current_status == Status::Initialized) { | 551 | current_status = Status::Ready; |
| 547 | // Receiving data means the communication is ready now | 552 | status_callback(current_status); |
| 548 | current_status = Status::Ready; | 553 | } |
| 549 | status_callback(current_status); | 554 | if (data.touch[0].is_active == 0) { |
| 550 | } | 555 | return; |
| 551 | const auto& touchpad_0 = data.touch[0]; | 556 | } |
| 552 | if (touchpad_0.is_active == 0) { | 557 | LOG_DEBUG(Input, "Current touch: {} {}", data.touch[0].x, |
| 553 | return; | 558 | data.touch[0].y); |
| 554 | } | 559 | min_x = std::min(min_x, static_cast<u16>(data.touch[0].x)); |
| 555 | LOG_DEBUG(Input, "Current touch: {} {}", touchpad_0.x, touchpad_0.y); | 560 | min_y = std::min(min_y, static_cast<u16>(data.touch[0].y)); |
| 556 | const u16 min_x = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.x)); | 561 | if (current_status == Status::Ready) { |
| 557 | const u16 min_y = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.y)); | 562 | // First touch - min data (min_x/min_y) |
| 558 | if (current_status == Status::Ready) { | 563 | current_status = Status::Stage1Completed; |
| 559 | // First touch - min data (min_x/min_y) | 564 | status_callback(current_status); |
| 560 | current_status = Status::Stage1Completed; | 565 | } |
| 561 | status_callback(current_status); | 566 | if (data.touch[0].x - min_x > CALIBRATION_THRESHOLD && |
| 562 | } | 567 | data.touch[0].y - min_y > CALIBRATION_THRESHOLD) { |
| 563 | if (touchpad_0.x - min_x > CALIBRATION_THRESHOLD && | 568 | // Set the current position as max value and finishes |
| 564 | touchpad_0.y - min_y > CALIBRATION_THRESHOLD) { | 569 | // configuration |
| 565 | // Set the current position as max value and finishes configuration | 570 | max_x = data.touch[0].x; |
| 566 | const u16 max_x = touchpad_0.x; | 571 | max_y = data.touch[0].y; |
| 567 | const u16 max_y = touchpad_0.y; | 572 | current_status = Status::Completed; |
| 568 | current_status = Status::Completed; | 573 | data_callback(min_x, min_y, max_x, max_y); |
| 569 | data_callback(min_x, min_y, max_x, max_y); | 574 | status_callback(current_status); |
| 570 | status_callback(current_status); | 575 | |
| 571 | 576 | complete_event.Set(); | |
| 572 | complete_event.Set(); | 577 | } |
| 573 | } | 578 | }}; |
| 574 | }}; | ||
| 575 | Socket socket{host, port, std::move(callback)}; | 579 | Socket socket{host, port, std::move(callback)}; |
| 576 | std::thread worker_thread{SocketLoop, &socket}; | 580 | std::thread worker_thread{SocketLoop, &socket}; |
| 577 | complete_event.Wait(); | 581 | 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 { | |||
| 54 | template <typename T> | 54 | template <typename T> |
| 55 | constexpr Type GetMessageType(); | 55 | constexpr Type GetMessageType(); |
| 56 | 56 | ||
| 57 | template <typename T> | ||
| 58 | Message<T> CreateMessage(const u32 magic, const T data, const u32 sender_id) { | ||
| 59 | boost::crc_32_type crc; | ||
| 60 | Header header{ | ||
| 61 | magic, PROTOCOL_VERSION, sizeof(T) + sizeof(Type), 0, sender_id, GetMessageType<T>(), | ||
| 62 | }; | ||
| 63 | Message<T> message{header, data}; | ||
| 64 | crc.process_bytes(&message, sizeof(Message<T>)); | ||
| 65 | message.header.crc = crc.checksum(); | ||
| 66 | return message; | ||
| 67 | } | ||
| 68 | |||
| 57 | namespace Request { | 69 | namespace Request { |
| 58 | 70 | ||
| 59 | enum RegisterFlags : u8 { | 71 | enum RegisterFlags : u8 { |
| @@ -101,14 +113,7 @@ static_assert(std::is_trivially_copyable_v<PadData>, | |||
| 101 | */ | 113 | */ |
| 102 | template <typename T> | 114 | template <typename T> |
| 103 | Message<T> Create(const T data, const u32 client_id = 0) { | 115 | Message<T> Create(const T data, const u32 client_id = 0) { |
| 104 | boost::crc_32_type crc; | 116 | return CreateMessage(CLIENT_MAGIC, data, client_id); |
| 105 | Header header{ | ||
| 106 | CLIENT_MAGIC, PROTOCOL_VERSION, sizeof(T) + sizeof(Type), 0, client_id, GetMessageType<T>(), | ||
| 107 | }; | ||
| 108 | Message<T> message{header, data}; | ||
| 109 | crc.process_bytes(&message, sizeof(Message<T>)); | ||
| 110 | message.header.crc = crc.checksum(); | ||
| 111 | return message; | ||
| 112 | } | 117 | } |
| 113 | } // namespace Request | 118 | } // namespace Request |
| 114 | 119 | ||
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 | |||
| 10 | core/network/network.cpp | 10 | core/network/network.cpp |
| 11 | tests.cpp | 11 | tests.cpp |
| 12 | video_core/buffer_base.cpp | 12 | video_core/buffer_base.cpp |
| 13 | input_common/calibration_configuration_job.cpp | ||
| 13 | ) | 14 | ) |
| 14 | 15 | ||
| 15 | create_target_directory_groups(tests) | 16 | create_target_directory_groups(tests) |
| 16 | 17 | ||
| 17 | target_link_libraries(tests PRIVATE common core) | 18 | target_link_libraries(tests PRIVATE common core input_common) |
| 18 | target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads) | 19 | target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads) |
| 19 | 20 | ||
| 20 | add_test(NAME tests COMMAND tests) | 21 | 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 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <string> | ||
| 7 | #include <thread> | ||
| 8 | #include <boost/asio.hpp> | ||
| 9 | #include <boost/crc.hpp> | ||
| 10 | #include <catch2/catch.hpp> | ||
| 11 | |||
| 12 | #include "input_common/drivers/udp_client.h" | ||
| 13 | #include "input_common/helpers/udp_protocol.h" | ||
| 14 | |||
| 15 | class FakeCemuhookServer { | ||
| 16 | public: | ||
| 17 | FakeCemuhookServer() | ||
| 18 | : socket(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) {} | ||
| 19 | |||
| 20 | ~FakeCemuhookServer() { | ||
| 21 | is_running = false; | ||
| 22 | boost::system::error_code error_code; | ||
| 23 | socket.shutdown(boost::asio::socket_base::shutdown_both, error_code); | ||
| 24 | socket.close(); | ||
| 25 | if (handler.joinable()) { | ||
| 26 | handler.join(); | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | u16 GetPort() { | ||
| 31 | return socket.local_endpoint().port(); | ||
| 32 | } | ||
| 33 | |||
| 34 | std::string GetHost() { | ||
| 35 | return socket.local_endpoint().address().to_string(); | ||
| 36 | } | ||
| 37 | |||
| 38 | void Run(const std::vector<InputCommon::CemuhookUDP::Response::TouchPad> touch_movement_path) { | ||
| 39 | constexpr size_t HeaderSize = sizeof(InputCommon::CemuhookUDP::Header); | ||
| 40 | constexpr size_t PadDataSize = | ||
| 41 | sizeof(InputCommon::CemuhookUDP::Message<InputCommon::CemuhookUDP::Response::PadData>); | ||
| 42 | |||
| 43 | REQUIRE(touch_movement_path.size() > 0); | ||
| 44 | is_running = true; | ||
| 45 | handler = std::thread([touch_movement_path, this]() { | ||
| 46 | auto current_touch_position = touch_movement_path.begin(); | ||
| 47 | while (is_running) { | ||
| 48 | boost::asio::ip::udp::endpoint sender_endpoint; | ||
| 49 | boost::system::error_code error_code; | ||
| 50 | auto received_size = socket.receive_from(boost::asio::buffer(receive_buffer), | ||
| 51 | sender_endpoint, 0, error_code); | ||
| 52 | |||
| 53 | if (received_size < HeaderSize) { | ||
| 54 | continue; | ||
| 55 | } | ||
| 56 | |||
| 57 | InputCommon::CemuhookUDP::Header header{}; | ||
| 58 | std::memcpy(&header, receive_buffer.data(), HeaderSize); | ||
| 59 | switch (header.type) { | ||
| 60 | case InputCommon::CemuhookUDP::Type::PadData: { | ||
| 61 | InputCommon::CemuhookUDP::Response::PadData pad_data{}; | ||
| 62 | pad_data.touch[0] = *current_touch_position; | ||
| 63 | const auto pad_message = InputCommon::CemuhookUDP::CreateMessage( | ||
| 64 | InputCommon::CemuhookUDP::SERVER_MAGIC, pad_data, 0); | ||
| 65 | std::memcpy(send_buffer.data(), &pad_message, PadDataSize); | ||
| 66 | socket.send_to(boost::asio::buffer(send_buffer, PadDataSize), sender_endpoint, | ||
| 67 | 0, error_code); | ||
| 68 | |||
| 69 | bool can_advance = | ||
| 70 | std::next(current_touch_position) != touch_movement_path.end(); | ||
| 71 | if (can_advance) { | ||
| 72 | std::advance(current_touch_position, 1); | ||
| 73 | } | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | case InputCommon::CemuhookUDP::Type::PortInfo: | ||
| 77 | case InputCommon::CemuhookUDP::Type::Version: | ||
| 78 | default: | ||
| 79 | break; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | }); | ||
| 83 | } | ||
| 84 | |||
| 85 | private: | ||
| 86 | boost::asio::io_service io_service; | ||
| 87 | boost::asio::ip::udp::socket socket; | ||
| 88 | std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> send_buffer; | ||
| 89 | std::array<u8, InputCommon::CemuhookUDP::MAX_PACKET_SIZE> receive_buffer; | ||
| 90 | bool is_running = false; | ||
| 91 | std::thread handler; | ||
| 92 | }; | ||
| 93 | |||
| 94 | TEST_CASE("CalibrationConfigurationJob completed", "[input_common]") { | ||
| 95 | Common::Event complete_event; | ||
| 96 | FakeCemuhookServer server; | ||
| 97 | server.Run({{ | ||
| 98 | .is_active = 1, | ||
| 99 | .x = 0, | ||
| 100 | .y = 0, | ||
| 101 | }, | ||
| 102 | { | ||
| 103 | .is_active = 1, | ||
| 104 | .x = 200, | ||
| 105 | .y = 200, | ||
| 106 | }}); | ||
| 107 | |||
| 108 | InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status{}; | ||
| 109 | u16 min_x{}; | ||
| 110 | u16 min_y{}; | ||
| 111 | u16 max_x{}; | ||
| 112 | u16 max_y{}; | ||
| 113 | InputCommon::CemuhookUDP::CalibrationConfigurationJob job( | ||
| 114 | server.GetHost(), server.GetPort(), | ||
| 115 | [&status, | ||
| 116 | &complete_event](InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status status_) { | ||
| 117 | status = status_; | ||
| 118 | if (status == | ||
| 119 | InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed) { | ||
| 120 | complete_event.Set(); | ||
| 121 | } | ||
| 122 | }, | ||
| 123 | [&](u16 min_x_, u16 min_y_, u16 max_x_, u16 max_y_) { | ||
| 124 | min_x = min_x_; | ||
| 125 | min_y = min_y_; | ||
| 126 | max_x = max_x_; | ||
| 127 | max_y = max_y_; | ||
| 128 | }); | ||
| 129 | |||
| 130 | complete_event.WaitUntil(std::chrono::system_clock::now() + std::chrono::seconds(10)); | ||
| 131 | REQUIRE(status == InputCommon::CemuhookUDP::CalibrationConfigurationJob::Status::Completed); | ||
| 132 | REQUIRE(min_x == 0); | ||
| 133 | REQUIRE(min_y == 0); | ||
| 134 | REQUIRE(max_x == 200); | ||
| 135 | REQUIRE(max_y == 200); | ||
| 136 | } | ||
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 2a532b883..04d0f3a2f 100644 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp | |||
| @@ -32,7 +32,7 @@ constexpr std::array PREFERRED_GPU_DECODERS = { | |||
| 32 | #ifdef _WIN32 | 32 | #ifdef _WIN32 |
| 33 | AV_HWDEVICE_TYPE_D3D11VA, | 33 | AV_HWDEVICE_TYPE_D3D11VA, |
| 34 | AV_HWDEVICE_TYPE_DXVA2, | 34 | AV_HWDEVICE_TYPE_DXVA2, |
| 35 | #elif defined(__linux__) | 35 | #elif defined(__unix__) |
| 36 | AV_HWDEVICE_TYPE_VAAPI, | 36 | AV_HWDEVICE_TYPE_VAAPI, |
| 37 | AV_HWDEVICE_TYPE_VDPAU, | 37 | AV_HWDEVICE_TYPE_VDPAU, |
| 38 | #endif | 38 | #endif |
| @@ -130,6 +130,12 @@ bool Codec::CreateGpuAvDevice() { | |||
| 130 | } | 130 | } |
| 131 | if (config->methods & HW_CONFIG_METHOD && config->device_type == type) { | 131 | if (config->methods & HW_CONFIG_METHOD && config->device_type == type) { |
| 132 | av_codec_ctx->pix_fmt = config->pix_fmt; | 132 | av_codec_ctx->pix_fmt = config->pix_fmt; |
| 133 | if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) { | ||
| 134 | // skip zero-copy decoders, we don't currently support them | ||
| 135 | LOG_DEBUG(Service_NVDRV, "Skipping decoder {} with unsupported capability {}.", | ||
| 136 | av_hwdevice_get_type_name(type), config->methods); | ||
| 137 | continue; | ||
| 138 | } | ||
| 133 | LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type)); | 139 | LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type)); |
| 134 | return true; | 140 | return true; |
| 135 | } | 141 | } |
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: | |||
| 92 | 92 | ||
| 93 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); | 93 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); |
| 94 | 94 | ||
| 95 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled) { | 95 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) { |
| 96 | UNIMPLEMENTED(); | 96 | UNIMPLEMENTED(); |
| 97 | } | 97 | } |
| 98 | 98 | ||
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) { | |||
| 437 | 437 | ||
| 438 | glBindTextureUnit(0, fxaa_texture.handle); | 438 | glBindTextureUnit(0, fxaa_texture.handle); |
| 439 | } | 439 | } |
| 440 | |||
| 441 | // Set projection matrix | ||
| 442 | const std::array ortho_matrix = | 440 | const std::array ortho_matrix = |
| 443 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); | 441 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); |
| 444 | 442 | ||
| 445 | GLuint fragment_handle; | 443 | const auto fragment_handle = [this]() { |
| 446 | const auto filter = Settings::values.scaling_filter.GetValue(); | 444 | switch (Settings::values.scaling_filter.GetValue()) { |
| 447 | switch (filter) { | 445 | case Settings::ScalingFilter::NearestNeighbor: |
| 448 | case Settings::ScalingFilter::NearestNeighbor: | 446 | case Settings::ScalingFilter::Bilinear: |
| 449 | fragment_handle = present_bilinear_fragment.handle; | 447 | return present_bilinear_fragment.handle; |
| 450 | break; | 448 | case Settings::ScalingFilter::Bicubic: |
| 451 | case Settings::ScalingFilter::Bilinear: | 449 | return present_bicubic_fragment.handle; |
| 452 | fragment_handle = present_bilinear_fragment.handle; | 450 | case Settings::ScalingFilter::Gaussian: |
| 453 | break; | 451 | return present_gaussian_fragment.handle; |
| 454 | case Settings::ScalingFilter::Bicubic: | 452 | case Settings::ScalingFilter::ScaleForce: |
| 455 | fragment_handle = present_bicubic_fragment.handle; | 453 | return present_scaleforce_fragment.handle; |
| 456 | break; | 454 | case Settings::ScalingFilter::Fsr: |
| 457 | case Settings::ScalingFilter::Gaussian: | 455 | LOG_WARNING( |
| 458 | fragment_handle = present_gaussian_fragment.handle; | 456 | Render_OpenGL, |
| 459 | break; | 457 | "FidelityFX Super Resolution is not supported in OpenGL, changing to ScaleForce"); |
| 460 | case Settings::ScalingFilter::ScaleForce: | 458 | return present_scaleforce_fragment.handle; |
| 461 | fragment_handle = present_scaleforce_fragment.handle; | 459 | default: |
| 462 | break; | 460 | return present_bilinear_fragment.handle; |
| 463 | case Settings::ScalingFilter::Fsr: | 461 | } |
| 464 | LOG_WARNING( | 462 | }(); |
| 465 | Render_OpenGL, | ||
| 466 | "FidelityFX FSR Super Sampling is not supported in OpenGL, changing to ScaleForce"); | ||
| 467 | fragment_handle = present_scaleforce_fragment.handle; | ||
| 468 | break; | ||
| 469 | default: | ||
| 470 | fragment_handle = present_bilinear_fragment.handle; | ||
| 471 | break; | ||
| 472 | } | ||
| 473 | program_manager.BindPresentPrograms(present_vertex.handle, fragment_handle); | 463 | program_manager.BindPresentPrograms(present_vertex.handle, fragment_handle); |
| 474 | glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE, | 464 | glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE, |
| 475 | ortho_matrix.data()); | 465 | 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 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | 6 | ||
| 7 | #include "common/settings.h" | ||
| 7 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" | 8 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" |
| 8 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" | 9 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" |
| 9 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" | 10 | #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 | |||
| 335 | cmdbuf.SetScissor(0, scissor); | 336 | cmdbuf.SetScissor(0, scissor); |
| 336 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); | 337 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); |
| 337 | } | 338 | } |
| 339 | |||
| 340 | VkExtent2D GetConversionExtent(const ImageView& src_image_view) { | ||
| 341 | const auto& resolution = Settings::values.resolution_info; | ||
| 342 | const bool is_rescaled = src_image_view.IsRescaled(); | ||
| 343 | u32 width = src_image_view.size.width; | ||
| 344 | u32 height = src_image_view.size.height; | ||
| 345 | return VkExtent2D{ | ||
| 346 | .width = is_rescaled ? resolution.ScaleUp(width) : width, | ||
| 347 | .height = is_rescaled ? resolution.ScaleUp(height) : height, | ||
| 348 | }; | ||
| 349 | } | ||
| 338 | } // Anonymous namespace | 350 | } // Anonymous namespace |
| 339 | 351 | ||
| 340 | BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, | 352 | BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, |
| @@ -425,61 +437,52 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, | |||
| 425 | } | 437 | } |
| 426 | 438 | ||
| 427 | void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer, | 439 | void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer, |
| 428 | const ImageView& src_image_view, u32 up_scale, | 440 | const ImageView& src_image_view) { |
| 429 | u32 down_shift) { | ||
| 430 | ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass()); | 441 | ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass()); |
| 431 | Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 442 | Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view); |
| 432 | } | 443 | } |
| 433 | 444 | ||
| 434 | void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, | 445 | void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, |
| 435 | const ImageView& src_image_view, u32 up_scale, | 446 | const ImageView& src_image_view) { |
| 436 | u32 down_shift) { | ||
| 437 | ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass()); | 447 | ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass()); |
| 438 | Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 448 | Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view); |
| 439 | } | 449 | } |
| 440 | 450 | ||
| 441 | void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer, | 451 | void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer, |
| 442 | const ImageView& src_image_view, u32 up_scale, | 452 | const ImageView& src_image_view) { |
| 443 | u32 down_shift) { | ||
| 444 | ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass()); | 453 | ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass()); |
| 445 | Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 454 | Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view); |
| 446 | } | 455 | } |
| 447 | 456 | ||
| 448 | void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, | 457 | void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, |
| 449 | const ImageView& src_image_view, u32 up_scale, | 458 | const ImageView& src_image_view) { |
| 450 | u32 down_shift) { | ||
| 451 | ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass()); | 459 | ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass()); |
| 452 | Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 460 | Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view); |
| 453 | } | 461 | } |
| 454 | 462 | ||
| 455 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, | 463 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, |
| 456 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 464 | const ImageView& src_image_view) { |
| 457 | ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), | 465 | ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), |
| 458 | convert_abgr8_to_d24s8_frag, true); | 466 | convert_abgr8_to_d24s8_frag); |
| 459 | ConvertColor(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, | 467 | Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view); |
| 460 | down_shift); | ||
| 461 | } | 468 | } |
| 462 | 469 | ||
| 463 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, | 470 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, |
| 464 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 471 | ImageView& src_image_view) { |
| 465 | ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), | 472 | ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), |
| 466 | convert_d24s8_to_abgr8_frag, false); | 473 | convert_d24s8_to_abgr8_frag); |
| 467 | ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view, up_scale, | 474 | ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view); |
| 468 | down_shift); | ||
| 469 | } | 475 | } |
| 470 | 476 | ||
| 471 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 477 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 472 | const ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 478 | const ImageView& src_image_view) { |
| 473 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | 479 | const VkPipelineLayout layout = *one_texture_pipeline_layout; |
| 474 | const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); | 480 | const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); |
| 475 | const VkSampler sampler = *nearest_sampler; | 481 | const VkSampler sampler = *nearest_sampler; |
| 476 | const VkExtent2D extent{ | 482 | const VkExtent2D extent = GetConversionExtent(src_image_view); |
| 477 | .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), | 483 | |
| 478 | .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U), | ||
| 479 | }; | ||
| 480 | scheduler.RequestRenderpass(dst_framebuffer); | 484 | scheduler.RequestRenderpass(dst_framebuffer); |
| 481 | scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift, | 485 | scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) { |
| 482 | this](vk::CommandBuffer cmdbuf) { | ||
| 483 | const VkOffset2D offset{ | 486 | const VkOffset2D offset{ |
| 484 | .x = 0, | 487 | .x = 0, |
| 485 | .y = 0, | 488 | .y = 0, |
| @@ -563,18 +566,16 @@ void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_f | |||
| 563 | } | 566 | } |
| 564 | 567 | ||
| 565 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 568 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 566 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 569 | ImageView& src_image_view) { |
| 567 | const VkPipelineLayout layout = *two_textures_pipeline_layout; | 570 | const VkPipelineLayout layout = *two_textures_pipeline_layout; |
| 568 | const VkImageView src_depth_view = src_image_view.DepthView(); | 571 | const VkImageView src_depth_view = src_image_view.DepthView(); |
| 569 | const VkImageView src_stencil_view = src_image_view.StencilView(); | 572 | const VkImageView src_stencil_view = src_image_view.StencilView(); |
| 570 | const VkSampler sampler = *nearest_sampler; | 573 | const VkSampler sampler = *nearest_sampler; |
| 571 | const VkExtent2D extent{ | 574 | const VkExtent2D extent = GetConversionExtent(src_image_view); |
| 572 | .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), | 575 | |
| 573 | .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U), | ||
| 574 | }; | ||
| 575 | scheduler.RequestRenderpass(dst_framebuffer); | 576 | scheduler.RequestRenderpass(dst_framebuffer); |
| 576 | scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, up_scale, | 577 | scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, |
| 577 | down_shift, this](vk::CommandBuffer cmdbuf) { | 578 | this](vk::CommandBuffer cmdbuf) { |
| 578 | const VkOffset2D offset{ | 579 | const VkOffset2D offset{ |
| 579 | .x = 0, | 580 | .x = 0, |
| 580 | .y = 0, | 581 | .y = 0, |
| @@ -695,11 +696,14 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip | |||
| 695 | return *blit_depth_stencil_pipelines.back(); | 696 | return *blit_depth_stencil_pipelines.back(); |
| 696 | } | 697 | } |
| 697 | 698 | ||
| 698 | void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | 699 | void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 700 | bool is_target_depth) { | ||
| 699 | if (pipeline) { | 701 | if (pipeline) { |
| 700 | return; | 702 | return; |
| 701 | } | 703 | } |
| 702 | const std::array stages = MakeStages(*full_screen_vert, *convert_depth_to_float_frag); | 704 | VkShaderModule frag_shader = |
| 705 | is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag; | ||
| 706 | const std::array stages = MakeStages(*full_screen_vert, frag_shader); | ||
| 703 | pipeline = device.GetLogical().CreateGraphicsPipeline({ | 707 | pipeline = device.GetLogical().CreateGraphicsPipeline({ |
| 704 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | 708 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, |
| 705 | .pNext = nullptr, | 709 | .pNext = nullptr, |
| @@ -712,8 +716,9 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend | |||
| 712 | .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, | 716 | .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, |
| 713 | .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | 717 | .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, |
| 714 | .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | 718 | .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, |
| 715 | .pDepthStencilState = nullptr, | 719 | .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr, |
| 716 | .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, | 720 | .pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO |
| 721 | : &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO, | ||
| 717 | .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, | 722 | .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, |
| 718 | .layout = *one_texture_pipeline_layout, | 723 | .layout = *one_texture_pipeline_layout, |
| 719 | .renderPass = renderpass, | 724 | .renderPass = renderpass, |
| @@ -723,37 +728,17 @@ void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRend | |||
| 723 | }); | 728 | }); |
| 724 | } | 729 | } |
| 725 | 730 | ||
| 731 | void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | ||
| 732 | ConvertPipeline(pipeline, renderpass, false); | ||
| 733 | } | ||
| 734 | |||
| 726 | void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { | 735 | void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) { |
| 727 | if (pipeline) { | 736 | ConvertPipeline(pipeline, renderpass, true); |
| 728 | return; | ||
| 729 | } | ||
| 730 | const std::array stages = MakeStages(*full_screen_vert, *convert_float_to_depth_frag); | ||
| 731 | pipeline = device.GetLogical().CreateGraphicsPipeline({ | ||
| 732 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | ||
| 733 | .pNext = nullptr, | ||
| 734 | .flags = 0, | ||
| 735 | .stageCount = static_cast<u32>(stages.size()), | ||
| 736 | .pStages = stages.data(), | ||
| 737 | .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | ||
| 738 | .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | ||
| 739 | .pTessellationState = nullptr, | ||
| 740 | .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, | ||
| 741 | .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | ||
| 742 | .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | ||
| 743 | .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, | ||
| 744 | .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO, | ||
| 745 | .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, | ||
| 746 | .layout = *one_texture_pipeline_layout, | ||
| 747 | .renderPass = renderpass, | ||
| 748 | .subpass = 0, | ||
| 749 | .basePipelineHandle = VK_NULL_HANDLE, | ||
| 750 | .basePipelineIndex = 0, | ||
| 751 | }); | ||
| 752 | } | 737 | } |
| 753 | 738 | ||
| 754 | void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 739 | void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 755 | vk::ShaderModule& module, bool is_target_depth, | 740 | vk::ShaderModule& module, bool single_texture, |
| 756 | bool single_texture) { | 741 | bool is_target_depth) { |
| 757 | if (pipeline) { | 742 | if (pipeline) { |
| 758 | return; | 743 | return; |
| 759 | } | 744 | } |
| @@ -782,13 +767,13 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass ren | |||
| 782 | } | 767 | } |
| 783 | 768 | ||
| 784 | void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 769 | void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 785 | vk::ShaderModule& module, bool single_texture) { | 770 | vk::ShaderModule& module) { |
| 786 | ConvertPipelineEx(pipeline, renderpass, module, false, single_texture); | 771 | ConvertPipelineEx(pipeline, renderpass, module, false, false); |
| 787 | } | 772 | } |
| 788 | 773 | ||
| 789 | void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 774 | void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 790 | vk::ShaderModule& module, bool single_texture) { | 775 | vk::ShaderModule& module) { |
| 791 | ConvertPipelineEx(pipeline, renderpass, module, true, single_texture); | 776 | ConvertPipelineEx(pipeline, renderpass, module, true, true); |
| 792 | } | 777 | } |
| 793 | 778 | ||
| 794 | } // namespace Vulkan | 779 | } // 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: | |||
| 44 | const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, | 44 | const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, |
| 45 | Tegra::Engines::Fermi2D::Operation operation); | 45 | Tegra::Engines::Fermi2D::Operation operation); |
| 46 | 46 | ||
| 47 | void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 47 | void ConvertD32ToR32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 48 | u32 up_scale, u32 down_shift); | ||
| 49 | 48 | ||
| 50 | void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 49 | void ConvertR32ToD32(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 51 | u32 up_scale, u32 down_shift); | ||
| 52 | 50 | ||
| 53 | void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 51 | void ConvertD16ToR16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 54 | u32 up_scale, u32 down_shift); | ||
| 55 | 52 | ||
| 56 | void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 53 | void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 57 | u32 up_scale, u32 down_shift); | ||
| 58 | 54 | ||
| 59 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | 55 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 60 | u32 up_scale, u32 down_shift); | ||
| 61 | 56 | ||
| 62 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | 57 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); |
| 63 | u32 up_scale, u32 down_shift); | ||
| 64 | 58 | ||
| 65 | private: | 59 | private: |
| 66 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 60 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 67 | const ImageView& src_image_view, u32 up_scale, u32 down_shift); | 61 | const ImageView& src_image_view); |
| 68 | 62 | ||
| 69 | void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 63 | void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 70 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | 64 | ImageView& src_image_view, u32 up_scale, u32 down_shift); |
| 71 | 65 | ||
| 72 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 66 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 73 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | 67 | ImageView& src_image_view); |
| 74 | 68 | ||
| 75 | [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); | 69 | [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); |
| 76 | 70 | ||
| 77 | [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); | 71 | [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); |
| 78 | 72 | ||
| 73 | void ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass, bool is_target_depth); | ||
| 74 | |||
| 79 | void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); | 75 | void ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); |
| 80 | 76 | ||
| 81 | void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); | 77 | void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); |
| 82 | 78 | ||
| 83 | void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 79 | void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 84 | vk::ShaderModule& module, bool is_target_depth, bool single_texture); | 80 | vk::ShaderModule& module, bool single_texture, bool is_target_depth); |
| 85 | 81 | ||
| 86 | void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 82 | void ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 87 | vk::ShaderModule& module, bool single_texture); | 83 | vk::ShaderModule& module); |
| 88 | 84 | ||
| 89 | void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | 85 | void ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass, |
| 90 | vk::ShaderModule& module, bool single_texture); | 86 | vk::ShaderModule& module); |
| 91 | 87 | ||
| 92 | const Device& device; | 88 | const Device& device; |
| 93 | VKScheduler& scheduler; | 89 | 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, | |||
| 391 | .offset = {0, 0}, | 391 | .offset = {0, 0}, |
| 392 | .extent = size, | 392 | .extent = size, |
| 393 | }; | 393 | }; |
| 394 | const auto filter = Settings::values.scaling_filter.GetValue(); | ||
| 395 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); | 394 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); |
| 396 | switch (filter) { | 395 | auto graphics_pipeline = [this]() { |
| 397 | case Settings::ScalingFilter::NearestNeighbor: | 396 | switch (Settings::values.scaling_filter.GetValue()) { |
| 398 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | 397 | case Settings::ScalingFilter::NearestNeighbor: |
| 399 | break; | 398 | case Settings::ScalingFilter::Bilinear: |
| 400 | case Settings::ScalingFilter::Bilinear: | 399 | return *bilinear_pipeline; |
| 401 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | 400 | case Settings::ScalingFilter::Bicubic: |
| 402 | break; | 401 | return *bicubic_pipeline; |
| 403 | case Settings::ScalingFilter::Bicubic: | 402 | case Settings::ScalingFilter::Gaussian: |
| 404 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bicubic_pipeline); | 403 | return *gaussian_pipeline; |
| 405 | break; | 404 | case Settings::ScalingFilter::ScaleForce: |
| 406 | case Settings::ScalingFilter::Gaussian: | 405 | return *scaleforce_pipeline; |
| 407 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *gaussian_pipeline); | 406 | default: |
| 408 | break; | 407 | return *bilinear_pipeline; |
| 409 | case Settings::ScalingFilter::ScaleForce: | 408 | } |
| 410 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *scaleforce_pipeline); | 409 | }(); |
| 411 | break; | 410 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline); |
| 412 | default: | ||
| 413 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *bilinear_pipeline); | ||
| 414 | break; | ||
| 415 | } | ||
| 416 | cmdbuf.SetViewport(0, viewport); | 411 | cmdbuf.SetViewport(0, viewport); |
| 417 | cmdbuf.SetScissor(0, scissor); | 412 | cmdbuf.SetScissor(0, scissor); |
| 418 | 413 | ||
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 616a7b457..d514b71d0 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -605,7 +605,11 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 605 | .flags = 0, | 605 | .flags = 0, |
| 606 | .topology = input_assembly_topology, | 606 | .topology = input_assembly_topology, |
| 607 | .primitiveRestartEnable = key.state.primitive_restart_enable != 0 && | 607 | .primitiveRestartEnable = key.state.primitive_restart_enable != 0 && |
| 608 | SupportsPrimitiveRestart(input_assembly_topology), | 608 | ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && |
| 609 | device.IsTopologyListPrimitiveRestartSupported()) || | ||
| 610 | SupportsPrimitiveRestart(input_assembly_topology) || | ||
| 611 | (input_assembly_topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && | ||
| 612 | device.IsPatchListPrimitiveRestartSupported())), | ||
| 609 | }; | 613 | }; |
| 610 | const VkPipelineTessellationStateCreateInfo tessellation_ci{ | 614 | const VkPipelineTessellationStateCreateInfo tessellation_ci{ |
| 611 | .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, | 615 | .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, |
| @@ -613,7 +617,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 613 | .flags = 0, | 617 | .flags = 0, |
| 614 | .patchControlPoints = key.state.patch_control_points_minus_one.Value() + 1, | 618 | .patchControlPoints = key.state.patch_control_points_minus_one.Value() + 1, |
| 615 | }; | 619 | }; |
| 616 | |||
| 617 | std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles; | 620 | std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles; |
| 618 | std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle); | 621 | std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle); |
| 619 | const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{ | 622 | const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{ |
| @@ -748,8 +751,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 748 | .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, | 751 | .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, |
| 749 | .pNext = nullptr, | 752 | .pNext = nullptr, |
| 750 | .flags = 0, | 753 | .flags = 0, |
| 751 | .logicOpEnable = VK_FALSE, | 754 | .logicOpEnable = key.state.logic_op_enable != 0, |
| 752 | .logicOp = VK_LOGIC_OP_COPY, | 755 | .logicOp = static_cast<VkLogicOp>(key.state.logic_op.Value()), |
| 753 | .attachmentCount = static_cast<u32>(cb_attachments.size()), | 756 | .attachmentCount = static_cast<u32>(cb_attachments.size()), |
| 754 | .pAttachments = cb_attachments.data(), | 757 | .pAttachments = cb_attachments.data(), |
| 755 | .blendConstants = {}, | 758 | .blendConstants = {}, |
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 | |||
| 1057 | }); | 1057 | }); |
| 1058 | } | 1058 | } |
| 1059 | 1059 | ||
| 1060 | void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, | 1060 | void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) { |
| 1061 | bool rescaled) { | ||
| 1062 | const u32 up_scale = rescaled ? resolution.up_scale : 1; | ||
| 1063 | const u32 down_shift = rescaled ? resolution.down_shift : 0; | ||
| 1064 | switch (dst_view.format) { | 1061 | switch (dst_view.format) { |
| 1065 | case PixelFormat::R16_UNORM: | 1062 | case PixelFormat::R16_UNORM: |
| 1066 | if (src_view.format == PixelFormat::D16_UNORM) { | 1063 | if (src_view.format == PixelFormat::D16_UNORM) { |
| 1067 | return blit_image_helper.ConvertD16ToR16(dst, src_view, up_scale, down_shift); | 1064 | return blit_image_helper.ConvertD16ToR16(dst, src_view); |
| 1068 | } | 1065 | } |
| 1069 | break; | 1066 | break; |
| 1070 | case PixelFormat::A8B8G8R8_UNORM: | 1067 | case PixelFormat::A8B8G8R8_UNORM: |
| 1071 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { | 1068 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { |
| 1072 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift); | 1069 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view); |
| 1073 | } | 1070 | } |
| 1074 | break; | 1071 | break; |
| 1075 | case PixelFormat::R32_FLOAT: | 1072 | case PixelFormat::R32_FLOAT: |
| 1076 | if (src_view.format == PixelFormat::D32_FLOAT) { | 1073 | if (src_view.format == PixelFormat::D32_FLOAT) { |
| 1077 | return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift); | 1074 | return blit_image_helper.ConvertD32ToR32(dst, src_view); |
| 1078 | } | 1075 | } |
| 1079 | break; | 1076 | break; |
| 1080 | case PixelFormat::D16_UNORM: | 1077 | case PixelFormat::D16_UNORM: |
| 1081 | if (src_view.format == PixelFormat::R16_UNORM) { | 1078 | if (src_view.format == PixelFormat::R16_UNORM) { |
| 1082 | return blit_image_helper.ConvertR16ToD16(dst, src_view, up_scale, down_shift); | 1079 | return blit_image_helper.ConvertR16ToD16(dst, src_view); |
| 1083 | } | 1080 | } |
| 1084 | break; | 1081 | break; |
| 1085 | case PixelFormat::S8_UINT_D24_UNORM: | 1082 | case PixelFormat::S8_UINT_D24_UNORM: |
| 1086 | return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift); | 1083 | if (src_view.format == PixelFormat::A8B8G8R8_UNORM || |
| 1084 | src_view.format == PixelFormat::B8G8R8A8_UNORM) { | ||
| 1085 | return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view); | ||
| 1086 | } | ||
| 1087 | break; | 1087 | break; |
| 1088 | case PixelFormat::D32_FLOAT: | 1088 | case PixelFormat::D32_FLOAT: |
| 1089 | if (src_view.format == PixelFormat::R32_FLOAT) { | 1089 | if (src_view.format == PixelFormat::R32_FLOAT) { |
| 1090 | return blit_image_helper.ConvertR32ToD32(dst, src_view, up_scale, down_shift); | 1090 | return blit_image_helper.ConvertR32ToD32(dst, src_view); |
| 1091 | } | 1091 | } |
| 1092 | break; | 1092 | break; |
| 1093 | default: | 1093 | default: |
| @@ -1329,6 +1329,10 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm | |||
| 1329 | } | 1329 | } |
| 1330 | } | 1330 | } |
| 1331 | 1331 | ||
| 1332 | bool Image::IsRescaled() const noexcept { | ||
| 1333 | return True(flags & ImageFlagBits::Rescaled); | ||
| 1334 | } | ||
| 1335 | |||
| 1332 | bool Image::ScaleUp(bool ignore) { | 1336 | bool Image::ScaleUp(bool ignore) { |
| 1333 | if (True(flags & ImageFlagBits::Rescaled)) { | 1337 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 1334 | return false; | 1338 | return false; |
| @@ -1469,7 +1473,8 @@ bool Image::BlitScaleHelper(bool scale_up) { | |||
| 1469 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, | 1473 | ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, |
| 1470 | ImageId image_id_, Image& image) | 1474 | ImageId image_id_, Image& image) |
| 1471 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, | 1475 | : VideoCommon::ImageViewBase{info, image.info, image_id_}, device{&runtime.device}, |
| 1472 | image_handle{image.Handle()}, samples{ConvertSampleCount(image.info.num_samples)} { | 1476 | src_image{&image}, image_handle{image.Handle()}, |
| 1477 | samples(ConvertSampleCount(image.info.num_samples)) { | ||
| 1473 | using Shader::TextureType; | 1478 | using Shader::TextureType; |
| 1474 | 1479 | ||
| 1475 | const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); | 1480 | const VkImageAspectFlags aspect_mask = ImageViewAspectMask(info); |
| @@ -1607,6 +1612,13 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type, | |||
| 1607 | return *view; | 1612 | return *view; |
| 1608 | } | 1613 | } |
| 1609 | 1614 | ||
| 1615 | bool ImageView::IsRescaled() const noexcept { | ||
| 1616 | if (!src_image) { | ||
| 1617 | return false; | ||
| 1618 | } | ||
| 1619 | return src_image->IsRescaled(); | ||
| 1620 | } | ||
| 1621 | |||
| 1610 | vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { | 1622 | vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { |
| 1611 | return device->GetLogical().CreateImageView({ | 1623 | return device->GetLogical().CreateImageView({ |
| 1612 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, | 1624 | .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: | |||
| 65 | 65 | ||
| 66 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); | 66 | void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies); |
| 67 | 67 | ||
| 68 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view, bool rescaled); | 68 | void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view); |
| 69 | 69 | ||
| 70 | bool CanAccelerateImageUpload(Image&) const noexcept { | 70 | bool CanAccelerateImageUpload(Image&) const noexcept { |
| 71 | return false; | 71 | return false; |
| @@ -139,6 +139,8 @@ public: | |||
| 139 | return std::exchange(initialized, true); | 139 | return std::exchange(initialized, true); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | bool IsRescaled() const noexcept; | ||
| 143 | |||
| 142 | bool ScaleUp(bool ignore = false); | 144 | bool ScaleUp(bool ignore = false); |
| 143 | 145 | ||
| 144 | bool ScaleDown(bool ignore = false); | 146 | bool ScaleDown(bool ignore = false); |
| @@ -189,6 +191,8 @@ public: | |||
| 189 | [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, | 191 | [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, |
| 190 | Shader::ImageFormat image_format); | 192 | Shader::ImageFormat image_format); |
| 191 | 193 | ||
| 194 | [[nodiscard]] bool IsRescaled() const noexcept; | ||
| 195 | |||
| 192 | [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { | 196 | [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { |
| 193 | return *image_views[static_cast<size_t>(texture_type)]; | 197 | return *image_views[static_cast<size_t>(texture_type)]; |
| 194 | } | 198 | } |
| @@ -222,6 +226,8 @@ private: | |||
| 222 | [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); | 226 | [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); |
| 223 | 227 | ||
| 224 | const Device* device = nullptr; | 228 | const Device* device = nullptr; |
| 229 | const Image* src_image{}; | ||
| 230 | |||
| 225 | std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; | 231 | std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> image_views; |
| 226 | std::unique_ptr<StorageViews> storage_views; | 232 | std::unique_ptr<StorageViews> storage_views; |
| 227 | vk::ImageView depth_view; | 233 | 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 | |||
| 1855 | .height = std::min(dst_view.size.height, src_view.size.height), | 1855 | .height = std::min(dst_view.size.height, src_view.size.height), |
| 1856 | .depth = std::min(dst_view.size.depth, src_view.size.depth), | 1856 | .depth = std::min(dst_view.size.depth, src_view.size.depth), |
| 1857 | }; | 1857 | }; |
| 1858 | UNIMPLEMENTED_IF(copy.extent != expected_size); | 1858 | const Extent3D scaled_extent = [is_rescaled, expected_size]() { |
| 1859 | if (!is_rescaled) { | ||
| 1860 | return expected_size; | ||
| 1861 | } | ||
| 1862 | const auto& resolution = Settings::values.resolution_info; | ||
| 1863 | return Extent3D{ | ||
| 1864 | .width = resolution.ScaleUp(expected_size.width), | ||
| 1865 | .height = resolution.ScaleUp(expected_size.height), | ||
| 1866 | .depth = expected_size.depth, | ||
| 1867 | }; | ||
| 1868 | }(); | ||
| 1869 | UNIMPLEMENTED_IF(copy.extent != scaled_extent); | ||
| 1859 | 1870 | ||
| 1860 | runtime.ConvertImage(dst_framebuffer, dst_view, src_view, is_rescaled); | 1871 | runtime.ConvertImage(dst_framebuffer, dst_view, src_view); |
| 1861 | } | 1872 | } |
| 1862 | } | 1873 | } |
| 1863 | 1874 | ||
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 7bf5b6578..9862b815b 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -271,7 +271,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 271 | .tessellationShader = true, | 271 | .tessellationShader = true, |
| 272 | .sampleRateShading = true, | 272 | .sampleRateShading = true, |
| 273 | .dualSrcBlend = true, | 273 | .dualSrcBlend = true, |
| 274 | .logicOp = false, | 274 | .logicOp = true, |
| 275 | .multiDrawIndirect = false, | 275 | .multiDrawIndirect = false, |
| 276 | .drawIndirectFirstInstance = false, | 276 | .drawIndirectFirstInstance = false, |
| 277 | .depthClamp = true, | 277 | .depthClamp = true, |
| @@ -433,6 +433,19 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 433 | LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); | 433 | LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart; | ||
| 437 | if (is_topology_list_restart_supported || is_patch_list_restart_supported) { | ||
| 438 | primitive_topology_list_restart = { | ||
| 439 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, | ||
| 440 | .pNext = nullptr, | ||
| 441 | .primitiveTopologyListRestart = is_topology_list_restart_supported, | ||
| 442 | .primitiveTopologyPatchListRestart = is_patch_list_restart_supported, | ||
| 443 | }; | ||
| 444 | SetNext(next, primitive_topology_list_restart); | ||
| 445 | } else { | ||
| 446 | LOG_INFO(Render_Vulkan, "Device doesn't support list topology primitive restart"); | ||
| 447 | } | ||
| 448 | |||
| 436 | VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback; | 449 | VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback; |
| 437 | if (ext_transform_feedback) { | 450 | if (ext_transform_feedback) { |
| 438 | transform_feedback = { | 451 | transform_feedback = { |
| @@ -891,6 +904,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 891 | bool has_ext_provoking_vertex{}; | 904 | bool has_ext_provoking_vertex{}; |
| 892 | bool has_ext_vertex_input_dynamic_state{}; | 905 | bool has_ext_vertex_input_dynamic_state{}; |
| 893 | bool has_ext_line_rasterization{}; | 906 | bool has_ext_line_rasterization{}; |
| 907 | bool has_ext_primitive_topology_list_restart{}; | ||
| 894 | for (const std::string& extension : supported_extensions) { | 908 | for (const std::string& extension : supported_extensions) { |
| 895 | const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name, | 909 | const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name, |
| 896 | bool push) { | 910 | bool push) { |
| @@ -915,6 +929,8 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 915 | test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); | 929 | test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); |
| 916 | test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); | 930 | test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); |
| 917 | test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); | 931 | test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); |
| 932 | test(has_ext_primitive_topology_list_restart, | ||
| 933 | VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME, true); | ||
| 918 | test(ext_sampler_filter_minmax, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, true); | 934 | test(ext_sampler_filter_minmax, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, true); |
| 919 | test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, | 935 | test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, |
| 920 | true); | 936 | true); |
| @@ -1113,6 +1129,19 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1113 | khr_pipeline_executable_properties = true; | 1129 | khr_pipeline_executable_properties = true; |
| 1114 | } | 1130 | } |
| 1115 | } | 1131 | } |
| 1132 | if (has_ext_primitive_topology_list_restart) { | ||
| 1133 | VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart{}; | ||
| 1134 | primitive_topology_list_restart.sType = | ||
| 1135 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; | ||
| 1136 | primitive_topology_list_restart.pNext = nullptr; | ||
| 1137 | features.pNext = &primitive_topology_list_restart; | ||
| 1138 | physical.GetFeatures2KHR(features); | ||
| 1139 | |||
| 1140 | is_topology_list_restart_supported = | ||
| 1141 | primitive_topology_list_restart.primitiveTopologyListRestart; | ||
| 1142 | is_patch_list_restart_supported = | ||
| 1143 | primitive_topology_list_restart.primitiveTopologyPatchListRestart; | ||
| 1144 | } | ||
| 1116 | if (has_khr_image_format_list && has_khr_swapchain_mutable_format) { | 1145 | if (has_khr_image_format_list && has_khr_swapchain_mutable_format) { |
| 1117 | extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); | 1146 | extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); |
| 1118 | extensions.push_back(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME); | 1147 | extensions.push_back(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME); |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 10653ac6b..4c9d86aad 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -238,6 +238,16 @@ public: | |||
| 238 | return khr_workgroup_memory_explicit_layout; | 238 | return khr_workgroup_memory_explicit_layout; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | /// Returns true if the device supports VK_EXT_primitive_topology_list_restart. | ||
| 242 | bool IsTopologyListPrimitiveRestartSupported() const { | ||
| 243 | return is_topology_list_restart_supported; | ||
| 244 | } | ||
| 245 | |||
| 246 | /// Returns true if the device supports VK_EXT_primitive_topology_list_restart. | ||
| 247 | bool IsPatchListPrimitiveRestartSupported() const { | ||
| 248 | return is_patch_list_restart_supported; | ||
| 249 | } | ||
| 250 | |||
| 241 | /// Returns true if the device supports VK_EXT_index_type_uint8. | 251 | /// Returns true if the device supports VK_EXT_index_type_uint8. |
| 242 | bool IsExtIndexTypeUint8Supported() const { | 252 | bool IsExtIndexTypeUint8Supported() const { |
| 243 | return ext_index_type_uint8; | 253 | return ext_index_type_uint8; |
| @@ -401,6 +411,9 @@ private: | |||
| 401 | bool is_shader_int16_supported{}; ///< Support for int16. | 411 | bool is_shader_int16_supported{}; ///< Support for int16. |
| 402 | bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. | 412 | bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. |
| 403 | bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. | 413 | bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. |
| 414 | bool is_topology_list_restart_supported{}; ///< Support for primitive restart with list | ||
| 415 | ///< topologies. | ||
| 416 | bool is_patch_list_restart_supported{}; ///< Support for primitive restart with list patch. | ||
| 404 | bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. | 417 | bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. |
| 405 | bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. | 418 | bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. |
| 406 | bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough. | 419 | bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough. |
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 @@ | |||
| 12 | #include "core/hid/emulated_controller.h" | 12 | #include "core/hid/emulated_controller.h" |
| 13 | #include "core/hid/hid_core.h" | 13 | #include "core/hid/hid_core.h" |
| 14 | #include "core/hid/hid_types.h" | 14 | #include "core/hid/hid_types.h" |
| 15 | #include "core/hle/lock.h" | ||
| 16 | #include "core/hle/service/hid/controllers/npad.h" | 15 | #include "core/hle/service/hid/controllers/npad.h" |
| 17 | #include "core/hle/service/hid/hid.h" | 16 | #include "core/hle/service/hid/hid.h" |
| 18 | #include "core/hle/service/sm/sm.h" | 17 | #include "core/hle/service/sm/sm.h" |
| @@ -664,7 +663,5 @@ void QtControllerSelector::ReconfigureControllers( | |||
| 664 | } | 663 | } |
| 665 | 664 | ||
| 666 | void QtControllerSelector::MainWindowReconfigureFinished() { | 665 | void QtControllerSelector::MainWindowReconfigureFinished() { |
| 667 | // Acquire the HLE mutex | ||
| 668 | std::lock_guard lock(HLE::g_hle_lock); | ||
| 669 | callback(); | 666 | callback(); |
| 670 | } | 667 | } |
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 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <QDateTime> | 5 | #include <QDateTime> |
| 6 | #include "core/hle/lock.h" | ||
| 7 | #include "yuzu/applets/qt_error.h" | 6 | #include "yuzu/applets/qt_error.h" |
| 8 | #include "yuzu/main.h" | 7 | #include "yuzu/main.h" |
| 9 | 8 | ||
| @@ -57,7 +56,5 @@ void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_te | |||
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | void QtErrorDisplay::MainWindowFinishedError() { | 58 | void QtErrorDisplay::MainWindowFinishedError() { |
| 60 | // Acquire the HLE mutex | ||
| 61 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 62 | callback(); | 59 | callback(); |
| 63 | } | 60 | } |
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 @@ | |||
| 14 | #include "common/fs/path_util.h" | 14 | #include "common/fs/path_util.h" |
| 15 | #include "common/string_util.h" | 15 | #include "common/string_util.h" |
| 16 | #include "core/constants.h" | 16 | #include "core/constants.h" |
| 17 | #include "core/hle/lock.h" | ||
| 18 | #include "yuzu/applets/qt_profile_select.h" | 17 | #include "yuzu/applets/qt_profile_select.h" |
| 19 | #include "yuzu/main.h" | 18 | #include "yuzu/main.h" |
| 20 | #include "yuzu/util/controller_navigation.h" | 19 | #include "yuzu/util/controller_navigation.h" |
| @@ -170,7 +169,5 @@ void QtProfileSelector::SelectProfile( | |||
| 170 | } | 169 | } |
| 171 | 170 | ||
| 172 | void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) { | 171 | void QtProfileSelector::MainWindowFinishedSelection(std::optional<Common::UUID> uuid) { |
| 173 | // Acquire the HLE mutex | ||
| 174 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 175 | callback(uuid); | 172 | callback(uuid); |
| 176 | } | 173 | } |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index b7bb43348..a7271e075 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -2546,39 +2546,30 @@ void GMainWindow::ToggleFullscreen() { | |||
| 2546 | } | 2546 | } |
| 2547 | 2547 | ||
| 2548 | void GMainWindow::ShowFullscreen() { | 2548 | void GMainWindow::ShowFullscreen() { |
| 2549 | const auto show_fullscreen = [](QWidget* window) { | ||
| 2550 | if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { | ||
| 2551 | window->showFullScreen(); | ||
| 2552 | return; | ||
| 2553 | } | ||
| 2554 | window->hide(); | ||
| 2555 | window->setWindowFlags(window->windowFlags() | Qt::FramelessWindowHint); | ||
| 2556 | const auto screen_geometry = QApplication::desktop()->screenGeometry(window); | ||
| 2557 | window->setGeometry(screen_geometry.x(), screen_geometry.y(), screen_geometry.width(), | ||
| 2558 | screen_geometry.height() + 1); | ||
| 2559 | window->raise(); | ||
| 2560 | window->showNormal(); | ||
| 2561 | }; | ||
| 2562 | |||
| 2549 | if (ui->action_Single_Window_Mode->isChecked()) { | 2563 | if (ui->action_Single_Window_Mode->isChecked()) { |
| 2550 | UISettings::values.geometry = saveGeometry(); | 2564 | UISettings::values.geometry = saveGeometry(); |
| 2551 | 2565 | ||
| 2552 | ui->menubar->hide(); | 2566 | ui->menubar->hide(); |
| 2553 | statusBar()->hide(); | 2567 | statusBar()->hide(); |
| 2554 | 2568 | ||
| 2555 | if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { | 2569 | show_fullscreen(this); |
| 2556 | showFullScreen(); | ||
| 2557 | return; | ||
| 2558 | } | ||
| 2559 | |||
| 2560 | hide(); | ||
| 2561 | setWindowFlags(windowFlags() | Qt::FramelessWindowHint); | ||
| 2562 | const auto screen_geometry = QApplication::desktop()->screenGeometry(this); | ||
| 2563 | setGeometry(screen_geometry.x(), screen_geometry.y(), screen_geometry.width(), | ||
| 2564 | screen_geometry.height() + 1); | ||
| 2565 | raise(); | ||
| 2566 | showNormal(); | ||
| 2567 | } else { | 2570 | } else { |
| 2568 | UISettings::values.renderwindow_geometry = render_window->saveGeometry(); | 2571 | UISettings::values.renderwindow_geometry = render_window->saveGeometry(); |
| 2569 | 2572 | show_fullscreen(render_window); | |
| 2570 | if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) { | ||
| 2571 | render_window->showFullScreen(); | ||
| 2572 | return; | ||
| 2573 | } | ||
| 2574 | |||
| 2575 | render_window->hide(); | ||
| 2576 | render_window->setWindowFlags(windowFlags() | Qt::FramelessWindowHint); | ||
| 2577 | const auto screen_geometry = QApplication::desktop()->screenGeometry(this); | ||
| 2578 | render_window->setGeometry(screen_geometry.x(), screen_geometry.y(), | ||
| 2579 | screen_geometry.width(), screen_geometry.height() + 1); | ||
| 2580 | render_window->raise(); | ||
| 2581 | render_window->showNormal(); | ||
| 2582 | } | 2573 | } |
| 2583 | } | 2574 | } |
| 2584 | 2575 | ||