fast_gpu_time{linkage,
GpuOverclock::Medium,
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::UpdateVertexBufferSlot(u32 index, const Binding& binding) {
template
void BufferCache::BindHostVertexBuffers() {
- auto& flags = maxwell3d->dirty.flags;
- u32 enabled_mask = enabled_vertex_buffers_mask;
- HostBindings bindings{};
- u32 last_index = std::numeric_limits::max();
- const auto flush_bindings = [&]() {
- if (bindings.buffers.empty()) {
- return;
- }
- bindings.max_index = bindings.min_index + static_cast(bindings.buffers.size());
- runtime.BindVertexBuffers(bindings);
- bindings = HostBindings{};
- last_index = std::numeric_limits::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 bindings{};
+ u32 last_index = std::numeric_limits::max();
+ const auto flush_bindings = [&]() {
+ if (bindings.buffers.empty()) {
+ return;
+ }
+ bindings.max_index = bindings.min_index + static_cast(bindings.buffers.size());
+ runtime.BindVertexBuffers(bindings);
+ bindings = HostBindings{};
+ last_index = std::numeric_limits::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 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