Compare commits

...

3 Commits

Author SHA1 Message Date
PavelBARABANOV f61a116050 [buffer_cashe] use old logic when Optimized Vertex Buffers is disabled 2026-10-21 22:08:08 +02:00
John 989768aa46 Fix [core, gpu, threads] Multithreading refactor (#4254) (#4548)
Performance loss regression fixed in Link's Awakening, Castlevania, Super Mario RPG, etc

Tested by Mr. Knobs on Android and myself on Linux

Multicore ON may be fixed for some users using Intel CPUs.
Games include: FF Tactics, Shredder's Revenge, Unity Engine Games.

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md).
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4548
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
2026-10-19 15:58:04 +02:00
John de7e6e01d4 Revert [input_common/joycon] Enumerate SDL devices iff SDL signals change (#4486) (#4545)
Due to causing the platform windows to crash when a controller is activated.

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md).
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

Co-authored-by: Your Name <John@John.localdomain>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4545
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2026-10-18 00:17:28 +02:00
3 changed files with 87 additions and 40 deletions
@@ -57,8 +57,21 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
// Set default speed limit to 100%. // Set default speed limit to 100%.
*out_speed_scale = 1.0f; *out_speed_scale = 1.0f;
// If no layers are visible, skip the logic. Acquiring and holding buffers here would
// consume the producer's queue without ever presenting.
bool any_visible = false;
for (auto& layer : display.stack.layers) {
if (layer->visible) {
any_visible = true;
break;
}
}
if (!any_visible) {
return 1;
}
// Wait for the previous composite, bounding the number of in-flight composites.
nvdisp.WaitForComposite(); nvdisp.WaitForComposite();
this->ReleaseFramebuffersLocked(display);
// Determine the number of vsync periods to wait before composing again. // Determine the number of vsync periods to wait before composing again.
std::optional<s32> swap_interval{}; std::optional<s32> swap_interval{};
@@ -152,6 +165,13 @@ u32 HardwareComposer::ComposeLocked(f32* out_speed_scale, Display& display,
// Advance by 1 frame (60 FPS compositing) // Advance by 1 frame (60 FPS compositing)
m_frame_number += 1; m_frame_number += 1;
// Release framebuffers once the frame has been handed to the compositor. This happens
// within the same vsync period as the acquire (release_frame_number is checked against
// the advanced counter), so the producer gets its buffers back immediately instead of
// losing a queue slot for a whole frame.
// TODO: support release fences; releasing before the composite has finished can tear.
this->ReleaseFramebuffersLocked(display);
return 1; return 1;
} }
+11 -12
View File
@@ -83,21 +83,20 @@ void Joycons::ScanThread(std::stop_token stop_token) {
constexpr u16 nintendo_vendor_id = 0x057e; constexpr u16 nintendo_vendor_id = 0x057e;
Common::SetCurrentThreadName("JoyconScanThread"); Common::SetCurrentThreadName("JoyconScanThread");
auto last_ret = 0u;
do { do {
auto ret = SDL_hid_device_change_count(); SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0);
if (last_ret == 0u || last_ret != ret) { SDL_hid_device_info* cur_dev = devs;
last_ret = ret;
SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0); while (cur_dev) {
for (auto* cur_dev = devs; cur_dev; cur_dev = cur_dev->next) { if (IsDeviceNew(cur_dev)) {
if (IsDeviceNew(cur_dev)) { LOG_DEBUG(Input, "Device Found,type : {:04X} {:04X}", cur_dev->vendor_id,
LOG_DEBUG(Input, "Device Found,type : {:04X} {:04X}", cur_dev->vendor_id, cur_dev->product_id); cur_dev->product_id);
RegisterNewDevice(cur_dev); RegisterNewDevice(cur_dev);
}
cur_dev = cur_dev->next;
} }
SDL_hid_free_enumeration(devs); cur_dev = cur_dev->next;
} }
SDL_hid_free_enumeration(devs);
} while (Common::StoppableTimedWait(stop_token, std::chrono::seconds{5})); } while (Common::StoppableTimedWait(stop_token, std::chrono::seconds{5}));
} }
+55 -27
View File
@@ -1738,36 +1738,64 @@ void BufferCache<P>::TouchBuffer(Buffer& buffer, BufferId buffer_id) noexcept {
template <class P> template <class P>
bool BufferCache<P>::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size) { bool BufferCache<P>::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size) {
upload_copies.clear(); #ifdef __ANDROID__
u64 total_size_bytes = 0; const bool use_optimized_vertex_buffers = Settings::values.use_optimized_vertex_buffers.GetValue();
u64 largest_copy = 0; #else
const DAddr buffer_start = buffer.cpu_addr_cached; constexpr bool use_optimized_vertex_buffers = true;
const auto add_upload = [&](DAddr start, DAddr end) { #endif
if (start == end) return;
const u64 range_size = end - start; if (use_optimized_vertex_buffers) {
upload_copies.push_back(BufferCopy{ upload_copies.clear();
.src_offset = total_size_bytes, u64 total_size_bytes = 0;
.dst_offset = start - buffer_start, u64 largest_copy = 0;
.size = range_size, 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;
upload_copies.push_back(BufferCopy{
.src_offset = total_size_bytes,
.dst_offset = start - 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);
}); });
total_size_bytes += range_size; if (total_size_bytes == 0) {
largest_copy = (std::max)(largest_copy, range_size); return true;
}; }
memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) { const std::span<BufferCopy> copies_span(upload_copies.data(), upload_copies.size());
DAddr upload_start = device_addr_out; UploadMemory(buffer, total_size_bytes, largest_copy, copies_span);
gpu_modified_ranges.ForEachInRange(device_addr_out, range_size, [&](DAddr gpu_start, DAddr gpu_end) { any_buffer_uploaded = true;
add_upload(upload_start, gpu_start); return false;
upload_start = gpu_end; } else {
boost::container::small_vector<BufferCopy, 4> copies;
u64 total_size_bytes = 0;
u64 largest_copy = 0;
DAddr buffer_start = buffer.CpuAddr();
memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) {
copies.push_back(BufferCopy{
.src_offset = total_size_bytes,
.dst_offset = device_addr_out - buffer_start,
.size = range_size,
});
total_size_bytes += range_size;
largest_copy = (std::max)(largest_copy, range_size);
}); });
add_upload(upload_start, device_addr_out + range_size); if (total_size_bytes == 0) {
}); return true;
if (total_size_bytes == 0) { }
return true; const std::span<BufferCopy> copies_span(copies.data(), copies.size());
UploadMemory(buffer, total_size_bytes, largest_copy, copies_span);
return false;
} }
const std::span<BufferCopy> copies_span(upload_copies.data(), upload_copies.size());
UploadMemory(buffer, total_size_bytes, largest_copy, copies_span);
any_buffer_uploaded = true;
return false;
} }
template <class P> template <class P>