mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-04 13:24:19 +00:00
Adjustments on the plain data for vertex buffer optimization
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
@@ -919,46 +920,46 @@ void BufferCache<P>::BindHostVertexBuffers() {
|
|||||||
|
|
||||||
if (use_optimized_vertex_buffers) {
|
if (use_optimized_vertex_buffers) {
|
||||||
auto& flags = maxwell3d->dirty.flags;
|
auto& flags = maxwell3d->dirty.flags;
|
||||||
u32 enabled_mask = enabled_vertex_buffers_mask;
|
const u32 enabled_mask = enabled_vertex_buffers_mask;
|
||||||
HostBindings<Buffer> bindings{};
|
bool any_dirty = false;
|
||||||
u32 last_index = (std::numeric_limits<u32>::max)();
|
u32 pending_mask = enabled_mask;
|
||||||
const auto flush_bindings = [&]() {
|
while (pending_mask != 0) {
|
||||||
if (bindings.buffers.empty()) {
|
const u32 index = std::countr_zero(pending_mask);
|
||||||
return;
|
pending_mask &= (pending_mask - 1);
|
||||||
}
|
|
||||||
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);
|
const Binding& binding = VertexBufferSlot(index);
|
||||||
Buffer& buffer = slot_buffers[binding.buffer_id];
|
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||||
TouchBuffer(buffer, binding.buffer_id);
|
TouchBuffer(buffer, binding.buffer_id);
|
||||||
SynchronizeBuffer(buffer, binding.device_addr, binding.size);
|
SynchronizeBuffer(buffer, binding.device_addr, binding.size);
|
||||||
if (!flags[Dirty::VertexBuffer0 + index]) {
|
any_dirty |= flags[Dirty::VertexBuffer0 + index];
|
||||||
flush_bindings();
|
}
|
||||||
continue;
|
if (enabled_mask == 0 || !any_dirty) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
const u32 min_index = static_cast<u32>(std::countr_zero(enabled_mask));
|
||||||
|
const u32 max_index = 32u - static_cast<u32>(std::countl_zero(enabled_mask));
|
||||||
|
HostBindings<Buffer> bindings{};
|
||||||
|
bindings.min_index = min_index;
|
||||||
|
bindings.max_index = max_index;
|
||||||
|
for (u32 index = min_index; index < max_index; ++index) {
|
||||||
flags[Dirty::VertexBuffer0 + index] = false;
|
flags[Dirty::VertexBuffer0 + index] = false;
|
||||||
const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
|
const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
|
||||||
|
if ((enabled_mask & (1u << index)) == 0) {
|
||||||
|
bindings.buffers.push_back(&slot_buffers[NULL_BUFFER_ID]);
|
||||||
|
bindings.offsets.push_back(0);
|
||||||
|
bindings.sizes.push_back(0);
|
||||||
|
bindings.strides.push_back(stride);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const Binding& binding = VertexBufferSlot(index);
|
||||||
|
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||||
const u32 offset = buffer.Offset(binding.device_addr);
|
const u32 offset = buffer.Offset(binding.device_addr);
|
||||||
buffer.MarkUsage(offset, binding.size);
|
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.buffers.push_back(&buffer);
|
||||||
bindings.offsets.push_back(offset);
|
bindings.offsets.push_back(offset);
|
||||||
bindings.sizes.push_back(binding.size);
|
bindings.sizes.push_back(binding.size);
|
||||||
bindings.strides.push_back(stride);
|
bindings.strides.push_back(stride);
|
||||||
last_index = index;
|
|
||||||
}
|
}
|
||||||
flush_bindings();
|
runtime.BindVertexBuffers(bindings);
|
||||||
} else {
|
} else {
|
||||||
HostBindings<typename P::Buffer> host_bindings;
|
HostBindings<typename P::Buffer> host_bindings;
|
||||||
bool any_valid{false};
|
bool any_valid{false};
|
||||||
|
|||||||
Reference in New Issue
Block a user