mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-06 14:09:58 +00:00
Port UMA part 4.1
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user