Port UMA part 4.1

This commit is contained in:
CamilleLaVey
2026-10-01 12:23:20 -04:00
parent 488dcefec5
commit 1b764efad9
3 changed files with 69 additions and 0 deletions
@@ -802,6 +802,21 @@ void BufferCache<P>::BindHostIndexBuffer() {
const u32 offset = buffer.Offset(channel_state->index_buffer.device_addr);
const u32 size = channel_state->index_buffer.size;
const auto& draw_state = maxwell3d->draw_manager.draw_state;
if constexpr (!HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
if (draw_state.topology == Maxwell::PrimitiveTopology::Quads ||
draw_state.topology == Maxwell::PrimitiveTopology::QuadStrip) {
const DAddr device_addr = channel_state->index_buffer.device_addr;
std::span<const u8> indices = draw_state.inline_index_draw_indexes;
if (indices.empty() && !IsRegionGpuModified(device_addr, size)) {
indices = ImmediateBufferWithData(device_addr, size);
}
if (runtime.BindQuadIndices(draw_state.topology, draw_state.index_buffer.format,
draw_state.index_buffer.first,
draw_state.index_buffer.count, indices)) {
return;
}
}
}
if (draw_state.inline_index_draw_indexes.empty()) {
SynchronizeBuffer(buffer, channel_state->index_buffer.device_addr, size);
} else if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) {
@@ -677,6 +677,57 @@ void BufferCacheRuntime::BindQuadIndexBuffer(PrimitiveTopology topology, u32 fir
}
}
bool BufferCacheRuntime::BindQuadIndices(PrimitiveTopology topology, IndexFormat index_format,
u32 base_vertex, u32 num_indices,
std::span<const u8> indices) {
const size_t index_size = size_t{1} << static_cast<u32>(index_format);
if (indices.size() < num_indices * index_size) {
return false;
}
u32 quads = num_indices / 4;
u32 stride = 4;
std::array<u32, 6> swizzle{0, 1, 2, 0, 2, 3};
if (topology == PrimitiveTopology::QuadStrip) {
quads = 0;
if (num_indices >= 2) {
quads = (num_indices - 2) / 2;
}
stride = 2;
swizzle = {0, 3, 1, 0, 2, 3};
}
const size_t size = (std::max)(quads, 1U) * sizeof(swizzle);
const StagingBufferRef staging = staging_pool.Request(size, MemoryUsage::Upload);
const auto convert = [&](auto index_type) {
u8* output = staging.mapped_span.data();
for (u32 quad = 0; quad < quads; ++quad) {
std::array<u32, 6> triangles;
for (size_t vertex = 0; vertex < triangles.size(); ++vertex) {
decltype(index_type) index;
std::memcpy(&index,
indices.data() + (quad * stride + swizzle[vertex]) * sizeof(index),
sizeof(index));
triangles[vertex] = index + base_vertex;
}
std::memcpy(output, triangles.data(), sizeof(triangles));
output += sizeof(triangles);
}
};
switch (index_format) {
case IndexFormat::UnsignedByte:
convert(u8{});
break;
case IndexFormat::UnsignedShort:
convert(u16{});
break;
case IndexFormat::UnsignedInt:
convert(u32{});
break;
}
BindIndexBuffer(PrimitiveTopology::Triangles, IndexFormat::UnsignedInt, 0, 0, staging.buffer,
static_cast<u32>(staging.offset), static_cast<u32>(size));
return true;
}
void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size, u32 stride) {
if (index >= device.GetMaxVertexInputBindings()) {
return;
@@ -178,6 +178,9 @@ public:
void BindQuadIndexBuffer(PrimitiveTopology topology, u32 first, u32 count);
bool BindQuadIndices(PrimitiveTopology topology, IndexFormat index_format, u32 base_vertex,
u32 num_indices, std::span<const u8> indices);
void BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size, u32 stride);
void BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bindings);