graphics: draw indexed indirect multi-draws from GPU-read arguments

This commit is contained in:
nmzik
2026-10-22 14:01:25 +02:00
parent c513a4a13a
commit 949de19bb0
5 changed files with 48 additions and 32 deletions
+6 -6
View File
@@ -886,7 +886,8 @@ void CommandProcessor::DrawIndirectMulti(uint32_t data_offset, uint32_t max_coun
EXIT_NOT_IMPLEMENTED((draw_initiator & ~0x20u) != (indexed ? 0u : 2u));
EXIT_NOT_IMPLEMENTED(m_draw_indirect_args_base_addr == 0);
// The guest records match Vulkan's indirect commands byte for byte.
EXIT_NOT_IMPLEMENTED(stride_in_bytes < (indexed ? sizeof(vk::DrawIndexedIndirectCommand)
EXIT_NOT_IMPLEMENTED((stride_in_bytes & 3u) != 0 ||
stride_in_bytes < (indexed ? sizeof(vk::DrawIndexedIndirectCommand)
: sizeof(vk::DrawIndirectCommand)));
const auto draw_count = count_addr == nullptr
@@ -902,15 +903,14 @@ void CommandProcessor::DrawIndirectMulti(uint32_t data_offset, uint32_t max_coun
// NUM_INSTANCES keeps the last draw's instance count.
m_num_instances_addr = args_addr + static_cast<uint64_t>(draw_count - 1) * stride_in_bytes +
offsetof(vk::DrawIndirectCommand, instanceCount);
// With no SGPRs to patch, the GPU reads a single indexed draw's arguments if the shaders allow.
if (indexed && draw_count == 1 && m_index_buffer_size != 0 &&
registers.vertex_offset == Pm4::SH_NOP && registers.instance_offset == Pm4::SH_NOP &&
registers.index_offset == Pm4::SH_NOP &&
// With no SGPRs to patch, the GPU reads indexed draws' arguments if the shaders allow.
if (indexed && m_index_buffer_size != 0 && registers.vertex_offset == Pm4::SH_NOP &&
registers.instance_offset == Pm4::SH_NOP && registers.index_offset == Pm4::SH_NOP &&
executor.DrawIndex(m_submit_id, CurrentBuffer(),
{.index_count = m_index_buffer_size,
.index_addr = IndexAddress(0),
.index_type_and_size = m_index_type_and_size,
.indirect_args = args_addr})) {
.indirect = {args_addr, draw_count, stride_in_bytes}})) {
return;
}