mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-24 02:31:31 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ec56438ace | |||
| 727150d446 | |||
| 503573e896 | |||
| 1f826f2218 | |||
| b100b47a2d | |||
| 27dfa6037a | |||
| f527acaf9f | |||
| 0cbc36be58 | |||
| 11ae6496f3 | |||
| c8db621706 | |||
| 0830ca147f | |||
| 7722ad07c7 | |||
| 5b7cdef141 | |||
| 39ebab267b | |||
| cb73a4dcc7 |
+3
-15
@@ -24,20 +24,8 @@ include(CMakeDependentOption)
|
||||
include(CTest)
|
||||
include(CPMUtil)
|
||||
|
||||
if (NOT DEFINED ARCHITECTURE)
|
||||
message(FATAL_ERROR "Architecture didn't make it out of scope, did you delete DetectArchitecture.cmake?")
|
||||
endif()
|
||||
|
||||
# Needed for FFmpeg w/ VAAPI and DRM
|
||||
if (OPENBSD)
|
||||
# OpenBSD 7.8 broke libcxx when upgrading, so we must define the PSTL backend manually
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R6/lib")
|
||||
elseif (NETBSD)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R7/lib")
|
||||
if (CXX_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14.0")
|
||||
message(FATAL_ERROR "GCC versions older than 14.0 are not supported. Update your system, or use clang/clang++ instead.")
|
||||
endif()
|
||||
|
||||
# NetBSD: Fun for the whole family!
|
||||
@@ -618,7 +606,7 @@ if (ENABLE_QT)
|
||||
|
||||
# Best practice is to ask for all components at once, so they are from the same version
|
||||
set(YUZU_QT_COMPONENTS Core Widgets Charts Concurrent Gui)
|
||||
if (LINUX OR FREEBSD)
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
list(APPEND YUZU_QT_COMPONENTS DBus)
|
||||
# yes Qt, we get it
|
||||
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
||||
|
||||
+4
-6
@@ -147,15 +147,13 @@ System provides a default `g++-10` which doesn't support the current C++ codebas
|
||||
|
||||
Make may error out when generating C++ headers of SPIRV shaders, hence it's recommended to use `gmake` over the default system one.
|
||||
|
||||
[parallel/spirv-tools](https://iso.us.netbsd.org/pub/pkgsrc/current/pkgsrc/parallel/spirv-tools/index.html) isn't available in binary form and must be built from source.
|
||||
|
||||
glslang is not available on NetBSD, to circumvent this simply build glslang by yourself:
|
||||
If [parallel/spirv-tools](https://iso.us.netbsd.org/pub/pkgsrc/current/pkgsrc/parallel/spirv-tools/index.html) isn't available in binary, build from source:
|
||||
|
||||
```sh
|
||||
pkgin python313
|
||||
pkgin install python314
|
||||
git clone --depth=1 https://github.com/KhronosGroup/glslang.git
|
||||
cd glslang
|
||||
python3.13 ./update_glslang_sources.py
|
||||
python3.14 ./update_glslang_sources.py
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build -- -j`nproc`
|
||||
cmake --install build
|
||||
@@ -163,7 +161,7 @@ cmake --install build
|
||||
|
||||
However, pkgsrc is highly recommended, see [getting pkgsrc](https://iso.us.netbsd.org/pub/pkgsrc/current/pkgsrc/doc/pkgsrc.html#getting). You must get `current` not the `2025Q2` version.
|
||||
|
||||
`QtCore` on NetBSD is included, but due to misconfigurations(!) we MUST include one of the standard headers that include `bits/c++config.h`, since source_location (required by `QtCore`) isn't properly configured to intake `bits/c++config.h` (none of the experimental library is). This is a bug with NetBSD packaging and not our fault, but alas.
|
||||
`QtCore` on NetBSD is included, but due to misconfigurations you must include `bits/c++config.h`, since source_location (required by `QtCore`) isn't properly configured to intake `bits/c++config.h` (none of the experimental library is).
|
||||
|
||||
## DragonFlyBSD
|
||||
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ First, enable the community repository; [see here](https://wiki.alpinelinux.org/
|
||||
# Enable the community repository
|
||||
setup-apkrepos -c
|
||||
# Install
|
||||
apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev qt6-charts-dev libusb-dev libtool boost-dev sdl3-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev jq patch
|
||||
apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev qt6-qtcharts-dev libusb-dev boost-dev sdl3-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev enet-dev glslang libtool jq patch
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
@@ -67,9 +67,7 @@
|
||||
#else
|
||||
# define CTX_SP (_UC_MACHINE_SP(ucontext))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ARCHITECTURE_arm64)
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
# if defined(__APPLE__)
|
||||
# define CTX_PC (mctx->__ss.__pc)
|
||||
# define CTX_SP (mctx->__ss.__sp)
|
||||
|
||||
@@ -92,7 +92,7 @@ if (ENABLE_OPENGL)
|
||||
target_compile_definitions(qt_common PUBLIC HAS_OPENGL)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
if (UNIX AND NOT APPLE AND NOT NETBSD)
|
||||
if (DEFINED Qt6Gui_PRIVATE_INCLUDE_DIRS)
|
||||
target_include_directories(qt_common PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
else()
|
||||
|
||||
@@ -121,7 +121,7 @@ void BufferCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t size
|
||||
|
||||
template <class P>
|
||||
void BufferCache<P>::WriteMemory(DAddr device_addr, u64 size) {
|
||||
if (IsRegionGpuModified(device_addr, size)) {
|
||||
if (memory_tracker.IsRegionGpuModified(device_addr, size)) {
|
||||
ClearDownload(device_addr, size);
|
||||
gpu_modified_ranges.Subtract(device_addr, size);
|
||||
}
|
||||
@@ -311,8 +311,11 @@ std::pair<typename P::Buffer*, u32> BufferCache<P>::ObtainCPUBuffer(
|
||||
MarkWrittenBuffer(buffer_id, device_addr, size);
|
||||
break;
|
||||
case ObtainBufferOperation::DiscardWrite: {
|
||||
ClearDownload(device_addr, size);
|
||||
gpu_modified_ranges.Subtract(device_addr, size);
|
||||
const DAddr device_addr_start = Common::AlignDown(device_addr, 64);
|
||||
const DAddr device_addr_end = Common::AlignUp(device_addr + size, 64);
|
||||
const size_t new_size = device_addr_end - device_addr_start;
|
||||
ClearDownload(device_addr_start, new_size);
|
||||
gpu_modified_ranges.Subtract(device_addr_start, new_size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1739,24 +1742,14 @@ bool BufferCache<P>::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 si
|
||||
u64 total_size_bytes = 0;
|
||||
u64 largest_copy = 0;
|
||||
const DAddr buffer_start = buffer.cpu_addr_cached;
|
||||
const auto add_upload = [&](DAddr start, DAddr end) {
|
||||
if (start == end) return;
|
||||
const u64 range_size = end - start;
|
||||
memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) {
|
||||
upload_copies.push_back(BufferCopy{
|
||||
.src_offset = total_size_bytes,
|
||||
.dst_offset = start - buffer_start,
|
||||
.dst_offset = device_addr_out - buffer_start,
|
||||
.size = range_size,
|
||||
});
|
||||
total_size_bytes += range_size;
|
||||
largest_copy = (std::max)(largest_copy, range_size);
|
||||
};
|
||||
memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) {
|
||||
DAddr upload_start = device_addr_out;
|
||||
gpu_modified_ranges.ForEachInRange(device_addr_out, range_size, [&](DAddr gpu_start, DAddr gpu_end) {
|
||||
add_upload(upload_start, gpu_start);
|
||||
upload_start = gpu_end;
|
||||
});
|
||||
add_upload(upload_start, device_addr_out + range_size);
|
||||
});
|
||||
if (total_size_bytes == 0) {
|
||||
return true;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
namespace Tegra {
|
||||
|
||||
constexpr u32 MacroRegistersStart = 0xE00;
|
||||
constexpr u32 ComputeInline = 0x6D;
|
||||
[[maybe_unused]] constexpr u32 ComputeInline = 0x6D;
|
||||
|
||||
DmaPusher::DmaPusher(Core::System& system_, MemoryManager& memory_manager_, Control::ChannelState& channel_state_)
|
||||
: system{system_}
|
||||
@@ -73,16 +73,11 @@ bool DmaPusher::Step() {
|
||||
synced = false;
|
||||
}
|
||||
|
||||
if (header.size > 0 && dma_state.method >= MacroRegistersStart && subchannels[dma_state.subchannel]) {
|
||||
subchannels[dma_state.subchannel]->current_dirty = memory_manager.IsMemoryDirty(dma_state.dma_get, header.size * sizeof(u32));
|
||||
}
|
||||
|
||||
if (header.size > 0) {
|
||||
if (subchannels[dma_state.subchannel] && dma_state.method_count) {
|
||||
const auto engine = subchannel_type[dma_state.subchannel];
|
||||
const bool kepler_payload = engine == Engines::EngineTypes::KeplerCompute && dma_state.method == ComputeInline && dma_state.non_incrementing;
|
||||
const bool macro_payload = engine == Engines::EngineTypes::Maxwell3D && dma_state.method >= MacroRegistersStart;
|
||||
if (kepler_payload || macro_payload) {
|
||||
const size_t words = std::min<size_t>(dma_state.method_count, header.size);
|
||||
subchannels[dma_state.subchannel]->current_dirty = memory_manager.IsMemoryDirty(dma_state.dma_get, words * sizeof(u32));
|
||||
}
|
||||
}
|
||||
const bool use_safe = Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe();
|
||||
if (use_safe) {
|
||||
Tegra::Memory::GpuGuestMemory<Tegra::CommandHeader, Tegra::Memory::GuestMemoryFlags::SafeRead>headers(memory_manager, dma_state.dma_get, header.size, &command_headers);
|
||||
|
||||
@@ -49,16 +49,13 @@ void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argu
|
||||
case KEPLER_COMPUTE_REG_INDEX(exec_upload): {
|
||||
UploadInfo info{.upload_address = upload_address,
|
||||
.exec_address = upload_state.ExecTargetAddress(),
|
||||
.copy_size = upload_state.GetUploadSize(),
|
||||
.was_dirty = upload_dirty};
|
||||
.copy_size = upload_state.GetUploadSize()};
|
||||
uploads.push_back(info);
|
||||
upload_state.ProcessExec(regs.exec_upload.linear != 0);
|
||||
break;
|
||||
}
|
||||
case KEPLER_COMPUTE_REG_INDEX(data_upload): {
|
||||
upload_address = current_dma_segment;
|
||||
upload_dirty = current_dirty;
|
||||
current_dirty = false;
|
||||
upload_state.ProcessData(method_argument, is_last_call);
|
||||
break;
|
||||
}
|
||||
@@ -67,11 +64,9 @@ void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argu
|
||||
|
||||
for (auto& data : uploads) {
|
||||
const GPUVAddr offset = data.exec_address - launch_desc_loc;
|
||||
if (offset / sizeof(u32) == LAUNCH_REG_INDEX(grid_dim_x)) {
|
||||
const bool source_dirty = memory_manager.IsMemoryDirty(data.upload_address, data.copy_size);
|
||||
if (data.was_dirty || source_dirty) {
|
||||
indirect_compute = {data.upload_address};
|
||||
}
|
||||
if (offset / sizeof(u32) == LAUNCH_REG_INDEX(grid_dim_x) &&
|
||||
memory_manager.IsMemoryDirty(data.upload_address, data.copy_size)) {
|
||||
indirect_compute = {data.upload_address};
|
||||
}
|
||||
}
|
||||
uploads.clear();
|
||||
@@ -88,8 +83,6 @@ void KeplerCompute::CallMultiMethod(Core::System& system, u32 method, const u32*
|
||||
switch (method) {
|
||||
case KEPLER_COMPUTE_REG_INDEX(data_upload):
|
||||
upload_address = current_dma_segment;
|
||||
upload_dirty = current_dirty;
|
||||
current_dirty = false;
|
||||
upload_state.ProcessData(base_start, amount);
|
||||
return;
|
||||
default:
|
||||
|
||||
@@ -226,13 +226,11 @@ private:
|
||||
VideoCore::RasterizerInterface* rasterizer = nullptr;
|
||||
Upload::State upload_state;
|
||||
GPUVAddr upload_address;
|
||||
bool upload_dirty{};
|
||||
|
||||
struct UploadInfo {
|
||||
GPUVAddr upload_address;
|
||||
GPUVAddr exec_address;
|
||||
u32 copy_size;
|
||||
bool was_dirty;
|
||||
};
|
||||
std::vector<UploadInfo> uploads;
|
||||
std::optional<GPUVAddr> indirect_compute{};
|
||||
|
||||
@@ -98,7 +98,10 @@ void Layer::ConfigureDraw(const Device& device, PresentPushConstants* out_push_c
|
||||
RefreshResources(device, framebuffer);
|
||||
SetAntiAliasPass(device);
|
||||
#ifdef HAS_RESHADE
|
||||
SetPostProcessPass(device);
|
||||
const bool is_applet =
|
||||
(framebuffer.layer_stack_mask & Service::Nvnflinger::LayerStackBit(
|
||||
Service::Nvnflinger::LayerStackId::Recording)) == 0;
|
||||
SetPostProcessPass(device, is_applet);
|
||||
#endif
|
||||
|
||||
// Finish any pending renderpass
|
||||
@@ -228,7 +231,11 @@ void Layer::SetAntiAliasPass(const Device& device) {
|
||||
}
|
||||
|
||||
#ifdef HAS_RESHADE
|
||||
void Layer::SetPostProcessPass(const Device& device) {
|
||||
void Layer::SetPostProcessPass(const Device& device, bool is_applet) {
|
||||
if (is_applet) {
|
||||
post_process.reset();
|
||||
return;
|
||||
}
|
||||
const VkExtent2D render_area{
|
||||
.width = Settings::values.resolution_info.ScaleUp(raw_width),
|
||||
.height = Settings::values.resolution_info.ScaleUp(raw_height),
|
||||
|
||||
@@ -70,7 +70,7 @@ private:
|
||||
void RefreshResources(const Device& device, const Tegra::FramebufferConfig& framebuffer);
|
||||
void SetAntiAliasPass(const Device& device);
|
||||
#ifdef HAS_RESHADE
|
||||
void SetPostProcessPass(const Device& device);
|
||||
void SetPostProcessPass(const Device& device, bool is_applet);
|
||||
#endif
|
||||
void ReleaseRawImages();
|
||||
|
||||
|
||||
@@ -43,26 +43,32 @@ namespace {
|
||||
switch (window_type) {
|
||||
case Core::Frontend::WindowSystemType::Headless:
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
case Core::Frontend::WindowSystemType::Windows:
|
||||
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(__APPLE__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
case Core::Frontend::WindowSystemType::Cocoa:
|
||||
extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(__ANDROID__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
case Core::Frontend::WindowSystemType::Android:
|
||||
extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(__HAIKU__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
case Core::Frontend::WindowSystemType::Xcb:
|
||||
extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#else
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
case Core::Frontend::WindowSystemType::X11:
|
||||
extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
case Core::Frontend::WindowSystemType::Wayland:
|
||||
extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "video_core/vulkan_common/vulkan_surface.h"
|
||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
#include "video_core/vulkan_common/vulkan.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
@@ -17,7 +18,7 @@ vk::SurfaceKHR CreateSurface(
|
||||
[[maybe_unused]] const vk::InstanceDispatch& dld = instance.Dispatch();
|
||||
VkSurfaceKHR unsafe_surface = VkSurfaceKHR{};
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Windows) {
|
||||
const HWND hWnd = static_cast<HWND>(window_info.render_surface);
|
||||
const VkWin32SurfaceCreateInfoKHR win32_ci{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
|
||||
@@ -30,7 +31,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Cocoa) {
|
||||
const VkMetalSurfaceCreateInfoEXT metal_ci = {
|
||||
.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
|
||||
@@ -45,7 +47,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#elif defined(__ANDROID__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Android) {
|
||||
const VkAndroidSurfaceCreateInfoKHR android_ci{
|
||||
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||
@@ -59,7 +62,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#elif defined(__HAIKU__)
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Xcb) {
|
||||
const VkXcbSurfaceCreateInfoKHR xcb_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
|
||||
@@ -76,7 +80,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::X11) {
|
||||
const VkXlibSurfaceCreateInfoKHR xlib_ci{
|
||||
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||
@@ -90,6 +95,8 @@ vk::SurfaceKHR CreateSurface(
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Wayland) {
|
||||
const VkWaylandSurfaceCreateInfoKHR wayland_ci{
|
||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||
@@ -105,7 +112,6 @@ vk::SurfaceKHR CreateSurface(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!unsafe_surface) {
|
||||
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");
|
||||
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||
|
||||
Reference in New Issue
Block a user