aboutsummaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorPavelBARABANOV <pavelbarabanov94@gmail.com>2026-02-24 18:49:44 +0100
committercrueter <crueter@eden-emu.dev>2026-02-24 18:49:44 +0100
commitd2bef2731cea600c49f1dfc6f0f34b81bc49c511 (patch)
tree2b87ae3b4402c4593a65214bc53b337c55d2718e /src/video_core
parentb45c78a051264aa17b44ed6b8f0c816d747f3717 (diff)
[android, tu] Adjusted PoD of Vertex/ Buffers for older turnip drivers (#3621)
This PR aims to return an older way to bind and host vertex/ buffers (via toggle), which had a bunch of indirection and added unnecessary overhead during the drawing phase; current new approach adds just PoD for this operations, which seems to not be acceptable for older turnip drivers. Meanwhile the performance improvements are gonna be enabled only if the toggle is turned on, it will be required to use newer turnip drivers to make it work (26.0+), default behavior will allow older drivers work as intended. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3621 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com> Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h121
1 files changed, 84 insertions, 37 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 7b92edecaa..014b4a318e 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -805,47 +805,94 @@ void BufferCache<P>::UpdateVertexBufferSlot(u32 index, const Binding& binding) {
template <class P>
void BufferCache<P>::BindHostVertexBuffers() {
- auto& flags = maxwell3d->dirty.flags;
- u32 enabled_mask = enabled_vertex_buffers_mask;
- HostBindings<Buffer> bindings{};
- u32 last_index = std::numeric_limits<u32>::max();
- const auto flush_bindings = [&]() {
- if (bindings.buffers.empty()) {
- return;
- }
- bindings.max_index = bindings.min_index + static_cast<u32>(bindings.buffers.size());
- runtime.BindVertexBuffers(bindings);
- bindings = HostBindings<Buffer>{};
- last_index = std::numeric_limits<u32>::max();
- };
- while (enabled_mask != 0) {
- const u32 index = std::countr_zero(enabled_mask);
- enabled_mask &= (enabled_mask - 1);
- const Binding& binding = VertexBufferSlot(index);
- Buffer& buffer = slot_buffers[binding.buffer_id];
- TouchBuffer(buffer, binding.buffer_id);
- SynchronizeBuffer(buffer, binding.device_addr, binding.size);
- if (!flags[Dirty::VertexBuffer0 + index]) {
- flush_bindings();
- continue;
+
+#ifdef ANDROID
+ const bool use_optimized_vertex_buffers = Settings::values.use_optimized_vertex_buffers.GetValue();
+#else
+ constexpr bool use_optimized_vertex_buffers = true;
+#endif
+
+ if (use_optimized_vertex_buffers) {
+ auto& flags = maxwell3d->dirty.flags;
+ u32 enabled_mask = enabled_vertex_buffers_mask;
+ HostBindings<Buffer> bindings{};
+ u32 last_index = std::numeric_limits<u32>::max();
+ const auto flush_bindings = [&]() {
+ if (bindings.buffers.empty()) {
+ return;
+ }
+ bindings.max_index = bindings.min_index + static_cast<u32>(bindings.buffers.size());
+ runtime.BindVertexBuffers(bindings);
+ bindings = HostBindings<Buffer>{};
+ last_index = std::numeric_limits<u32>::max();
+ };
+ while (enabled_mask != 0) {
+ const u32 index = std::countr_zero(enabled_mask);
+ enabled_mask &= (enabled_mask - 1);
+ const Binding& binding = VertexBufferSlot(index);
+ Buffer& buffer = slot_buffers[binding.buffer_id];
+ TouchBuffer(buffer, binding.buffer_id);
+ SynchronizeBuffer(buffer, binding.device_addr, binding.size);
+ if (!flags[Dirty::VertexBuffer0 + index]) {
+ flush_bindings();
+ continue;
+ }
+ flags[Dirty::VertexBuffer0 + index] = false;
+ const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
+ const u32 offset = buffer.Offset(binding.device_addr);
+ buffer.MarkUsage(offset, binding.size);
+ if (!bindings.buffers.empty() && index != last_index + 1) {
+ flush_bindings();
+ }
+ if (bindings.buffers.empty()) {
+ bindings.min_index = index;
+ }
+ bindings.buffers.push_back(&buffer);
+ bindings.offsets.push_back(offset);
+ bindings.sizes.push_back(binding.size);
+ bindings.strides.push_back(stride);
+ last_index = index;
}
- flags[Dirty::VertexBuffer0 + index] = false;
- const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
- const u32 offset = buffer.Offset(binding.device_addr);
- buffer.MarkUsage(offset, binding.size);
- if (!bindings.buffers.empty() && index != last_index + 1) {
- flush_bindings();
+ flush_bindings();
+ } else {
+ HostBindings<typename P::Buffer> host_bindings;
+ 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.device_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;
}
- if (bindings.buffers.empty()) {
- bindings.min_index = index;
+
+ if (any_valid) {
+ host_bindings.max_index++;
+ for (u32 index = host_bindings.min_index; index < host_bindings.max_index; index++) {
+ flags[Dirty::VertexBuffer0 + index] = false;
+
+ const Binding& binding = channel_state->vertex_buffers[index];
+ Buffer& buffer = slot_buffers[binding.buffer_id];
+
+ const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
+ const u32 offset = buffer.Offset(binding.device_addr);
+ buffer.MarkUsage(offset, binding.size);
+
+ host_bindings.buffers.push_back(&buffer);
+ host_bindings.offsets.push_back(offset);
+ host_bindings.sizes.push_back(binding.size);
+ host_bindings.strides.push_back(stride);
+ }
+ runtime.BindVertexBuffers(host_bindings);
}
- bindings.buffers.push_back(&buffer);
- bindings.offsets.push_back(offset);
- bindings.sizes.push_back(binding.size);
- bindings.strides.push_back(stride);
- last_index = index;
}
- flush_bindings();
}
template <class P>