Compare commits
39 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae1a8a7dc7 | ||
|
|
fd5d7947f6 | ||
|
|
a67bdeb2c2 | ||
|
|
f1e12e3b08 | ||
|
|
93061d1ea1 | ||
|
|
6d12e7320b | ||
|
|
78ff2862f6 | ||
|
|
197e13d93d | ||
|
|
bedb5135c0 | ||
|
|
256c7ec0a7 | ||
|
|
711190bb67 | ||
|
|
b9a86b040b | ||
|
|
346c253cd2 | ||
|
|
ce191ba32b | ||
|
|
23371fa187 | ||
|
|
af7f3f078c | ||
|
|
66b8042b59 | ||
|
|
8acf728d5d | ||
|
|
6e293be20b | ||
|
|
20db91f0fc | ||
|
|
8a526b2c26 | ||
|
|
fd0ef5411c | ||
|
|
b99c4dd568 | ||
|
|
e681f5678c | ||
|
|
76a676883a | ||
|
|
4cbdce17b6 | ||
|
|
b77a247e8c | ||
|
|
1fa16bc594 | ||
|
|
d9e2824c4e | ||
|
|
d35c989902 | ||
|
|
7ffb96f474 | ||
|
|
e9701a3cda | ||
|
|
b23c358e3d | ||
|
|
cdc73498e3 | ||
|
|
8d8f850bd6 | ||
|
|
03e8d9aca7 | ||
|
|
013c34cb32 | ||
|
|
f9fc996083 | ||
|
|
fc0c4db20d |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
100
externals/nx_tzdb/CMakeLists.txt
vendored
100
externals/nx_tzdb/CMakeLists.txt
vendored
@@ -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_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")
|
||||
|
||||
if (NOT EXISTS ${NX_TZDB_ARCHIVE})
|
||||
file(DOWNLOAD ${NX_TZDB_DOWNLOAD_URL} ${NX_TZDB_ARCHIVE})
|
||||
add_library(nx_tzdb INTERFACE)
|
||||
|
||||
find_program(GIT git)
|
||||
find_program(GNU_MAKE make)
|
||||
find_program(DATE_PROG 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 DATE_PROG)
|
||||
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_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()
|
||||
|
||||
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)
|
||||
|
||||
8
externals/nx_tzdb/NxTzdbCreateHeader.cmake
vendored
8
externals/nx_tzdb/NxTzdbCreateHeader.cmake
vendored
@@ -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 " ")
|
||||
|
||||
2
externals/nx_tzdb/include/nx_tzdb.h
vendored
2
externals/nx_tzdb/include/nx_tzdb.h
vendored
@@ -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"
|
||||
|
||||
1
externals/nx_tzdb/tzdb_to_nx
vendored
Submodule
1
externals/nx_tzdb/tzdb_to_nx
vendored
Submodule
Submodule externals/nx_tzdb/tzdb_to_nx added at 8c272f21d1
2
externals/vcpkg
vendored
2
externals/vcpkg
vendored
Submodule externals/vcpkg updated: a487471068...cbf56573a9
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
@@ -910,9 +911,13 @@ static Result ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time,
|
||||
|
||||
calendar_additional_info.is_dst = rules.ttis[tti_index].is_dst;
|
||||
const char* time_zone{&rules.chars[rules.ttis[tti_index].abbreviation_list_index]};
|
||||
for (int index{}; time_zone[index] != '\0'; ++index) {
|
||||
u32 index;
|
||||
for (index = 0; time_zone[index] != '\0' && time_zone[index] != ',' &&
|
||||
index < calendar_additional_info.timezone_name.size() - 1;
|
||||
++index) {
|
||||
calendar_additional_info.timezone_name[index] = time_zone[index];
|
||||
}
|
||||
calendar_additional_info.timezone_name[index] = '\0';
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ GPUVAddr MemoryManager::PageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cp
|
||||
[[maybe_unused]] const auto current_entry_type = GetEntry<false>(current_gpu_addr);
|
||||
SetEntry<false>(current_gpu_addr, entry_type);
|
||||
if (current_entry_type != entry_type) {
|
||||
rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, page_size);
|
||||
rasterizer->ModifyGPUMemory(unique_identifier, current_gpu_addr, page_size);
|
||||
}
|
||||
if constexpr (entry_type == EntryType::Mapped) {
|
||||
const VAddr current_cpu_addr = cpu_addr + offset;
|
||||
@@ -134,7 +134,7 @@ GPUVAddr MemoryManager::BigPageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr
|
||||
[[maybe_unused]] const auto current_entry_type = GetEntry<true>(current_gpu_addr);
|
||||
SetEntry<true>(current_gpu_addr, entry_type);
|
||||
if (current_entry_type != entry_type) {
|
||||
rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, big_page_size);
|
||||
rasterizer->ModifyGPUMemory(unique_identifier, current_gpu_addr, big_page_size);
|
||||
}
|
||||
if constexpr (entry_type == EntryType::Mapped) {
|
||||
const VAddr current_cpu_addr = cpu_addr + offset;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -705,10 +705,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
||||
std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
||||
ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env,
|
||||
PipelineStatistics* statistics, bool build_in_parallel) try {
|
||||
// TODO: Remove this when Intel fixes their shader compiler.
|
||||
// https://github.com/IGCIT/Intel-GPU-Community-Issue-Tracker-IGCIT/issues/159
|
||||
if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS &&
|
||||
!Settings::values.enable_compute_pipelines.GetValue()) {
|
||||
if (device.HasBrokenCompute()) {
|
||||
LOG_ERROR(Render_Vulkan, "Skipping 0x{:016x}", key.Hash());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ void TextureCache<P>::SynchronizeComputeDescriptors() {
|
||||
}
|
||||
|
||||
template <class P>
|
||||
bool TextureCache<P>::RescaleRenderTargets(bool is_clear) {
|
||||
bool TextureCache<P>::RescaleRenderTargets() {
|
||||
auto& flags = maxwell3d->dirty.flags;
|
||||
u32 scale_rating = 0;
|
||||
bool rescaled = false;
|
||||
@@ -338,13 +338,13 @@ bool TextureCache<P>::RescaleRenderTargets(bool is_clear) {
|
||||
ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
|
||||
if (flags[Dirty::ColorBuffer0 + index] || force) {
|
||||
flags[Dirty::ColorBuffer0 + index] = false;
|
||||
BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
|
||||
BindRenderTarget(&color_buffer_id, FindColorBuffer(index));
|
||||
}
|
||||
check_rescale(color_buffer_id, tmp_color_images[index]);
|
||||
}
|
||||
if (flags[Dirty::ZetaBuffer] || force) {
|
||||
flags[Dirty::ZetaBuffer] = false;
|
||||
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
|
||||
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer());
|
||||
}
|
||||
check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
|
||||
|
||||
@@ -409,7 +409,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool rescaled = RescaleRenderTargets(is_clear);
|
||||
const bool rescaled = RescaleRenderTargets();
|
||||
if (is_rescaling != rescaled) {
|
||||
flags[Dirty::RescaleViewports] = true;
|
||||
flags[Dirty::RescaleScissors] = true;
|
||||
@@ -1678,7 +1678,7 @@ SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) {
|
||||
}
|
||||
|
||||
template <class P>
|
||||
ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) {
|
||||
ImageViewId TextureCache<P>::FindColorBuffer(size_t index) {
|
||||
const auto& regs = maxwell3d->regs;
|
||||
if (index >= regs.rt_control.count) {
|
||||
return ImageViewId{};
|
||||
@@ -1692,11 +1692,11 @@ ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) {
|
||||
return ImageViewId{};
|
||||
}
|
||||
const ImageInfo info(regs.rt[index], regs.anti_alias_samples_mode);
|
||||
return FindRenderTargetView(info, gpu_addr, is_clear);
|
||||
return FindRenderTargetView(info, gpu_addr);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
ImageViewId TextureCache<P>::FindDepthBuffer(bool is_clear) {
|
||||
ImageViewId TextureCache<P>::FindDepthBuffer() {
|
||||
const auto& regs = maxwell3d->regs;
|
||||
if (!regs.zeta_enable) {
|
||||
return ImageViewId{};
|
||||
@@ -1706,18 +1706,16 @@ ImageViewId TextureCache<P>::FindDepthBuffer(bool is_clear) {
|
||||
return ImageViewId{};
|
||||
}
|
||||
const ImageInfo info(regs.zeta, regs.zeta_size, regs.anti_alias_samples_mode);
|
||||
return FindRenderTargetView(info, gpu_addr, is_clear);
|
||||
return FindRenderTargetView(info, gpu_addr);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr,
|
||||
bool is_clear) {
|
||||
const auto options = is_clear ? RelaxedOptions::Samples : RelaxedOptions{};
|
||||
ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr) {
|
||||
ImageId image_id{};
|
||||
bool delete_state = has_deleted_images;
|
||||
do {
|
||||
has_deleted_images = false;
|
||||
image_id = FindOrInsertImage(info, gpu_addr, options);
|
||||
image_id = FindOrInsertImage(info, gpu_addr);
|
||||
delete_state |= has_deleted_images;
|
||||
} while (has_deleted_images);
|
||||
has_deleted_images = delete_state;
|
||||
|
||||
@@ -178,9 +178,8 @@ public:
|
||||
void SynchronizeComputeDescriptors();
|
||||
|
||||
/// Updates the Render Targets if they can be rescaled
|
||||
/// @param is_clear True when the render targets are being used for clears
|
||||
/// @retval True if the Render Targets have been rescaled.
|
||||
bool RescaleRenderTargets(bool is_clear);
|
||||
bool RescaleRenderTargets();
|
||||
|
||||
/// Update bound render targets and upload memory if necessary
|
||||
/// @param is_clear True when the render targets are being used for clears
|
||||
@@ -336,14 +335,13 @@ private:
|
||||
[[nodiscard]] SamplerId FindSampler(const TSCEntry& config);
|
||||
|
||||
/// Find or create an image view for the given color buffer index
|
||||
[[nodiscard]] ImageViewId FindColorBuffer(size_t index, bool is_clear);
|
||||
[[nodiscard]] ImageViewId FindColorBuffer(size_t index);
|
||||
|
||||
/// Find or create an image view for the depth buffer
|
||||
[[nodiscard]] ImageViewId FindDepthBuffer(bool is_clear);
|
||||
[[nodiscard]] ImageViewId FindDepthBuffer();
|
||||
|
||||
/// Find or create a view for a render target with the given image parameters
|
||||
[[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr,
|
||||
bool is_clear);
|
||||
[[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr);
|
||||
|
||||
/// Iterates over all the images in a region calling func
|
||||
template <typename Func>
|
||||
|
||||
@@ -562,6 +562,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits");
|
||||
cant_blit_msaa = true;
|
||||
}
|
||||
has_broken_compute =
|
||||
CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) &&
|
||||
!Settings::values.enable_compute_pipelines.GetValue();
|
||||
if (is_intel_anv || (is_qualcomm && !is_s8gen2)) {
|
||||
LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format");
|
||||
must_emulate_bgr565 = true;
|
||||
@@ -783,9 +786,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 +804,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);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
|
||||
@@ -68,7 +69,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 +80,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 +87,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) \
|
||||
@@ -528,6 +519,11 @@ public:
|
||||
return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue();
|
||||
}
|
||||
|
||||
/// @returns True if compute pipelines can cause crashing.
|
||||
bool HasBrokenCompute() const {
|
||||
return has_broken_compute;
|
||||
}
|
||||
|
||||
/// Returns true when the device does not properly support cube compatibility.
|
||||
bool HasBrokenCubeImageCompability() const {
|
||||
return has_broken_cube_compatibility;
|
||||
@@ -589,6 +585,22 @@ public:
|
||||
return supports_conditional_barriers;
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id,
|
||||
u32 driver_version) {
|
||||
if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {
|
||||
const u32 major = VK_API_VERSION_MAJOR(driver_version);
|
||||
const u32 minor = VK_API_VERSION_MINOR(driver_version);
|
||||
const u32 patch = VK_API_VERSION_PATCH(driver_version);
|
||||
if (major == 0 && minor == 405 && patch < 286) {
|
||||
LOG_WARNING(
|
||||
Render_Vulkan,
|
||||
"Intel proprietary drivers 0.405.0 until 0.405.286 have broken compute");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Checks if the physical device is suitable and configures the object state
|
||||
/// with all necessary info about its properties.
|
||||
@@ -636,7 +648,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
|
||||
@@ -683,6 +694,7 @@ private:
|
||||
bool is_integrated{}; ///< Is GPU an iGPU.
|
||||
bool is_virtual{}; ///< Is GPU a virtual GPU.
|
||||
bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device.
|
||||
bool has_broken_compute{}; ///< Compute shaders can cause crashes
|
||||
bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit
|
||||
bool has_renderdoc{}; ///< Has RenderDoc attached
|
||||
bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)},
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
|
||||
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) {
|
||||
if (record.has_broken_compute) {
|
||||
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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
61
src/yuzu/vk_device_info.cpp
Normal file
61
src/yuzu/vk_device_info.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// 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_device.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 "vulkan/vulkan_core.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 has_broken_compute_)
|
||||
: name{name_}, vsync_support{vsync_modes_}, has_broken_compute{has_broken_compute_} {}
|
||||
|
||||
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);
|
||||
|
||||
bool has_broken_compute{Vulkan::Device::CheckBrokenCompute(
|
||||
driver_properties.driverID, properties.properties.driverVersion)};
|
||||
|
||||
records.push_back(VkDeviceInfo::Record(name, present_modes, has_broken_compute));
|
||||
}
|
||||
} catch (const Vulkan::vk::Exception& exception) {
|
||||
LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what());
|
||||
}
|
||||
} // namespace VkDeviceInfo
|
||||
36
src/yuzu/vk_device_info.h
Normal file
36
src/yuzu/vk_device_info.h
Normal file
@@ -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 has_broken_compute);
|
||||
~Record();
|
||||
|
||||
const std::string name;
|
||||
const std::vector<VkPresentModeKHR> vsync_support;
|
||||
const bool has_broken_compute;
|
||||
};
|
||||
|
||||
void PopulateRecords(std::vector<Record>& records, QWindow* window);
|
||||
} // namespace VkDeviceInfo
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
|
||||
"name": "yuzu",
|
||||
"builtin-baseline": "a487471068f4cb1cbb4eeb340763cdcc0a75fd68",
|
||||
"builtin-baseline": "cbf56573a987527b39272e88cbdd11389b78c6e4",
|
||||
"version": "1.0",
|
||||
"dependencies": [
|
||||
"boost-algorithm",
|
||||
|
||||
Reference in New Issue
Block a user