diff options
Diffstat (limited to '')
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 @@ [submodule "libadrenotools"] path = externals/libadrenotools url = https://github.com/bylaws/libadrenotools +[submodule "tzdb_to_nx"] + path = externals/nx_tzdb/tzdb_to_nx + 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) option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF) +option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" OFF) + CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "NOT WIN32" OFF) # 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 @@ # SPDX-FileCopyrightText: 2023 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later -set(NX_TZDB_VERSION "220816") -set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip") +set(NX_TZDB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include") + +add_library(nx_tzdb INTERFACE) + +find_program(GIT git) +find_program(GNU_MAKE make) +find_program(GNU_DATE date) +set(CAN_BUILD_NX_TZDB true) + +if (NOT GIT) + set(CAN_BUILD_NX_TZDB false) +endif() +if (NOT GNU_MAKE) + set(CAN_BUILD_NX_TZDB false) +endif() +if (NOT GNU_DATE) + set(CAN_BUILD_NX_TZDB false) +endif() +if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR ANDROID) + # tzdb_to_nx currently requires a posix-compliant host + # MinGW and Android are handled here due to the executable format being different from the host system + # TODO (lat9nq): cross-compiling support + set(CAN_BUILD_NX_TZDB false) +endif() + +set(NX_TZDB_VERSION "220816") set(NX_TZDB_ARCHIVE "${CMAKE_CURRENT_BINARY_DIR}/${NX_TZDB_VERSION}.zip") -set(NX_TZDB_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb") -set(NX_TZDB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include") +set(NX_TZDB_ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/nx_tzdb") + +if ((NOT CAN_BUILD_NX_TZDB OR YUZU_DOWNLOAD_TIME_ZONE_DATA) AND NOT EXISTS ${NX_TZDB_ARCHIVE}) + set(NX_TZDB_DOWNLOAD_URL "https://github.com/lat9nq/tzdb_to_nx/releases/download/${NX_TZDB_VERSION}/${NX_TZDB_VERSION}.zip") + + message(STATUS "Downloading time zone data from ${NX_TZDB_DOWNLOAD_URL}...") + file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE} + STATUS NX_TZDB_DOWNLOAD_STATUS) + list(GET NX_TZDB_DOWNLOAD_STATUS 0 NX_TZDB_DOWNLOAD_STATUS_CODE) + if (NOT NX_TZDB_DOWNLOAD_STATUS_CODE EQUAL 0) + message(FATAL_ERROR "Time zone data download failed (status code ${NX_TZDB_DOWNLOAD_STATUS_CODE})") + endif() -if (NOT EXISTS ${NX_TZDB_ARCHIVE}) - file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE}) file(ARCHIVE_EXTRACT INPUT ${NX_TZDB_ARCHIVE} DESTINATION - ${NX_TZDB_DIR}) + ${NX_TZDB_ROMFS_DIR}) +elseif (CAN_BUILD_NX_TZDB AND NOT YUZU_DOWNLOAD_TIME_ZONE_DATA) + add_subdirectory(tzdb_to_nx) + add_dependencies(nx_tzdb x80e) + + set(NX_TZDB_ROMFS_DIR "${NX_TZDB_DIR}") endif() -add_library(nx_tzdb INTERFACE) target_include_directories(nx_tzdb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include INTERFACE ${NX_TZDB_INCLUDE_DIR}) @@ -41,25 +77,25 @@ function(CreateHeader ZONE_PATH HEADER_NAME) target_sources(nx_tzdb PRIVATE ${HEADER_PATH}) endfunction() -CreateHeader(${NX_TZDB_DIR} base) -CreateHeader(${NX_TZDB_DIR}/zoneinfo zoneinfo) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Africa africa) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/America america) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/Argentina america_argentina) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/Indiana america_indiana) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/Kentucky america_kentucky) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/America/North_Dakota america_north_dakota) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Antartica antartica) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Arctic arctic) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Asia asia) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Atlantic atlantic) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Australia australia) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Brazil brazil) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Canada canada) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Chile chile) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Etc etc) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Europe europe) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Indian indian) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Mexico mexico) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/Pacific pacific) -CreateHeader(${NX_TZDB_DIR}/zoneinfo/US us) +CreateHeader(${NX_TZDB_ROMFS_DIR} base) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo zoneinfo) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Africa africa) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America america) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Argentina america_argentina) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Indiana america_indiana) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/Kentucky america_kentucky) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/America/North_Dakota america_north_dakota) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Antarctica antarctica) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Arctic arctic) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Asia asia) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Atlantic atlantic) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Australia australia) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Brazil brazil) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Canada canada) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Chile chile) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Etc etc) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Europe europe) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Indian indian) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Mexico mexico) +CreateHeader(${NX_TZDB_ROMFS_DIR}/zoneinfo/Pacific pacific) +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}) set(FILE_DATA "") foreach(ZONE_FILE ${FILE_LIST}) - if ("${ZONE_FILE}" STREQUAL "\n") + if (ZONE_FILE STREQUAL "\n") continue() endif() @@ -26,13 +26,13 @@ foreach(ZONE_FILE ${FILE_LIST}) foreach(I RANGE 0 ${ZONE_DATA_LEN} 2) math(EXPR BREAK_LINE "(${I} + 2) % 38") - string(SUBSTRING "${ZONE_DATA}" "${I}" "2" HEX_DATA) - if ("${HEX_DATA}" STREQUAL "") + string(SUBSTRING "${ZONE_DATA}" "${I}" 2 HEX_DATA) + if (NOT HEX_DATA) break() endif() string(APPEND FILE_DATA "0x${HEX_DATA},") - if ("${BREAK_LINE}" STREQUAL "0") + if (BREAK_LINE EQUAL 0) string(APPEND FILE_DATA "\n") else() 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 @@ #include "nx_tzdb/america_indiana.h" #include "nx_tzdb/america_kentucky.h" #include "nx_tzdb/america_north_dakota.h" -#include "nx_tzdb/antartica.h" +#include "nx_tzdb/antarctica.h" #include "nx_tzdb/arctic.h" #include "nx_tzdb/asia.h" #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 { const static std::map<std::string, const std::map<const char*, const std::vector<u8>>&> tzdb_zoneinfo_dirs = {{"Africa", NxTzdb::africa}, {"America", NxTzdb::america}, - {"Antartica", NxTzdb::antartica}, + {"Antarctica", NxTzdb::antarctica}, {"Arctic", NxTzdb::arctic}, {"Asia", NxTzdb::asia}, {"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& static Result ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time, CalendarTimeInternal& calendar_time, CalendarAdditionalInfo& calendar_additional_info) { - if ((rules.go_ahead && time < rules.ats[0]) || - (rules.go_back && time > rules.ats[rules.time_count - 1])) { + ASSERT(rules.go_ahead ? rules.time_count > 0 : true); + if ((rules.go_back && time < rules.ats[0]) || + (rules.go_ahead && time > rules.ats[rules.time_count - 1])) { s64 seconds{}; if (time < rules.ats[0]) { 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) { LOG_DEBUG(Service_Time, "called, location_name={}", location_name); TimeZone::TimeZoneRule time_zone_rule{}; - if (const Result result{ - time_zone_content_manager.LoadTimeZoneRule(time_zone_rule, location_name)}; - result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } + const Result result{time_zone_content_manager.LoadTimeZoneRule(time_zone_rule, location_name)}; std::vector<u8> time_zone_rule_outbuffer(sizeof(TimeZone::TimeZoneRule)); std::memcpy(time_zone_rule_outbuffer.data(), &time_zone_rule, sizeof(TimeZone::TimeZoneRule)); ctx.WriteBuffer(time_zone_rule_outbuffer); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } 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() { bool any_valid{false}; auto& flags = maxwell3d->dirty.flags; for (u32 index = 0; index < NUM_VERTEX_BUFFERS; ++index) { + const Binding& binding = channel_state->vertex_buffers[index]; + Buffer& buffer = slot_buffers[binding.buffer_id]; + TouchBuffer(buffer, binding.buffer_id); + SynchronizeBuffer(buffer, binding.cpu_addr, binding.size); if (!flags[Dirty::VertexBuffer0 + index]) { continue; } + flags[Dirty::VertexBuffer0 + index] = false; + host_bindings.min_index = std::min(host_bindings.min_index, index); host_bindings.max_index = std::max(host_bindings.max_index, index); any_valid = true; @@ -735,9 +741,6 @@ void BufferCache<P>::BindHostVertexBuffers() { const Binding& binding = channel_state->vertex_buffers[index]; Buffer& buffer = slot_buffers[binding.buffer_id]; - TouchBuffer(buffer, binding.buffer_id); - SynchronizeBuffer(buffer, binding.cpu_addr, binding.size); - const u32 stride = maxwell3d->regs.vertex_streams[index].stride; const u32 offset = buffer.Offset(binding.cpu_addr); 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 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/settings.h" #include "video_core/dirty_flags.h" #include "video_core/engines/draw_manager.h" #include "video_core/rasterizer_interface.h" @@ -195,8 +196,12 @@ void DrawManager::DrawTexture() { if (lower_left) { draw_texture_state.dst_y0 -= dst_height; } - draw_texture_state.dst_x1 = draw_texture_state.dst_x0 + dst_width; - draw_texture_state.dst_y1 = draw_texture_state.dst_y0 + dst_height; + draw_texture_state.dst_x1 = + draw_texture_state.dst_x0 + + static_cast<f32>(Settings::values.resolution_info.ScaleUp(static_cast<u32>(dst_width))); + draw_texture_state.dst_y1 = + draw_texture_state.dst_y0 + + static_cast<f32>(Settings::values.resolution_info.ScaleUp(static_cast<u32>(dst_height))); draw_texture_state.src_x0 = static_cast<float>(regs.draw_texture.src_x0) / 4096.f; draw_texture_state.src_y0 = static_cast<float>(regs.draw_texture.src_y0) / 4096.f; draw_texture_state.src_x1 = @@ -207,7 +212,6 @@ void DrawManager::DrawTexture() { draw_texture_state.src_y0; draw_texture_state.src_sampler = regs.draw_texture.src_sampler; draw_texture_state.src_texture = regs.draw_texture.src_texture; - maxwell3d->rasterizer->DrawTexture(); } 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 buffer_handles.push_back(handle); } if (device.IsExtExtendedDynamicStateSupported()) { - scheduler.Record([bindings = bindings, - buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { + scheduler.Record([bindings = std::move(bindings), + buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { cmdbuf.BindVertexBuffers2EXT( bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(), bindings.offsets.data(), bindings.sizes.data(), bindings.strides.data()); }); } else { - scheduler.Record([bindings = bindings, - buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { + scheduler.Record([bindings = std::move(bindings), + buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { cmdbuf.BindVertexBuffers(bindings.min_index, bindings.max_index - bindings.min_index, buffer_handles.data(), bindings.offsets.data()); }); @@ -561,12 +561,12 @@ void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings< for (u32 index = 0; index < bindings.buffers.size(); ++index) { buffer_handles.push_back(bindings.buffers[index]->Handle()); } - scheduler.Record( - [bindings = bindings, buffer_handles = buffer_handles](vk::CommandBuffer cmdbuf) { - cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles.size()), - buffer_handles.data(), bindings.offsets.data(), - bindings.sizes.data()); - }); + scheduler.Record([bindings = std::move(bindings), + buffer_handles = std::move(buffer_handles)](vk::CommandBuffer cmdbuf) { + cmdbuf.BindTransformFeedbackBuffersEXT(0, static_cast<u32>(buffer_handles.size()), + buffer_handles.data(), bindings.offsets.data(), + bindings.sizes.data()); + }); } 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 @@ #include <thread> +#include "common/polyfill_ranges.h" #include "common/settings.h" #include "video_core/renderer_vulkan/vk_master_semaphore.h" #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) { FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION); FOR_EACH_VK_EXTENSION(EXTENSION); -#ifdef _WIN32 - FOR_EACH_VK_EXTENSION_WIN32(EXTENSION); -#endif #undef FEATURE_EXTENSION #undef EXTENSION @@ -804,11 +801,6 @@ bool Device::GetSuitability(bool requires_swapchain) { FOR_EACH_VK_RECOMMENDED_EXTENSION(LOG_EXTENSION); FOR_EACH_VK_MANDATORY_EXTENSION(CHECK_EXTENSION); -#ifdef _WIN32 - FOR_EACH_VK_MANDATORY_EXTENSION_WIN32(CHECK_EXTENSION); -#else - FOR_EACH_VK_MANDATORY_EXTENSION_GENERIC(CHECK_EXTENSION); -#endif if (requires_swapchain) { 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 @@ EXTENSION(EXT, VERTEX_ATTRIBUTE_DIVISOR, vertex_attribute_divisor) \ EXTENSION(KHR, DRAW_INDIRECT_COUNT, draw_indirect_count) \ EXTENSION(KHR, DRIVER_PROPERTIES, driver_properties) \ - EXTENSION(KHR, EXTERNAL_MEMORY_FD, external_memory_fd) \ EXTENSION(KHR, PUSH_DESCRIPTOR, push_descriptor) \ EXTENSION(KHR, SAMPLER_MIRROR_CLAMP_TO_EDGE, sampler_mirror_clamp_to_edge) \ EXTENSION(KHR, SHADER_FLOAT_CONTROLS, shader_float_controls) \ @@ -80,9 +79,6 @@ EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \ EXTENSION(NV, VIEWPORT_SWIZZLE, viewport_swizzle) -#define FOR_EACH_VK_EXTENSION_WIN32(EXTENSION) \ - EXTENSION(KHR, EXTERNAL_MEMORY_WIN32, external_memory_win32) - // Define extensions which must be supported. #define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) \ @@ -90,12 +86,6 @@ EXTENSION_NAME(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME) \ EXTENSION_NAME(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME) -#define FOR_EACH_VK_MANDATORY_EXTENSION_GENERIC(EXTENSION_NAME) \ - EXTENSION_NAME(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME) - -#define FOR_EACH_VK_MANDATORY_EXTENSION_WIN32(EXTENSION_NAME) \ - EXTENSION_NAME(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME) - // Define extensions where the absence of the extension may result in a degraded experience. #define FOR_EACH_VK_RECOMMENDED_EXTENSION(EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME) \ @@ -636,7 +626,6 @@ private: FOR_EACH_VK_FEATURE_1_3(FEATURE); FOR_EACH_VK_FEATURE_EXT(FEATURE); FOR_EACH_VK_EXTENSION(EXTENSION); - FOR_EACH_VK_EXTENSION_WIN32(EXTENSION); #undef EXTENSION #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 util/url_request_interceptor.h util/util.cpp util/util.h + vk_device_info.cpp + vk_device_info.h compatdb.cpp compatdb.h 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 @@ #include "common/settings.h" #include "core/core.h" #include "ui_configure.h" +#include "vk_device_info.h" #include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_audio.h" #include "yuzu/configuration/configure_cpu.h" @@ -28,6 +29,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, InputCommon::InputSubsystem* input_subsystem, + std::vector<VkDeviceInfo::Record>& vk_device_records, Core::System& system_, bool enable_web_config) : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry(registry_), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, @@ -38,7 +40,8 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, general_tab{std::make_unique<ConfigureGeneral>(system_, this)}, graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, this)}, graphics_tab{std::make_unique<ConfigureGraphics>( - system_, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this)}, + system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, + this)}, hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)}, input_tab{std::make_unique<ConfigureInput>(system_, this)}, 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 @@ #pragma once #include <memory> +#include <vector> #include <QDialog> +#include "yuzu/vk_device_info.h" namespace Core { class System; @@ -40,8 +42,9 @@ class ConfigureDialog : public QDialog { public: explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, - InputCommon::InputSubsystem* input_subsystem, Core::System& system_, - bool enable_web_config = true); + InputCommon::InputSubsystem* input_subsystem, + std::vector<VkDeviceInfo::Record>& vk_device_records, + Core::System& system_, bool enable_web_config = true); ~ConfigureDialog() override; 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 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// Include this early to include Vulkan headers how we want to -#include "video_core/vulkan_common/vulkan_device.h" -#include "video_core/vulkan_common/vulkan_wrapper.h" - #include <algorithm> #include <functional> #include <iosfwd> @@ -34,13 +30,11 @@ #include "common/settings.h" #include "core/core.h" #include "ui_configure_graphics.h" -#include "video_core/vulkan_common/vulkan_instance.h" -#include "video_core/vulkan_common/vulkan_library.h" -#include "video_core/vulkan_common/vulkan_surface.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_graphics.h" #include "yuzu/qt_common.h" #include "yuzu/uisettings.h" +#include "yuzu/vk_device_info.h" static const std::vector<VkPresentModeKHR> default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR}; @@ -77,9 +71,10 @@ static constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode) } ConfigureGraphics::ConfigureGraphics(const Core::System& system_, + std::vector<VkDeviceInfo::Record>& records_, const std::function<void()>& expose_compute_option_, QWidget* parent) - : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, + : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, records{records_}, expose_compute_option{expose_compute_option_}, system{system_} { vulkan_device = Settings::values.vulkan_device.GetValue(); RetrieveVulkanDevices(); @@ -504,47 +499,19 @@ void ConfigureGraphics::UpdateAPILayout() { } } -void ConfigureGraphics::RetrieveVulkanDevices() try { - if (UISettings::values.has_broken_vulkan) { - return; - } - - using namespace Vulkan; - - auto* window = this->window()->windowHandle(); - auto wsi = QtCommon::GetWindowSystemInfo(window); - - vk::InstanceDispatch dld; - const auto library = OpenLibrary(); - const vk::Instance instance = CreateInstance(*library, dld, VK_API_VERSION_1_1, wsi.type); - const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); - vk::SurfaceKHR surface = CreateSurface(instance, wsi); - +void ConfigureGraphics::RetrieveVulkanDevices() { vulkan_devices.clear(); - vulkan_devices.reserve(physical_devices.size()); + vulkan_devices.reserve(records.size()); device_present_modes.clear(); - device_present_modes.reserve(physical_devices.size()); - for (const VkPhysicalDevice device : physical_devices) { - const auto physical_device = vk::PhysicalDevice(device, dld); - const std::string name = physical_device.GetProperties().deviceName; - const std::vector<VkPresentModeKHR> present_modes = - physical_device.GetSurfacePresentModesKHR(*surface); - vulkan_devices.push_back(QString::fromStdString(name)); - device_present_modes.push_back(present_modes); - - VkPhysicalDeviceDriverProperties driver_properties{}; - driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; - driver_properties.pNext = nullptr; - VkPhysicalDeviceProperties2 properties{}; - properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; - properties.pNext = &driver_properties; - dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); - if (driver_properties.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { + device_present_modes.reserve(records.size()); + for (const auto& record : records) { + vulkan_devices.push_back(QString::fromStdString(record.name)); + device_present_modes.push_back(record.vsync_support); + + if (record.is_intel_proprietary) { expose_compute_option(); } } -} catch (const Vulkan::vk::Exception& exception) { - LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); } 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 @@ #include <qobjectdefs.h> #include <vulkan/vulkan_core.h> #include "common/common_types.h" +#include "vk_device_info.h" class QEvent; class QObject; @@ -39,6 +40,7 @@ class ConfigureGraphics : public QWidget { public: explicit ConfigureGraphics(const Core::System& system_, + std::vector<VkDeviceInfo::Record>& records, const std::function<void()>& expose_compute_option_, QWidget* parent = nullptr); ~ConfigureGraphics() override; @@ -77,6 +79,7 @@ private: ConfigurationShared::CheckState use_disk_shader_cache; ConfigurationShared::CheckState use_asynchronous_gpu_emulation; + std::vector<VkDeviceInfo::Record>& records; std::vector<QString> vulkan_devices; std::vector<std::vector<VkPresentModeKHR>> device_present_modes; 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 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include <fmt/format.h> @@ -34,8 +35,10 @@ #include "yuzu/configuration/configure_system.h" #include "yuzu/uisettings.h" #include "yuzu/util/util.h" +#include "yuzu/vk_device_info.h" ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, + std::vector<VkDeviceInfo::Record>& vk_device_records, Core::System& system_) : QDialog(parent), 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 general_tab = std::make_unique<ConfigureGeneral>(system_, this); graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); graphics_tab = std::make_unique<ConfigureGraphics>( - system_, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this); + system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this); input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); system_tab = std::make_unique<ConfigureSystem>(system_, this); 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 @@ #include <memory> #include <string> +#include <vector> #include <QDialog> #include <QList> #include "core/file_sys/vfs_types.h" +#include "vk_device_info.h" #include "yuzu/configuration/config.h" namespace Core { @@ -45,6 +47,7 @@ class ConfigurePerGame : public QDialog { public: // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, + std::vector<VkDeviceInfo::Record>& vk_device_records, Core::System& system_); ~ConfigurePerGame() override; 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 #include "yuzu/startup_checks.h" #include "yuzu/uisettings.h" #include "yuzu/util/clickable_label.h" +#include "yuzu/vk_device_info.h" #ifdef YUZU_DBGHELP #include "yuzu/mini_dump.h" @@ -440,6 +441,8 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan renderer_status_button->setDisabled(true); renderer_status_button->setChecked(false); + } else { + VkDeviceInfo::PopulateRecords(vk_device_records, this->window()->windowHandle()); } #if defined(HAVE_SDL2) && !defined(_WIN32) @@ -3494,7 +3497,8 @@ void GMainWindow::OnConfigure() { const auto old_language_index = Settings::values.language_index.GetValue(); Settings::SetConfiguringGlobal(true); - ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), *system, + ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), + vk_device_records, *system, !multiplayer_state->IsHostingPublicRoom()); connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this, &GMainWindow::OnLanguageChanged); @@ -3765,7 +3769,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file const auto v_file = Core::GetGameFileFromPath(vfs, file_name); Settings::SetConfiguringGlobal(false); - ConfigurePerGame dialog(this, title_id, file_name, *system); + ConfigurePerGame dialog(this, title_id, file_name, vk_device_records, *system); dialog.LoadFromFile(v_file); const auto result = dialog.exec(); 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 { Warning, }; +namespace VkDeviceInfo { +class Record; +} + class GMainWindow : public QMainWindow { Q_OBJECT @@ -418,6 +422,8 @@ private: GameListPlaceholder* game_list_placeholder; + std::vector<VkDeviceInfo::Record> vk_device_records; + // Status bar elements QLabel* message_label = nullptr; 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 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <utility> +#include <vector> +#include "common/dynamic_library.h" +#include "common/logging/log.h" +#include "video_core/vulkan_common/vulkan_instance.h" +#include "video_core/vulkan_common/vulkan_library.h" +#include "video_core/vulkan_common/vulkan_surface.h" +#include "video_core/vulkan_common/vulkan_wrapper.h" +#include "yuzu/qt_common.h" +#include "yuzu/vk_device_info.h" + +class QWindow; + +namespace VkDeviceInfo { +Record::Record(std::string_view name_, const std::vector<VkPresentModeKHR>& vsync_modes_, + bool is_intel_proprietary_) + : name{name_}, vsync_support{vsync_modes_}, is_intel_proprietary{is_intel_proprietary_} {} + +Record::~Record() = default; + +void PopulateRecords(std::vector<Record>& records, QWindow* window) try { + using namespace Vulkan; + + auto wsi = QtCommon::GetWindowSystemInfo(window); + + vk::InstanceDispatch dld; + const auto library = OpenLibrary(); + const vk::Instance instance = CreateInstance(*library, dld, VK_API_VERSION_1_1, wsi.type); + const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); + vk::SurfaceKHR surface = CreateSurface(instance, wsi); + + records.clear(); + records.reserve(physical_devices.size()); + for (const VkPhysicalDevice device : physical_devices) { + const auto physical_device = vk::PhysicalDevice(device, dld); + const std::string name = physical_device.GetProperties().deviceName; + const std::vector<VkPresentModeKHR> present_modes = + physical_device.GetSurfacePresentModesKHR(*surface); + + VkPhysicalDeviceDriverProperties driver_properties{}; + driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; + driver_properties.pNext = nullptr; + VkPhysicalDeviceProperties2 properties{}; + properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; + properties.pNext = &driver_properties; + dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); + + records.push_back(VkDeviceInfo::Record(name, present_modes, + driver_properties.driverID == + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS)); + } +} catch (const Vulkan::vk::Exception& exception) { + LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); +} +} // 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 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <algorithm> +#include <iterator> +#include <memory> +#include <string> +#include <string_view> +#include <vector> +#include "common/common_types.h" +#include "vulkan/vulkan_core.h" + +class QWindow; + +namespace Settings { +enum class VSyncMode : u32; +} +// #include "common/settings.h" + +namespace VkDeviceInfo { +// Short class to record Vulkan driver information for configuration purposes +class Record { +public: + explicit Record(std::string_view name, const std::vector<VkPresentModeKHR>& vsync_modes, + bool is_intel_proprietary); + ~Record(); + + const std::string name; + const std::vector<VkPresentModeKHR> vsync_support; + const bool is_intel_proprietary; +}; + +void PopulateRecords(std::vector<Record>& records, QWindow* window); +} // namespace VkDeviceInfo |