diff options
26 files changed, 244 insertions, 131 deletions
diff --git a/.gitmodules b/.gitmodules index 95eae8109..89f2ad924 100644 --- a/.gitmodules +++ b/.gitmodules | |||
| @@ -52,3 +52,6 @@ | |||
| 52 | [submodule "libadrenotools"] | 52 | [submodule "libadrenotools"] |
| 53 | path = externals/libadrenotools | 53 | path = externals/libadrenotools |
| 54 | url = https://github.com/bylaws/libadrenotools | 54 | url = https://github.com/bylaws/libadrenotools |
| 55 | [submodule "tzdb_to_nx"] | ||
| 56 | path = externals/nx_tzdb/tzdb_to_nx | ||
| 57 | url = https://github.com/lat9nq/tzdb_to_nx.git | ||
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d03bbf94..6d3146c9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -59,6 +59,8 @@ option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ON) | |||
| 59 | 59 | ||
| 60 | option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF) | 60 | option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF) |
| 61 | 61 | ||
| 62 | option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" OFF) | ||
| 63 | |||
| 62 | CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "NOT WIN32" OFF) | 64 | CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "NOT WIN32" OFF) |
| 63 | 65 | ||
| 64 | # On Android, fetch and compile libcxx before doing anything else | 66 | # On Android, fetch and compile libcxx before doing anything else |
diff --git a/externals/nx_tzdb/CMakeLists.txt b/externals/nx_tzdb/CMakeLists.txt index 2f625c108..d5a1c6317 100644 --- a/externals/nx_tzdb/CMakeLists.txt +++ b/externals/nx_tzdb/CMakeLists.txt | |||
| @@ -1,24 +1,60 @@ | |||
| 1 | # SPDX-FileCopyrightText: 2023 yuzu Emulator Project | 1 | # SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
| 2 | # SPDX-License-Identifier: GPL-2.0-or-later | 2 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | set(NX_TZDB_VERSION "220816") | 4 | set(NX_TZDB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include") |
| 5 | set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip") | 5 | |
| 6 | add_library(nx_tzdb INTERFACE) | ||
| 7 | |||
| 8 | find_program(GIT git) | ||
| 9 | find_program(GNU_MAKE make) | ||
| 10 | find_program(GNU_DATE date) | ||
| 6 | 11 | ||
| 12 | set(CAN_BUILD_NX_TZDB true) | ||
| 13 | |||
| 14 | if (NOT GIT) | ||
| 15 | set(CAN_BUILD_NX_TZDB false) | ||
| 16 | endif() | ||
| 17 | if (NOT GNU_MAKE) | ||
| 18 | set(CAN_BUILD_NX_TZDB false) | ||
| 19 | endif() | ||
| 20 | if (NOT GNU_DATE) | ||
| 21 | set(CAN_BUILD_NX_TZDB false) | ||
| 22 | endif() | ||
| 23 | if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID) | ||
| 24 | # tzdb_to_nx currently requires a posix-compliant host | ||
| 25 | # MinGW and Android are handled here due to the executable format being different from the host system | ||
| 26 | # TODO (lat9nq): cross-compiling support | ||
| 27 | set(CAN_BUILD_NX_TZDB false) | ||
| 28 | endif() | ||
| 29 | |||
| 30 | set(NX_TZDB_VERSION "220816") | ||
| 7 | set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip") | 31 | set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip") |
| 8 | set(NX_TZDB_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb") | ||
| 9 | 32 | ||
| 10 | set(NX_TZDB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include") | 33 | set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb") |
| 34 | |||
| 35 | if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ARCHIVE}) | ||
| 36 | set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip") | ||
| 37 | |||
| 38 | message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...") | ||
| 39 | file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE} | ||
| 40 | STATUS NX_TZDB_DOWNLOAD_STATUS) | ||
| 41 | list(GET NX_TZDB_DOWNLOAD_STATUS 0 NX_TZDB_DOWNLOAD_STATUS_CODE) | ||
| 42 | if (NOT NX_TZDB_DOWNLOAD_STATUS_CODE EQUAL 0) | ||
| 43 | message(FATAL_ERROR "Time zone data download failed (status code ${NX_TZDB_DOWNLOAD_STATUS_CODE})") | ||
| 44 | endif() | ||
| 11 | 45 | ||
| 12 | if (NOT EXISTS ${NX_TZDB_ARCHIVE}) | ||
| 13 | file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE}) | ||
| 14 | file(ARCHIVE_EXTRACT | 46 | file(ARCHIVE_EXTRACT |
| 15 | INPUT | 47 | INPUT |
| 16 | ${NX_TZDB_ARCHIVE} | 48 | ${NX_TZDB_ARCHIVE} |
| 17 | DESTINATION | 49 | DESTINATION |
| 18 | ${NX_TZDB_DIR}) | 50 | ${NX_TZDB_ROMFS_DIR}) |
| 51 | elseif (CAN_BUILD_NX_TZDB AND NOT YUZU_DOWNLOAD_TIME_ZONE_DATA) | ||
| 52 | add_subdirectory(tzdb_to_nx) | ||
| 53 | add_dependencies(nx_tzdb x80e) | ||
| 54 | |||
| 55 | set(NX_TZDB_ROMFS_DIR "${NX_TZDB_DIR}") | ||
| 19 | endif() | 56 | endif() |
| 20 | 57 | ||
| 21 | add_library(nx_tzdb INTERFACE) | ||
| 22 | target_include_directories(nx_tzdb | 58 | target_include_directories(nx_tzdb |
| 23 | INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include | 59 | INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include |
| 24 | INTERFACE ${NX_TZDB_INCLUDE_DIR}) | 60 | INTERFACE ${NX_TZDB_INCLUDE_DIR}) |
| @@ -41,25 +77,25 @@ function(CreateHeader ZONE_PATH HEADER_NAME) | |||
| 41 | target_sources(nx_tzdb PRIVATE ${HEADER_PATH}) | 77 | target_sources(nx_tzdb PRIVATE ${HEADER_PATH}) |
| 42 | endfunction() | 78 | endfunction() |
| 43 | 79 | ||
| 44 | CreateHeader(${NX_TZDB_DIR} base) | 80 | CreateHeader(${NX_TZDB_ROMFS_DIR} base) |
| 45 | CreateHeader(${NX_TZDB_DIR}/zoneinfo zoneinfo) | 81 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo zoneinfo) |
| 46 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Africa africa) | 82 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Africa africa) |
| 47 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/America america) | 83 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America america) |
| 48 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/Argentina america_argentina) | 84 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Argentina america_argentina) |
| 49 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/Indiana america_indiana) | 85 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Indiana america_indiana) |
| 50 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/Kentucky america_kentucky) | 86 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Kentucky america_kentucky) |
| 51 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/North_Dakota america_north_dakota) | 87 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/North_Dakota america_north_dakota) |
| 52 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Antartica antartica) | 88 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Antarctica antarctica) |
| 53 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Arctic arctic) | 89 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Arctic arctic) |
| 54 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Asia asia) | 90 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Asia asia) |
| 55 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Atlantic atlantic) | 91 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Atlantic atlantic) |
| 56 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Australia australia) | 92 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Australia australia) |
| 57 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Brazil brazil) | 93 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Brazil brazil) |
| 58 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Canada canada) | 94 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Canada canada) |
| 59 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Chile chile) | 95 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Chile chile) |
| 60 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Etc etc) | 96 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Etc etc) |
| 61 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Europe europe) | 97 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Europe europe) |
| 62 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Indian indian) | 98 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Indian indian) |
| 63 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Mexico mexico) | 99 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Mexico mexico) |
| 64 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/Pacific pacific) | 100 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Pacific pacific) |
| 65 | CreateHeader(${NX_TZDB_DIR}/zoneinfo/US us) | 101 | CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/US us) |
diff --git a/externals/nx_tzdb/NxTzdbCreateHeader.cmake b/externals/nx_tzdb/NxTzdbCreateHeader.cmake index 69166aa5b..8c29e1167 100644 --- a/externals/nx_tzdb/NxTzdbCreateHeader.cmake +++ b/externals/nx_tzdb/NxTzdbCreateHeader.cmake | |||
| @@ -15,7 +15,7 @@ set(DIRECTORY_NAME ${HEADER_NAME}) | |||
| 15 | 15 | ||
| 16 | set(FILE_DATA "") | 16 | set(FILE_DATA "") |
| 17 | foreach(ZONE_FILE ${FILE_LIST}) | 17 | foreach(ZONE_FILE ${FILE_LIST}) |
| 18 | if ("${ZONE_FILE}" STREQUAL "\n") | 18 | if (ZONE_FILE STREQUAL "\n") |
| 19 | continue() | 19 | continue() |
| 20 | endif() | 20 | endif() |
| 21 | 21 | ||
| @@ -26,13 +26,13 @@ foreach(ZONE_FILE ${FILE_LIST}) | |||
| 26 | foreach(I RANGE 0 ${ZONE_DATA_LEN} 2) | 26 | foreach(I RANGE 0 ${ZONE_DATA_LEN} 2) |
| 27 | math(EXPR BREAK_LINE "(${I} + 2) % 38") | 27 | math(EXPR BREAK_LINE "(${I} + 2) % 38") |
| 28 | 28 | ||
| 29 | string(SUBSTRING "${ZONE_DATA}" "${I}" "2" HEX_DATA) | 29 | string(SUBSTRING "${ZONE_DATA}" "${I}" 2 HEX_DATA) |
| 30 | if ("${HEX_DATA}" STREQUAL "") | 30 | if (NOT HEX_DATA) |
| 31 | break() | 31 | break() |
| 32 | endif() | 32 | endif() |
| 33 | 33 | ||
| 34 | string(APPEND FILE_DATA "0x${HEX_DATA},") | 34 | string(APPEND FILE_DATA "0x${HEX_DATA},") |
| 35 | if ("${BREAK_LINE}" STREQUAL "0") | 35 | if (BREAK_LINE EQUAL 0) |
| 36 | string(APPEND FILE_DATA "\n") | 36 | string(APPEND FILE_DATA "\n") |
| 37 | else() | 37 | else() |
| 38 | string(APPEND FILE_DATA " ") | 38 | string(APPEND FILE_DATA " ") |
diff --git a/externals/nx_tzdb/include/nx_tzdb.h b/externals/nx_tzdb/include/nx_tzdb.h index d7b1e4304..1f7c6069a 100644 --- a/externals/nx_tzdb/include/nx_tzdb.h +++ b/externals/nx_tzdb/include/nx_tzdb.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "nx_tzdb/america_indiana.h" | 9 | #include "nx_tzdb/america_indiana.h" |
| 10 | #include "nx_tzdb/america_kentucky.h" | 10 | #include "nx_tzdb/america_kentucky.h" |
| 11 | #include "nx_tzdb/america_north_dakota.h" | 11 | #include "nx_tzdb/america_north_dakota.h" |
| 12 | #include "nx_tzdb/antartica.h" | 12 | #include "nx_tzdb/antarctica.h" |
| 13 | #include "nx_tzdb/arctic.h" | 13 | #include "nx_tzdb/arctic.h" |
| 14 | #include "nx_tzdb/asia.h" | 14 | #include "nx_tzdb/asia.h" |
| 15 | #include "nx_tzdb/atlantic.h" | 15 | #include "nx_tzdb/atlantic.h" |
diff --git a/externals/nx_tzdb/tzdb_to_nx b/externals/nx_tzdb/tzdb_to_nx new file mode 160000 | |||
| Subproject 34df65eff295c2bd9ee9e6a077d662486d5cabb | |||
diff --git a/src/core/file_sys/system_archive/time_zone_binary.cpp b/src/core/file_sys/system_archive/time_zone_binary.cpp index ceb0b41c6..7c17bbefa 100644 --- a/src/core/file_sys/system_archive/time_zone_binary.cpp +++ b/src/core/file_sys/system_archive/time_zone_binary.cpp | |||
| @@ -15,7 +15,7 @@ namespace FileSys::SystemArchive { | |||
| 15 | const static std::map<std::string, const std::map<const char*, const std::vector<u8>>&> | 15 | const static std::map<std::string, const std::map<const char*, const std::vector<u8>>&> |
| 16 | tzdb_zoneinfo_dirs = {{"Africa", NxTzdb::africa}, | 16 | tzdb_zoneinfo_dirs = {{"Africa", NxTzdb::africa}, |
| 17 | {"America", NxTzdb::america}, | 17 | {"America", NxTzdb::america}, |
| 18 | {"Antartica", NxTzdb::antartica}, | 18 | {"Antarctica", NxTzdb::antarctica}, |
| 19 | {"Arctic", NxTzdb::arctic}, | 19 | {"Arctic", NxTzdb::arctic}, |
| 20 | {"Asia", NxTzdb::asia}, | 20 | {"Asia", NxTzdb::asia}, |
| 21 | {"Atlantic", NxTzdb::atlantic}, | 21 | {"Atlantic", NxTzdb::atlantic}, |
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index e1728c06d..63aacd19f 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp | |||
| @@ -849,8 +849,9 @@ static Result CreateCalendarTime(s64 time, int gmt_offset, CalendarTimeInternal& | |||
| 849 | static Result ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, | 849 | static Result ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, |
| 850 | CalendarTimeInternal& calendar_time, | 850 | CalendarTimeInternal& calendar_time, |
| 851 | CalendarAdditionalInfo& calendar_additional_info) { | 851 | CalendarAdditionalInfo& calendar_additional_info) { |
| 852 | if ((rules.go_ahead && time < rules.ats[0]) || | 852 | ASSERT(rules.go_ahead ? rules.time_count > 0 : true); |
| 853 | (rules.go_back && time > rules.ats[rules.time_count - 1])) { | 853 | if ((rules.go_back && time < rules.ats[0]) || |
| 854 | (rules.go_ahead && time > rules.ats[rules.time_count - 1])) { | ||
| 854 | s64 seconds{}; | 855 | s64 seconds{}; |
| 855 | if (time < rules.ats[0]) { | 856 | if (time < rules.ats[0]) { |
| 856 | seconds = rules.ats[0] - time; | 857 | seconds = rules.ats[0] - time; |
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp index e8273e152..8171c82a5 100644 --- a/src/core/hle/service/time/time_zone_service.cpp +++ b/src/core/hle/service/time/time_zone_service.cpp | |||
| @@ -112,20 +112,14 @@ void ITimeZoneService::LoadTimeZoneRule(HLERequestContext& ctx) { | |||
| 112 | LOG_DEBUG(Service_Time, "called, location_name={}", location_name); | 112 | LOG_DEBUG(Service_Time, "called, location_name={}", location_name); |
| 113 | 113 | ||
| 114 | TimeZone::TimeZoneRule time_zone_rule{}; | 114 | TimeZone::TimeZoneRule time_zone_rule{}; |
| 115 | if (const Result result{ | 115 | const Result result{time_zone_content_manager.LoadTimeZoneRule(time_zone_rule, location_name)}; |
| 116 | time_zone_content_manager.LoadTimeZoneRule(time_zone_rule, location_name)}; | ||
| 117 | result != ResultSuccess) { | ||
| 118 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 119 | rb.Push(result); | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | 116 | ||
| 123 | std::vector<u8> time_zone_rule_outbuffer(sizeof(TimeZone::TimeZoneRule)); | 117 | std::vector<u8> time_zone_rule_outbuffer(sizeof(TimeZone::TimeZoneRule)); |
| 124 | std::memcpy(time_zone_rule_outbuffer.data(), &time_zone_rule, sizeof(TimeZone::TimeZoneRule)); | 118 | std::memcpy(time_zone_rule_outbuffer.data(), &time_zone_rule, sizeof(TimeZone::TimeZoneRule)); |
| 125 | ctx.WriteBuffer(time_zone_rule_outbuffer); | 119 | ctx.WriteBuffer(time_zone_rule_outbuffer); |
| 126 | 120 | ||
| 127 | IPC::ResponseBuilder rb{ctx, 2}; | 121 | IPC::ResponseBuilder rb{ctx, 2}; |
| 128 | rb.Push(ResultSuccess); | 122 | rb.Push(result); |
| 129 | } | 123 | } |
| 130 | 124 | ||
| 131 | void ITimeZoneService::ToCalendarTime(HLERequestContext& ctx) { | 125 | void ITimeZoneService::ToCalendarTime(HLERequestContext& ctx) { |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 9bafd8cc0..45977d578 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -719,9 +719,15 @@ void BufferCache<P>::BindHostVertexBuffers() { | |||
| 719 | bool any_valid{false}; | 719 | bool any_valid{false}; |
| 720 | auto& flags = maxwell3d->dirty.flags; | 720 | auto& flags = maxwell3d->dirty.flags; |
| 721 | for (u32 index = 0; index < NUM_VERTEX_BUFFERS; ++index) { | 721 | for (u32 index = 0; index < NUM_VERTEX_BUFFERS; ++index) { |
| 722 | const Binding& binding = channel_state->vertex_buffers[index]; | ||
| 723 | Buffer& buffer = slot_buffers[binding.buffer_id]; | ||
| 724 | TouchBuffer(buffer, binding.buffer_id); | ||
| 725 | SynchronizeBuffer(buffer, binding.cpu_addr, binding.size); | ||
| 722 | if (!flags[Dirty::VertexBuffer0 + index]) { | 726 | if (!flags[Dirty::VertexBuffer0 + index]) { |
| 723 | continue; | 727 | continue; |
| 724 | } | 728 | } |
| 729 | flags[Dirty::VertexBuffer0 + index] = false; | ||
| 730 | |||
| 725 | host_bindings.min_index = std::min(host_bindings.min_index, index); | 731 | host_bindings.min_index = std::min(host_bindings.min_index, index); |
| 726 | host_bindings.max_index = std::max(host_bindings.max_index, index); | 732 | host_bindings.max_index = std::max(host_bindings.max_index, index); |
| 727 | any_valid = true; | 733 | any_valid = true; |
| @@ -735,9 +741,6 @@ void BufferCache<P>::BindHostVertexBuffers() { | |||
| 735 | const Binding& binding = channel_state->vertex_buffers[index]; | 741 | const Binding& binding = channel_state->vertex_buffers[index]; |
| 736 | Buffer& buffer = slot_buffers[binding.buffer_id]; | 742 | Buffer& buffer = slot_buffers[binding.buffer_id]; |
| 737 | 743 | ||
| 738 | TouchBuffer(buffer, binding.buffer_id); | ||
| 739 | SynchronizeBuffer(buffer, binding.cpu_addr, binding.size); | ||
| 740 | |||
| 741 | const u32 stride = maxwell3d->regs.vertex_streams[index].stride; | 744 | const u32 stride = maxwell3d->regs.vertex_streams[index].stride; |
| 742 | const u32 offset = buffer.Offset(binding.cpu_addr); | 745 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 743 | 746 | ||
diff --git a/src/video_core/engines/draw_manager.cpp b/src/video_core/engines/draw_manager.cpp index 0e94c521a..f34090791 100644 --- a/src/video_core/engines/draw_manager.cpp +++ b/src/video_core/engines/draw_manager.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/settings.h" | ||
| 4 | #include "video_core/dirty_flags.h" | 5 | #include "video_core/dirty_flags.h" |
| 5 | #include "video_core/engines/draw_manager.h" | 6 | #include "video_core/engines/draw_manager.h" |
| 6 | #include "video_core/rasterizer_interface.h" | 7 | #include "video_core/rasterizer_interface.h" |
| @@ -195,8 +196,12 @@ void DrawManager::DrawTexture() { | |||
| 195 | if (lower_left) { | 196 | if (lower_left) { |
| 196 | draw_texture_state.dst_y0 -= dst_height; | 197 | draw_texture_state.dst_y0 -= dst_height; |
| 197 | } | 198 | } |
| 198 | draw_texture_state.dst_x1 = draw_texture_state.dst_x0 + dst_width; | 199 | draw_texture_state.dst_x1 = |
| 199 | draw_texture_state.dst_y1 = draw_texture_state.dst_y0 + dst_height; | 200 | draw_texture_state.dst_x0 + |
| 201 | static_cast<f32>(Settings::values.resolution_info.ScaleUp(static_cast<u32>(dst_width))); | ||
| 202 | draw_texture_state.dst_y1 = | ||
| 203 | draw_texture_state.dst_y0 + | ||
| 204 | static_cast<f32>(Settings::values.resolution_info.ScaleUp(static_cast<u32>(dst_height))); | ||
| 200 | draw_texture_state.src_x0 = static_cast<float>(regs.draw_texture.src_x0) / 4096.f; | 205 | draw_texture_state.src_x0 = static_cast<float>(regs.draw_texture.src_x0) / 4096.f; |
| 201 | draw_texture_state.src_y0 = static_cast<float>(regs.draw_texture.src_y0) / 4096.f; | 206 | draw_texture_state.src_y0 = static_cast<float>(regs.draw_texture.src_y0) / 4096.f; |
| 202 | draw_texture_state.src_x1 = | 207 | draw_texture_state.src_x1 = |
| @@ -207,7 +212,6 @@ void DrawManager::DrawTexture() { | |||
| 207 | draw_texture_state.src_y0; | 212 | draw_texture_state.src_y0; |
| 208 | draw_texture_state.src_sampler = regs.draw_texture.src_sampler; | 213 | draw_texture_state.src_sampler = regs.draw_texture.src_sampler; |
| 209 | draw_texture_state.src_texture = regs.draw_texture.src_texture; | 214 | draw_texture_state.src_texture = regs.draw_texture.src_texture; |
| 210 | |||
| 211 | maxwell3d->rasterizer->DrawTexture(); | 215 | maxwell3d->rasterizer->DrawTexture(); |
| 212 | } | 216 | } |
| 213 | 217 | ||
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 8c33722d3..e30fcb1ed 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -516,15 +516,15 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bi | |||
| 516 | buffer_handles.push_back(handle); | 516 | buffer_handles.push_back(handle); |
| 517 | } | 517 | } |
| 518 | if (device.IsExtExtendedDynamicStateSupported()) { | 518 | if (device.IsExtExtendedDynamicStateSupported()) { |
| 519 | scheduler.Record([bindings = bindings, | 519 | scheduler.Record([bindings = std::move(bindings), |
| 520 | buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { | 520 | buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { |
| 521 | cmdbuf.BindVertexBuffers2EXT( | 521 | cmdbuf.BindVertexBuffers2EXT( |
| 522 | bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(), | 522 | bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(), |
| 523 | bindings.offsets.data(), bindings.sizes.data(), bindings.strides.data()); | 523 | bindings.offsets.data(), bindings.sizes.data(), bindings.strides.data()); |
| 524 | }); | 524 | }); |
| 525 | } else { | 525 | } else { |
| 526 | scheduler.Record([bindings = bindings, | 526 | scheduler.Record([bindings = std::move(bindings), |
| 527 | buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { | 527 | buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { |
| 528 | cmdbuf.BindVertexBuffers(bindings.min_index, bindings.max_index - bindings.min_index, | 528 | cmdbuf.BindVertexBuffers(bindings.min_index, bindings.max_index - bindings.min_index, |
| 529 | buffer_handles.data(), bindings.offsets.data()); | 529 | buffer_handles.data(), bindings.offsets.data()); |
| 530 | }); | 530 | }); |
| @@ -561,12 +561,12 @@ void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings< | |||
| 561 | for (u32 index = 0; index < bindings.buffers.size(); ++index) { | 561 | for (u32 index = 0; index < bindings.buffers.size(); ++index) { |
| 562 | buffer_handles.push_back(bindings.buffers[index]->Handle()); | 562 | buffer_handles.push_back(bindings.buffers[index]->Handle()); |
| 563 | } | 563 | } |
| 564 | scheduler.Record( | 564 | scheduler.Record([bindings = std::move(bindings), |
| 565 | [bindings = bindings, buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { | 565 | buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { |
| 566 | cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles.size()), | 566 | cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles.size()), |
| 567 | buffer_handles.data(), bindings.offsets.data(), | 567 | buffer_handles.data(), bindings.offsets.data(), |
| 568 | bindings.sizes.data()); | 568 | bindings.sizes.data()); |
| 569 | }); | 569 | }); |
| 570 | } | 570 | } |
| 571 | 571 | ||
| 572 | void BufferCacheRuntime::ReserveNullBuffer() { | 572 | void BufferCacheRuntime::ReserveNullBuffer() { |
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp index b128c4f6e..5eeda08d2 100644 --- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp +++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <thread> | 4 | #include <thread> |
| 5 | 5 | ||
| 6 | #include "common/polyfill_ranges.h" | ||
| 6 | #include "common/settings.h" | 7 | #include "common/settings.h" |
| 7 | #include "video_core/renderer_vulkan/vk_master_semaphore.h" | 8 | #include "video_core/renderer_vulkan/vk_master_semaphore.h" |
| 8 | #include "video_core/vulkan_common/vulkan_device.h" | 9 | #include "video_core/vulkan_common/vulkan_device.h" |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 3d2e9a16a..dcedf4425 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -783,9 +783,6 @@ bool Device::GetSuitability(bool requires_swapchain) { | |||
| 783 | 783 | ||
| 784 | FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION); | 784 | FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION); |
| 785 | FOR_EACH_VK_EXTENSION(EXTENSION); | 785 | FOR_EACH_VK_EXTENSION(EXTENSION); |
| 786 | #ifdef _WIN32 | ||
| 787 | FOR_EACH_VK_EXTENSION_WIN32(EXTENSION); | ||
| 788 | #endif | ||
| 789 | 786 | ||
| 790 | #undef FEATURE_EXTENSION | 787 | #undef FEATURE_EXTENSION |
| 791 | #undef EXTENSION | 788 | #undef EXTENSION |
| @@ -804,11 +801,6 @@ bool Device::GetSuitability(bool requires_swapchain) { | |||
| 804 | 801 | ||
| 805 | FOR_EACH_VK_RECOMMENDED_EXTENSION(LOG_EXTENSION); | 802 | FOR_EACH_VK_RECOMMENDED_EXTENSION(LOG_EXTENSION); |
| 806 | FOR_EACH_VK_MANDATORY_EXTENSION(CHECK_EXTENSION); | 803 | FOR_EACH_VK_MANDATORY_EXTENSION(CHECK_EXTENSION); |
| 807 | #ifdef _WIN32 | ||
| 808 | FOR_EACH_VK_MANDATORY_EXTENSION_WIN32(CHECK_EXTENSION); | ||
| 809 | #else | ||
| 810 | FOR_EACH_VK_MANDATORY_EXTENSION_GENERIC(CHECK_EXTENSION); | ||
| 811 | #endif | ||
| 812 | 804 | ||
| 813 | if (requires_swapchain) { | 805 | if (requires_swapchain) { |
| 814 | CHECK_EXTENSION(VK_KHR_SWAPCHAIN_EXTENSION_NAME); | 806 | CHECK_EXTENSION(VK_KHR_SWAPCHAIN_EXTENSION_NAME); |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index f314d0ffe..8c7e44fcb 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -68,7 +68,6 @@ | |||
| 68 | EXTENSION(EXT, VERTEX_ATTRIBUTE_DIVISOR, vertex_attribute_divisor) \ | 68 | EXTENSION(EXT, VERTEX_ATTRIBUTE_DIVISOR, vertex_attribute_divisor) \ |
| 69 | EXTENSION(KHR, DRAW_INDIRECT_COUNT, draw_indirect_count) \ | 69 | EXTENSION(KHR, DRAW_INDIRECT_COUNT, draw_indirect_count) \ |
| 70 | EXTENSION(KHR, DRIVER_PROPERTIES, driver_properties) \ | 70 | EXTENSION(KHR, DRIVER_PROPERTIES, driver_properties) \ |
| 71 | EXTENSION(KHR, EXTERNAL_MEMORY_FD, external_memory_fd) \ | ||
| 72 | EXTENSION(KHR, PUSH_DESCRIPTOR, push_descriptor) \ | 71 | EXTENSION(KHR, PUSH_DESCRIPTOR, push_descriptor) \ |
| 73 | EXTENSION(KHR, SAMPLER_MIRROR_CLAMP_TO_EDGE, sampler_mirror_clamp_to_edge) \ | 72 | EXTENSION(KHR, SAMPLER_MIRROR_CLAMP_TO_EDGE, sampler_mirror_clamp_to_edge) \ |
| 74 | EXTENSION(KHR, SHADER_FLOAT_CONTROLS, shader_float_controls) \ | 73 | EXTENSION(KHR, SHADER_FLOAT_CONTROLS, shader_float_controls) \ |
| @@ -80,9 +79,6 @@ | |||
| 80 | EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \ | 79 | EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \ |
| 81 | EXTENSION(NV, VIEWPORT_SWIZZLE, viewport_swizzle) | 80 | EXTENSION(NV, VIEWPORT_SWIZZLE, viewport_swizzle) |
| 82 | 81 | ||
| 83 | #define FOR_EACH_VK_EXTENSION_WIN32(EXTENSION) \ | ||
| 84 | EXTENSION(KHR, EXTERNAL_MEMORY_WIN32, external_memory_win32) | ||
| 85 | |||
| 86 | // Define extensions which must be supported. | 82 | // Define extensions which must be supported. |
| 87 | #define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \ | 83 | #define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \ |
| 88 | EXTENSION_NAME(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) \ | 84 | EXTENSION_NAME(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) \ |
| @@ -90,12 +86,6 @@ | |||
| 90 | EXTENSION_NAME(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME) \ | 86 | EXTENSION_NAME(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME) \ |
| 91 | EXTENSION_NAME(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME) | 87 | EXTENSION_NAME(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME) |
| 92 | 88 | ||
| 93 | #define FOR_EACH_VK_MANDATORY_EXTENSION_GENERIC(EXTENSION_NAME) \ | ||
| 94 | EXTENSION_NAME(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME) | ||
| 95 | |||
| 96 | #define FOR_EACH_VK_MANDATORY_EXTENSION_WIN32(EXTENSION_NAME) \ | ||
| 97 | EXTENSION_NAME(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME) | ||
| 98 | |||
| 99 | // Define extensions where the absence of the extension may result in a degraded experience. | 89 | // Define extensions where the absence of the extension may result in a degraded experience. |
| 100 | #define FOR_EACH_VK_RECOMMENDED_EXTENSION(EXTENSION_NAME) \ | 90 | #define FOR_EACH_VK_RECOMMENDED_EXTENSION(EXTENSION_NAME) \ |
| 101 | EXTENSION_NAME(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME) \ | 91 | EXTENSION_NAME(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME) \ |
| @@ -636,7 +626,6 @@ private: | |||
| 636 | FOR_EACH_VK_FEATURE_1_3(FEATURE); | 626 | FOR_EACH_VK_FEATURE_1_3(FEATURE); |
| 637 | FOR_EACH_VK_FEATURE_EXT(FEATURE); | 627 | FOR_EACH_VK_FEATURE_EXT(FEATURE); |
| 638 | FOR_EACH_VK_EXTENSION(EXTENSION); | 628 | FOR_EACH_VK_EXTENSION(EXTENSION); |
| 639 | FOR_EACH_VK_EXTENSION_WIN32(EXTENSION); | ||
| 640 | 629 | ||
| 641 | #undef EXTENSION | 630 | #undef EXTENSION |
| 642 | #undef FEATURE | 631 | #undef FEATURE |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 84d9ca796..733c296e4 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -210,6 +210,8 @@ add_executable(yuzu | |||
| 210 | util/url_request_interceptor.h | 210 | util/url_request_interceptor.h |
| 211 | util/util.cpp | 211 | util/util.cpp |
| 212 | util/util.h | 212 | util/util.h |
| 213 | vk_device_info.cpp | ||
| 214 | vk_device_info.h | ||
| 213 | compatdb.cpp | 215 | compatdb.cpp |
| 214 | compatdb.h | 216 | compatdb.h |
| 215 | yuzu.qrc | 217 | yuzu.qrc |
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 8e76a819a..bdf83ebfe 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "common/settings.h" | 6 | #include "common/settings.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "ui_configure.h" | 8 | #include "ui_configure.h" |
| 9 | #include "vk_device_info.h" | ||
| 9 | #include "yuzu/configuration/config.h" | 10 | #include "yuzu/configuration/config.h" |
| 10 | #include "yuzu/configuration/configure_audio.h" | 11 | #include "yuzu/configuration/configure_audio.h" |
| 11 | #include "yuzu/configuration/configure_cpu.h" | 12 | #include "yuzu/configuration/configure_cpu.h" |
| @@ -28,6 +29,7 @@ | |||
| 28 | 29 | ||
| 29 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, | 30 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, |
| 30 | InputCommon::InputSubsystem* input_subsystem, | 31 | InputCommon::InputSubsystem* input_subsystem, |
| 32 | std::vector<VkDeviceInfo::Record>& vk_device_records, | ||
| 31 | Core::System& system_, bool enable_web_config) | 33 | Core::System& system_, bool enable_web_config) |
| 32 | : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, | 34 | : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, |
| 33 | registry(registry_), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, | 35 | registry(registry_), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, |
| @@ -38,7 +40,8 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, | |||
| 38 | general_tab{std::make_unique<ConfigureGeneral>(system_, this)}, | 40 | general_tab{std::make_unique<ConfigureGeneral>(system_, this)}, |
| 39 | graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, this)}, | 41 | graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, this)}, |
| 40 | graphics_tab{std::make_unique<ConfigureGraphics>( | 42 | graphics_tab{std::make_unique<ConfigureGraphics>( |
| 41 | system_, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this)}, | 43 | system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, |
| 44 | this)}, | ||
| 42 | hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)}, | 45 | hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)}, |
| 43 | input_tab{std::make_unique<ConfigureInput>(system_, this)}, | 46 | input_tab{std::make_unique<ConfigureInput>(system_, this)}, |
| 44 | network_tab{std::make_unique<ConfigureNetwork>(system_, this)}, | 47 | network_tab{std::make_unique<ConfigureNetwork>(system_, this)}, |
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index a086a07c4..2a08b7fee 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h | |||
| @@ -4,7 +4,9 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <vector> | ||
| 7 | #include <QDialog> | 8 | #include <QDialog> |
| 9 | #include "yuzu/vk_device_info.h" | ||
| 8 | 10 | ||
| 9 | namespace Core { | 11 | namespace Core { |
| 10 | class System; | 12 | class System; |
| @@ -40,8 +42,9 @@ class ConfigureDialog : public QDialog { | |||
| 40 | 42 | ||
| 41 | public: | 43 | public: |
| 42 | explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, | 44 | explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, |
| 43 | InputCommon::InputSubsystem* input_subsystem, Core::System& system_, | 45 | InputCommon::InputSubsystem* input_subsystem, |
| 44 | bool enable_web_config = true); | 46 | std::vector<VkDeviceInfo::Record>& vk_device_records, |
| 47 | Core::System& system_, bool enable_web_config = true); | ||
| 45 | ~ConfigureDialog() override; | 48 | ~ConfigureDialog() override; |
| 46 | 49 | ||
| 47 | void ApplyConfiguration(); | 50 | void ApplyConfiguration(); |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 431585216..78b487494 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -1,10 +1,6 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2016 Citra Emulator Project | 1 | // SPDX-FileCopyrightText: 2016 Citra Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | // Include this early to include Vulkan headers how we want to | ||
| 5 | #include "video_core/vulkan_common/vulkan_device.h" | ||
| 6 | #include "video_core/vulkan_common/vulkan_wrapper.h" | ||
| 7 | |||
| 8 | #include <algorithm> | 4 | #include <algorithm> |
| 9 | #include <functional> | 5 | #include <functional> |
| 10 | #include <iosfwd> | 6 | #include <iosfwd> |
| @@ -34,13 +30,11 @@ | |||
| 34 | #include "common/settings.h" | 30 | #include "common/settings.h" |
| 35 | #include "core/core.h" | 31 | #include "core/core.h" |
| 36 | #include "ui_configure_graphics.h" | 32 | #include "ui_configure_graphics.h" |
| 37 | #include "video_core/vulkan_common/vulkan_instance.h" | ||
| 38 | #include "video_core/vulkan_common/vulkan_library.h" | ||
| 39 | #include "video_core/vulkan_common/vulkan_surface.h" | ||
| 40 | #include "yuzu/configuration/configuration_shared.h" | 33 | #include "yuzu/configuration/configuration_shared.h" |
| 41 | #include "yuzu/configuration/configure_graphics.h" | 34 | #include "yuzu/configuration/configure_graphics.h" |
| 42 | #include "yuzu/qt_common.h" | 35 | #include "yuzu/qt_common.h" |
| 43 | #include "yuzu/uisettings.h" | 36 | #include "yuzu/uisettings.h" |
| 37 | #include "yuzu/vk_device_info.h" | ||
| 44 | 38 | ||
| 45 | static const std::vector<VkPresentModeKHR> default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR, | 39 | static const std::vector<VkPresentModeKHR> default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR, |
| 46 | VK_PRESENT_MODE_FIFO_KHR}; | 40 | VK_PRESENT_MODE_FIFO_KHR}; |
| @@ -77,9 +71,10 @@ static constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode) | |||
| 77 | } | 71 | } |
| 78 | 72 | ||
| 79 | ConfigureGraphics::ConfigureGraphics(const Core::System& system_, | 73 | ConfigureGraphics::ConfigureGraphics(const Core::System& system_, |
| 74 | std::vector<VkDeviceInfo::Record>& records_, | ||
| 80 | const std::function<void()>& expose_compute_option_, | 75 | const std::function<void()>& expose_compute_option_, |
| 81 | QWidget* parent) | 76 | QWidget* parent) |
| 82 | : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, | 77 | : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, records{records_}, |
| 83 | expose_compute_option{expose_compute_option_}, system{system_} { | 78 | expose_compute_option{expose_compute_option_}, system{system_} { |
| 84 | vulkan_device = Settings::values.vulkan_device.GetValue(); | 79 | vulkan_device = Settings::values.vulkan_device.GetValue(); |
| 85 | RetrieveVulkanDevices(); | 80 | RetrieveVulkanDevices(); |
| @@ -504,47 +499,19 @@ void ConfigureGraphics::UpdateAPILayout() { | |||
| 504 | } | 499 | } |
| 505 | } | 500 | } |
| 506 | 501 | ||
| 507 | void ConfigureGraphics::RetrieveVulkanDevices() try { | 502 | void ConfigureGraphics::RetrieveVulkanDevices() { |
| 508 | if (UISettings::values.has_broken_vulkan) { | ||
| 509 | return; | ||
| 510 | } | ||
| 511 | |||
| 512 | using namespace Vulkan; | ||
| 513 | |||
| 514 | auto* window = this->window()->windowHandle(); | ||
| 515 | auto wsi = QtCommon::GetWindowSystemInfo(window); | ||
| 516 | |||
| 517 | vk::InstanceDispatch dld; | ||
| 518 | const auto library = OpenLibrary(); | ||
| 519 | const vk::Instance instance = CreateInstance(*library, dld, VK_API_VERSION_1_1, wsi.type); | ||
| 520 | const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); | ||
| 521 | vk::SurfaceKHR surface = CreateSurface(instance, wsi); | ||
| 522 | |||
| 523 | vulkan_devices.clear(); | 503 | vulkan_devices.clear(); |
| 524 | vulkan_devices.reserve(physical_devices.size()); | 504 | vulkan_devices.reserve(records.size()); |
| 525 | device_present_modes.clear(); | 505 | device_present_modes.clear(); |
| 526 | device_present_modes.reserve(physical_devices.size()); | 506 | device_present_modes.reserve(records.size()); |
| 527 | for (const VkPhysicalDevice device : physical_devices) { | 507 | for (const auto& record : records) { |
| 528 | const auto physical_device = vk::PhysicalDevice(device, dld); | 508 | vulkan_devices.push_back(QString::fromStdString(record.name)); |
| 529 | const std::string name = physical_device.GetProperties().deviceName; | 509 | device_present_modes.push_back(record.vsync_support); |
| 530 | const std::vector<VkPresentModeKHR> present_modes = | 510 | |
| 531 | physical_device.GetSurfacePresentModesKHR(*surface); | 511 | if (record.is_intel_proprietary) { |
| 532 | vulkan_devices.push_back(QString::fromStdString(name)); | ||
| 533 | device_present_modes.push_back(present_modes); | ||
| 534 | |||
| 535 | VkPhysicalDeviceDriverProperties driver_properties{}; | ||
| 536 | driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; | ||
| 537 | driver_properties.pNext = nullptr; | ||
| 538 | VkPhysicalDeviceProperties2 properties{}; | ||
| 539 | properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; | ||
| 540 | properties.pNext = &driver_properties; | ||
| 541 | dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); | ||
| 542 | if (driver_properties.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { | ||
| 543 | expose_compute_option(); | 512 | expose_compute_option(); |
| 544 | } | 513 | } |
| 545 | } | 514 | } |
| 546 | } catch (const Vulkan::vk::Exception& exception) { | ||
| 547 | LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); | ||
| 548 | } | 515 | } |
| 549 | 516 | ||
| 550 | Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { | 517 | Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { |
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 364b1cac2..be9310b74 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <qobjectdefs.h> | 12 | #include <qobjectdefs.h> |
| 13 | #include <vulkan/vulkan_core.h> | 13 | #include <vulkan/vulkan_core.h> |
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "vk_device_info.h" | ||
| 15 | 16 | ||
| 16 | class QEvent; | 17 | class QEvent; |
| 17 | class QObject; | 18 | class QObject; |
| @@ -39,6 +40,7 @@ class ConfigureGraphics : public QWidget { | |||
| 39 | 40 | ||
| 40 | public: | 41 | public: |
| 41 | explicit ConfigureGraphics(const Core::System& system_, | 42 | explicit ConfigureGraphics(const Core::System& system_, |
| 43 | std::vector<VkDeviceInfo::Record>& records, | ||
| 42 | const std::function<void()>& expose_compute_option_, | 44 | const std::function<void()>& expose_compute_option_, |
| 43 | QWidget* parent = nullptr); | 45 | QWidget* parent = nullptr); |
| 44 | ~ConfigureGraphics() override; | 46 | ~ConfigureGraphics() override; |
| @@ -77,6 +79,7 @@ private: | |||
| 77 | ConfigurationShared::CheckState use_disk_shader_cache; | 79 | ConfigurationShared::CheckState use_disk_shader_cache; |
| 78 | ConfigurationShared::CheckState use_asynchronous_gpu_emulation; | 80 | ConfigurationShared::CheckState use_asynchronous_gpu_emulation; |
| 79 | 81 | ||
| 82 | std::vector<VkDeviceInfo::Record>& records; | ||
| 80 | std::vector<QString> vulkan_devices; | 83 | std::vector<QString> vulkan_devices; |
| 81 | std::vector<std::vector<VkPresentModeKHR>> device_present_modes; | 84 | std::vector<std::vector<VkPresentModeKHR>> device_present_modes; |
| 82 | std::vector<VkPresentModeKHR> | 85 | std::vector<VkPresentModeKHR> |
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 7ac162586..eb96e6068 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <utility> | 8 | #include <utility> |
| 9 | #include <vector> | ||
| 9 | 10 | ||
| 10 | #include <fmt/format.h> | 11 | #include <fmt/format.h> |
| 11 | 12 | ||
| @@ -34,8 +35,10 @@ | |||
| 34 | #include "yuzu/configuration/configure_system.h" | 35 | #include "yuzu/configuration/configure_system.h" |
| 35 | #include "yuzu/uisettings.h" | 36 | #include "yuzu/uisettings.h" |
| 36 | #include "yuzu/util/util.h" | 37 | #include "yuzu/util/util.h" |
| 38 | #include "yuzu/vk_device_info.h" | ||
| 37 | 39 | ||
| 38 | ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, | 40 | ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, |
| 41 | std::vector<VkDeviceInfo::Record>& vk_device_records, | ||
| 39 | Core::System& system_) | 42 | Core::System& system_) |
| 40 | : QDialog(parent), | 43 | : QDialog(parent), |
| 41 | ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_} { | 44 | ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_} { |
| @@ -50,7 +53,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st | |||
| 50 | general_tab = std::make_unique<ConfigureGeneral>(system_, this); | 53 | general_tab = std::make_unique<ConfigureGeneral>(system_, this); |
| 51 | graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); | 54 | graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); |
| 52 | graphics_tab = std::make_unique<ConfigureGraphics>( | 55 | graphics_tab = std::make_unique<ConfigureGraphics>( |
| 53 | system_, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this); | 56 | system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this); |
| 54 | input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); | 57 | input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); |
| 55 | system_tab = std::make_unique<ConfigureSystem>(system_, this); | 58 | system_tab = std::make_unique<ConfigureSystem>(system_, this); |
| 56 | 59 | ||
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index 85752f1fa..7ec1ded06 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h | |||
| @@ -5,11 +5,13 @@ | |||
| 5 | 5 | ||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <vector> | ||
| 8 | 9 | ||
| 9 | #include <QDialog> | 10 | #include <QDialog> |
| 10 | #include <QList> | 11 | #include <QList> |
| 11 | 12 | ||
| 12 | #include "core/file_sys/vfs_types.h" | 13 | #include "core/file_sys/vfs_types.h" |
| 14 | #include "vk_device_info.h" | ||
| 13 | #include "yuzu/configuration/config.h" | 15 | #include "yuzu/configuration/config.h" |
| 14 | 16 | ||
| 15 | namespace Core { | 17 | namespace Core { |
| @@ -45,6 +47,7 @@ class ConfigurePerGame : public QDialog { | |||
| 45 | public: | 47 | public: |
| 46 | // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 | 48 | // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 |
| 47 | explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, | 49 | explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, |
| 50 | std::vector<VkDeviceInfo::Record>& vk_device_records, | ||
| 48 | Core::System& system_); | 51 | Core::System& system_); |
| 49 | ~ConfigurePerGame() override; | 52 | ~ConfigurePerGame() override; |
| 50 | 53 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 013715b44..8768a7c3c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -147,6 +147,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 147 | #include "yuzu/startup_checks.h" | 147 | #include "yuzu/startup_checks.h" |
| 148 | #include "yuzu/uisettings.h" | 148 | #include "yuzu/uisettings.h" |
| 149 | #include "yuzu/util/clickable_label.h" | 149 | #include "yuzu/util/clickable_label.h" |
| 150 | #include "yuzu/vk_device_info.h" | ||
| 150 | 151 | ||
| 151 | #ifdef YUZU_DBGHELP | 152 | #ifdef YUZU_DBGHELP |
| 152 | #include "yuzu/mini_dump.h" | 153 | #include "yuzu/mini_dump.h" |
| @@ -440,6 +441,8 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan | |||
| 440 | 441 | ||
| 441 | renderer_status_button->setDisabled(true); | 442 | renderer_status_button->setDisabled(true); |
| 442 | renderer_status_button->setChecked(false); | 443 | renderer_status_button->setChecked(false); |
| 444 | } else { | ||
| 445 | VkDeviceInfo::PopulateRecords(vk_device_records, this->window()->windowHandle()); | ||
| 443 | } | 446 | } |
| 444 | 447 | ||
| 445 | #if defined(HAVE_SDL2) && !defined(_WIN32) | 448 | #if defined(HAVE_SDL2) && !defined(_WIN32) |
| @@ -3494,7 +3497,8 @@ void GMainWindow::OnConfigure() { | |||
| 3494 | const auto old_language_index = Settings::values.language_index.GetValue(); | 3497 | const auto old_language_index = Settings::values.language_index.GetValue(); |
| 3495 | 3498 | ||
| 3496 | Settings::SetConfiguringGlobal(true); | 3499 | Settings::SetConfiguringGlobal(true); |
| 3497 | ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), *system, | 3500 | ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), |
| 3501 | vk_device_records, *system, | ||
| 3498 | !multiplayer_state->IsHostingPublicRoom()); | 3502 | !multiplayer_state->IsHostingPublicRoom()); |
| 3499 | connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this, | 3503 | connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this, |
| 3500 | &GMainWindow::OnLanguageChanged); | 3504 | &GMainWindow::OnLanguageChanged); |
| @@ -3765,7 +3769,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file | |||
| 3765 | const auto v_file = Core::GetGameFileFromPath(vfs, file_name); | 3769 | const auto v_file = Core::GetGameFileFromPath(vfs, file_name); |
| 3766 | 3770 | ||
| 3767 | Settings::SetConfiguringGlobal(false); | 3771 | Settings::SetConfiguringGlobal(false); |
| 3768 | ConfigurePerGame dialog(this, title_id, file_name, *system); | 3772 | ConfigurePerGame dialog(this, title_id, file_name, vk_device_records, *system); |
| 3769 | dialog.LoadFromFile(v_file); | 3773 | dialog.LoadFromFile(v_file); |
| 3770 | const auto result = dialog.exec(); | 3774 | const auto result = dialog.exec(); |
| 3771 | 3775 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 6bb70972f..e0e775d87 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -118,6 +118,10 @@ enum class ReinitializeKeyBehavior { | |||
| 118 | Warning, | 118 | Warning, |
| 119 | }; | 119 | }; |
| 120 | 120 | ||
| 121 | namespace VkDeviceInfo { | ||
| 122 | class Record; | ||
| 123 | } | ||
| 124 | |||
| 121 | class GMainWindow : public QMainWindow { | 125 | class GMainWindow : public QMainWindow { |
| 122 | Q_OBJECT | 126 | Q_OBJECT |
| 123 | 127 | ||
| @@ -418,6 +422,8 @@ private: | |||
| 418 | 422 | ||
| 419 | GameListPlaceholder* game_list_placeholder; | 423 | GameListPlaceholder* game_list_placeholder; |
| 420 | 424 | ||
| 425 | std::vector<VkDeviceInfo::Record> vk_device_records; | ||
| 426 | |||
| 421 | // Status bar elements | 427 | // Status bar elements |
| 422 | QLabel* message_label = nullptr; | 428 | QLabel* message_label = nullptr; |
| 423 | QLabel* shader_building_label = nullptr; | 429 | QLabel* shader_building_label = nullptr; |
diff --git a/src/yuzu/vk_device_info.cpp b/src/yuzu/vk_device_info.cpp new file mode 100644 index 000000000..9bd1ec686 --- /dev/null +++ b/src/yuzu/vk_device_info.cpp | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include <utility> | ||
| 5 | #include <vector> | ||
| 6 | #include "common/dynamic_library.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "video_core/vulkan_common/vulkan_instance.h" | ||
| 9 | #include "video_core/vulkan_common/vulkan_library.h" | ||
| 10 | #include "video_core/vulkan_common/vulkan_surface.h" | ||
| 11 | #include "video_core/vulkan_common/vulkan_wrapper.h" | ||
| 12 | #include "yuzu/qt_common.h" | ||
| 13 | #include "yuzu/vk_device_info.h" | ||
| 14 | |||
| 15 | class QWindow; | ||
| 16 | |||
| 17 | namespace VkDeviceInfo { | ||
| 18 | Record::Record(std::string_view name_, const std::vector<VkPresentModeKHR>& vsync_modes_, | ||
| 19 | bool is_intel_proprietary_) | ||
| 20 | : name{name_}, vsync_support{vsync_modes_}, is_intel_proprietary{is_intel_proprietary_} {} | ||
| 21 | |||
| 22 | Record::~Record() = default; | ||
| 23 | |||
| 24 | void PopulateRecords(std::vector<Record>& records, QWindow* window) try { | ||
| 25 | using namespace Vulkan; | ||
| 26 | |||
| 27 | auto wsi = QtCommon::GetWindowSystemInfo(window); | ||
| 28 | |||
| 29 | vk::InstanceDispatch dld; | ||
| 30 | const auto library = OpenLibrary(); | ||
| 31 | const vk::Instance instance = CreateInstance(*library, dld, VK_API_VERSION_1_1, wsi.type); | ||
| 32 | const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); | ||
| 33 | vk::SurfaceKHR surface = CreateSurface(instance, wsi); | ||
| 34 | |||
| 35 | records.clear(); | ||
| 36 | records.reserve(physical_devices.size()); | ||
| 37 | for (const VkPhysicalDevice device : physical_devices) { | ||
| 38 | const auto physical_device = vk::PhysicalDevice(device, dld); | ||
| 39 | const std::string name = physical_device.GetProperties().deviceName; | ||
| 40 | const std::vector<VkPresentModeKHR> present_modes = | ||
| 41 | physical_device.GetSurfacePresentModesKHR(*surface); | ||
| 42 | |||
| 43 | VkPhysicalDeviceDriverProperties driver_properties{}; | ||
| 44 | driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; | ||
| 45 | driver_properties.pNext = nullptr; | ||
| 46 | VkPhysicalDeviceProperties2 properties{}; | ||
| 47 | properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; | ||
| 48 | properties.pNext = &driver_properties; | ||
| 49 | dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); | ||
| 50 | |||
| 51 | records.push_back(VkDeviceInfo::Record(name, present_modes, | ||
| 52 | driver_properties.driverID == | ||
| 53 | VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS)); | ||
| 54 | } | ||
| 55 | } catch (const Vulkan::vk::Exception& exception) { | ||
| 56 | LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); | ||
| 57 | } | ||
| 58 | } // namespace VkDeviceInfo | ||
diff --git a/src/yuzu/vk_device_info.h b/src/yuzu/vk_device_info.h new file mode 100644 index 000000000..5a6c64416 --- /dev/null +++ b/src/yuzu/vk_device_info.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <algorithm> | ||
| 7 | #include <iterator> | ||
| 8 | #include <memory> | ||
| 9 | #include <string> | ||
| 10 | #include <string_view> | ||
| 11 | #include <vector> | ||
| 12 | #include "common/common_types.h" | ||
| 13 | #include "vulkan/vulkan_core.h" | ||
| 14 | |||
| 15 | class QWindow; | ||
| 16 | |||
| 17 | namespace Settings { | ||
| 18 | enum class VSyncMode : u32; | ||
| 19 | } | ||
| 20 | // #include "common/settings.h" | ||
| 21 | |||
| 22 | namespace VkDeviceInfo { | ||
| 23 | // Short class to record Vulkan driver information for configuration purposes | ||
| 24 | class Record { | ||
| 25 | public: | ||
| 26 | explicit Record(std::string_view name, const std::vector<VkPresentModeKHR>& vsync_modes, | ||
| 27 | bool is_intel_proprietary); | ||
| 28 | ~Record(); | ||
| 29 | |||
| 30 | const std::string name; | ||
| 31 | const std::vector<VkPresentModeKHR> vsync_support; | ||
| 32 | const bool is_intel_proprietary; | ||
| 33 | }; | ||
| 34 | |||
| 35 | void PopulateRecords(std::vector<Record>& records, QWindow* window); | ||
| 36 | } // namespace VkDeviceInfo | ||