diff --git a/src/graphics/guest_gpu/command_processor/commandProcessor.h b/src/graphics/guest_gpu/command_processor/commandProcessor.h index 983bd2db6..78a6de45f 100644 --- a/src/graphics/guest_gpu/command_processor/commandProcessor.h +++ b/src/graphics/guest_gpu/command_processor/commandProcessor.h @@ -73,13 +73,9 @@ public: void SetDrawIndirectArgsBaseAddress(uint64_t draw_indirect_args_base_addr); void SetDispatchIndirectArgsBaseAddress(uint64_t dispatch_indirect_args_base_addr); void SetNumInstances(uint32_t num_instances); - void DrawIndex(uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type, - uint32_t instance_count = 0, const void* object_ids = nullptr, - uint32_t render_target_slice_offset = 0, int32_t vertex_offset_add = 0, - uint32_t first_instance = 0, bool offsets_from_indirect_args = false); - void DrawIndexOffset(uint32_t index_offset, uint32_t index_count, uint32_t flags); - void DrawIndexAuto(uint32_t index_count, uint32_t flags, - uint32_t render_target_slice_offset = 0); + void DrawIndex(DrawIndexArgs args); + void DrawIndexOffset(uint32_t index_offset, uint32_t index_count); + void DrawIndexAuto(DrawAutoArgs args); void DrawIndirect(uint32_t data_offset, uint32_t draw_initiator, bool indexed); void DrawIndirectMulti(uint32_t data_offset, uint32_t max_count_or_count, const volatile uint32_t* count_addr, uint32_t stride_in_bytes, @@ -149,10 +145,6 @@ private: uint32_t interrupt_context_id); void ProcessPm4(Pm4Execution& execution, size_t stop_depth); void SuspendPm4(); - void SubmitNonIndexedDraw(uint32_t vertex_count, uint32_t flags, - uint32_t render_target_slice_offset, uint32_t first_vertex, - uint32_t first_instance, bool offsets_from_indirect_args = false); - CommandScheduler& GetScheduler() const { return m_renderer.GetCommandScheduler(); } CommandBuffer& CurrentBuffer() { return GetScheduler().Current(); } void CheckBuffer() const { GetScheduler().CheckActive(); } diff --git a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp index a15316011..552f8b0d0 100644 --- a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp +++ b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp @@ -1618,15 +1618,15 @@ KYTY_CP_OP_PARSER(CpOpDrawIndex) { auto* index_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); uint32_t max_instance_count = buffer[3]; - auto* object_ids = - reinterpret_cast(buffer[4] | (static_cast(buffer[5]) << 32u)); - uint32_t instance_count = buffer[6]; - uint32_t flags = buffer[7]; + uint32_t instance_count = buffer[6]; + uint32_t flags = buffer[7]; EXIT_NOT_IMPLEMENTED(instance_count > max_instance_count); EXIT_NOT_IMPLEMENTED((flags & ~0xa0u) != 0); - cp.DrawIndex(index_count, index_addr, 0, 1, instance_count, object_ids); + cp.DrawIndex({.index_count = index_count, + .index_addr = index_addr, + .instance_count = instance_count}); return 8; } @@ -1641,7 +1641,7 @@ KYTY_CP_OP_PARSER(CpOpDrawIndex) { EXIT_NOT_IMPLEMENTED(index_count > max_index_count); EXIT_NOT_IMPLEMENTED((flags & ~0x20u) != 0); - cp.DrawIndex(index_count, index_addr, 0, 1); + cp.DrawIndex({.index_count = index_count, .index_addr = index_addr}); return 5; } @@ -1700,7 +1700,7 @@ KYTY_CP_OP_PARSER(CpOpDrawIndexOffset) { EXIT_NOT_IMPLEMENTED(index_count > max_index_size); EXIT_NOT_IMPLEMENTED((flags & ~0x20u) != 0); - cp.DrawIndexOffset(index_offset, index_count, 0); + cp.DrawIndexOffset(index_offset, index_count); return 4; } @@ -1715,7 +1715,7 @@ KYTY_CP_OP_PARSER(CpOpDrawIndexAuto) { EXIT_NOT_IMPLEMENTED((flags & ~0x22u) != 0); - cp.DrawIndexAuto(index_count, 0); + cp.DrawIndexAuto({.vertex_count = index_count}); return 2; } diff --git a/src/graphics/guest_gpu/graphicsRun.cpp b/src/graphics/guest_gpu/graphicsRun.cpp index d57200056..a68f70905 100644 --- a/src/graphics/guest_gpu/graphicsRun.cpp +++ b/src/graphics/guest_gpu/graphicsRun.cpp @@ -40,6 +40,21 @@ static thread_local bool g_gpu_mutex_owned = false; static thread_local bool g_gpu_thread = false; static thread_local GuestGpu* g_gpu_state = nullptr; +struct DrawIndirectArgs { + uint32_t vertex_count_per_instance; + uint32_t instance_count; + uint32_t start_vertex_location; + uint32_t start_instance_location; +}; + +struct DrawIndexedIndirectArgs { + uint32_t index_count_per_instance; + uint32_t instance_count; + uint32_t start_index_location; + uint32_t base_vertex_location; + uint32_t start_instance_location; +}; + class GpuMutexLock final { public: explicit GpuMutexLock(Common::Mutex& mutex): m_mutex(mutex) { @@ -847,37 +862,21 @@ void CommandProcessor::SetPredication(uint32_t condition, uint32_t op, uint32_t } } -void CommandProcessor::DrawIndex(uint32_t index_count, const void* index_addr, uint32_t flags, - uint32_t type, uint32_t instance_count, const void* object_ids, - uint32_t render_target_slice_offset, int32_t vertex_offset_add, - uint32_t first_instance, bool offsets_from_indirect_args) { +void CommandProcessor::DrawIndex(DrawIndexArgs args) { CheckBuffer(); - if (instance_count == 0) { - instance_count = m_num_instances; + args.index_type_and_size = m_index_type_and_size; + if (args.instance_count == 0) { + args.instance_count = m_num_instances; } - if (object_ids != nullptr) { - LOGF("\t draw indexed multi-instanced objectIds = 0x%016" PRIx64 "\n", - reinterpret_cast(object_ids)); + if (args.base_vertex != 0 || args.first_instance != 0) { + LOGF("\t draw indexed offsets: base_vertex = %" PRId32 ", first_instance = %" PRIu32 "\n", + args.base_vertex, args.first_instance); } - if (render_target_slice_offset != 0) { - LOGF("\t draw render target slice offset = %" PRIu32 "\n", render_target_slice_offset); - } - if (vertex_offset_add != 0 || first_instance != 0) { - LOGF("\t draw indexed offsets: vertex_offset_add = %" PRId32 ", first_instance = %" PRIu32 - "\n", - vertex_offset_add, first_instance); - } - m_renderer.GetRenderExecutor().DrawIndex(m_submit_id, CurrentBuffer(), m_index_type_and_size, - index_count, index_addr, flags, type, instance_count, - render_target_slice_offset, vertex_offset_add, - first_instance, offsets_from_indirect_args); + m_renderer.GetRenderExecutor().DrawIndex(m_submit_id, CurrentBuffer(), args); } -void CommandProcessor::DrawIndexOffset(uint32_t index_offset, uint32_t index_count, - uint32_t flags) { - CheckBuffer(); - +void CommandProcessor::DrawIndexOffset(uint32_t index_offset, uint32_t index_count) { uint64_t index_size = 0; switch (m_index_type_and_size) { case 0: index_size = 2; break; @@ -889,25 +888,10 @@ void CommandProcessor::DrawIndexOffset(uint32_t index_offset, uint32_t index_cou auto* index_addr = reinterpret_cast( m_index_base_addr + static_cast(index_offset) * index_size); - m_renderer.GetRenderExecutor().DrawIndex(m_submit_id, CurrentBuffer(), m_index_type_and_size, - index_count, index_addr, flags, 1, m_num_instances); + DrawIndex({.index_count = index_count, .index_addr = index_addr}); } void CommandProcessor::DrawIndirect(uint32_t data_offset, uint32_t draw_initiator, bool indexed) { - struct DrawIndirectArgs { - uint32_t vertex_count_per_instance; - uint32_t instance_count; - uint32_t start_vertex_location; - uint32_t start_instance_location; - }; - struct DrawIndexedIndirectArgs { - uint32_t index_count_per_instance; - uint32_t instance_count; - uint32_t start_index_location; - uint32_t base_vertex_location; - uint32_t start_instance_location; - }; - EXIT_NOT_IMPLEMENTED((draw_initiator & ~0x20u) != 2u); EXIT_NOT_IMPLEMENTED(m_draw_indirect_args_base_addr == 0); @@ -929,8 +913,11 @@ void CommandProcessor::DrawIndirect(uint32_t data_offset, uint32_t draw_initiato } } m_num_instances = args.instance_count; - SubmitNonIndexedDraw(args.vertex_count_per_instance, 0, 0, args.start_vertex_location, - args.start_instance_location, true); + DrawIndexAuto({.vertex_count = args.vertex_count_per_instance, + .instance_count = args.instance_count, + .first_vertex = args.start_vertex_location, + .first_instance = args.start_instance_location, + .offset_source = DrawOffsetSource::IndirectArgs}); return; } @@ -971,28 +958,18 @@ void CommandProcessor::DrawIndirect(uint32_t data_offset, uint32_t draw_initiato } m_num_instances = args.instance_count; - DrawIndex(index_count, index_addr, 0, 1, args.instance_count, nullptr, 0, - static_cast(args.base_vertex_location), args.start_instance_location, true); + DrawIndex({.index_count = index_count, + .index_addr = index_addr, + .instance_count = args.instance_count, + .base_vertex = static_cast(args.base_vertex_location), + .first_instance = args.start_instance_location, + .offset_source = DrawOffsetSource::IndirectArgs}); } void CommandProcessor::DrawIndirectMulti(uint32_t data_offset, uint32_t max_count_or_count, const volatile uint32_t* count_addr, uint32_t stride_in_bytes, uint32_t draw_initiator, bool indexed) { - struct DrawIndirectArgs { - uint32_t vertex_count_per_instance; - uint32_t instance_count; - uint32_t start_vertex_location; - uint32_t start_instance_location; - }; - struct DrawIndexedIndirectArgs { - uint32_t index_count_per_instance; - uint32_t instance_count; - uint32_t start_index_location; - uint32_t base_vertex_location; - uint32_t start_instance_location; - }; - EXIT_NOT_IMPLEMENTED((draw_initiator & ~0x20u) != 2u); EXIT_NOT_IMPLEMENTED(m_draw_indirect_args_base_addr == 0); @@ -1029,8 +1006,11 @@ void CommandProcessor::DrawIndirectMulti(uint32_t data_offset, uint32_t max_coun } } m_num_instances = args->instance_count; - SubmitNonIndexedDraw(args->vertex_count_per_instance, 0, 0, args->start_vertex_location, - args->start_instance_location, true); + DrawIndexAuto({.vertex_count = args->vertex_count_per_instance, + .instance_count = args->instance_count, + .first_vertex = args->start_vertex_location, + .first_instance = args->start_instance_location, + .offset_source = DrawOffsetSource::IndirectArgs}); continue; } @@ -1072,9 +1052,12 @@ void CommandProcessor::DrawIndirectMulti(uint32_t data_offset, uint32_t max_coun } m_num_instances = args->instance_count; - DrawIndex(index_count, index_addr, 0, 1, args->instance_count, nullptr, 0, - static_cast(args->base_vertex_location), args->start_instance_location, - true); + DrawIndex({.index_count = index_count, + .index_addr = index_addr, + .instance_count = args->instance_count, + .base_vertex = static_cast(args->base_vertex_location), + .first_instance = args->start_instance_location, + .offset_source = DrawOffsetSource::IndirectArgs}); } } @@ -1165,20 +1148,13 @@ void CommandProcessor::DispatchIndirect(uint32_t data_offset, uint32_t mode) { DispatchDirect(args->thread_group_x, args->thread_group_y, args->thread_group_z, mode); } -void CommandProcessor::DrawIndexAuto(uint32_t index_count, uint32_t flags, - uint32_t render_target_slice_offset) { - SubmitNonIndexedDraw(index_count, flags, render_target_slice_offset, 0, 0); -} - -void CommandProcessor::SubmitNonIndexedDraw(uint32_t vertex_count, uint32_t flags, - uint32_t render_target_slice_offset, - uint32_t first_vertex, uint32_t first_instance, - bool offsets_from_indirect_args) { +void CommandProcessor::DrawIndexAuto(DrawAutoArgs args) { CheckBuffer(); - m_renderer.GetRenderExecutor().DrawAuto( - m_submit_id, CurrentBuffer(), vertex_count, flags, render_target_slice_offset, - m_num_instances, first_vertex, first_instance, offsets_from_indirect_args); + if (args.instance_count == 0) { + args.instance_count = m_num_instances; + } + m_renderer.GetRenderExecutor().DrawAuto(m_submit_id, CurrentBuffer(), args); } void CommandProcessor::WaitFlipDone(uint32_t video_out_handle, uint32_t display_buffer_index) { diff --git a/src/graphics/host_gpu/renderer/render.h b/src/graphics/host_gpu/renderer/render.h index 61747c34f..3a548612c 100644 --- a/src/graphics/host_gpu/renderer/render.h +++ b/src/graphics/host_gpu/renderer/render.h @@ -48,6 +48,31 @@ enum class CommandBufferDebugOp : uint32_t { Unknown, }; +enum class DrawOffsetSource : uint8_t { + DrawState, + IndirectArgs, +}; + +struct DrawIndexArgs { + uint32_t index_count = 0; + const void* index_addr = nullptr; + uint32_t instance_count = 0; + uint32_t index_type_and_size = 0; + int32_t base_vertex = 0; + uint32_t first_instance = 0; + DrawOffsetSource offset_source = DrawOffsetSource::DrawState; + uint32_t render_target_slice_offset = 0; +}; + +struct DrawAutoArgs { + uint32_t vertex_count = 0; + uint32_t instance_count = 0; + uint32_t first_vertex = 0; + uint32_t first_instance = 0; + DrawOffsetSource offset_source = DrawOffsetSource::DrawState; + uint32_t render_target_slice_offset = 0; +}; + struct SubmitInfo { static constexpr uint32_t MaxSemaphores = 3; @@ -129,15 +154,6 @@ public: explicit RenderExecutor(RenderContext& context): m_context(context) {} KYTY_CLASS_NO_COPY(RenderExecutor); - void DrawIndex(uint64_t submit_id, CommandBuffer& buffer, uint32_t index_type_and_size, - uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type, - uint32_t instance_count = 1, uint32_t render_target_slice_offset = 0, - int32_t vertex_offset_add = 0, uint32_t first_instance = 0, - bool offsets_from_indirect_args = false); - void DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_t index_count, uint32_t flags, - uint32_t render_target_slice_offset = 0, uint32_t instance_count = 1, - uint32_t first_vertex = 0, uint32_t first_instance = 0, - bool offsets_from_indirect_args = false); void DispatchDirect(uint64_t submit_id, CommandBuffer& buffer, uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode); @@ -150,6 +166,9 @@ public: std::span bindings); private: + void DrawIndex(uint64_t submit_id, CommandBuffer& buffer, const DrawIndexArgs& args); + void DrawAuto(uint64_t submit_id, CommandBuffer& buffer, const DrawAutoArgs& args); + struct GraphicsBindings { PreparedBindings vertex; std::optional pixel; @@ -193,6 +212,7 @@ private: std::vector m_descriptor_writes; std::vector m_image_occurrences; + friend class CommandProcessor; friend struct RenderExecutorTestAccess; }; diff --git a/src/graphics/host_gpu/renderer/renderDraw.cpp b/src/graphics/host_gpu/renderer/renderDraw.cpp index 05946d945..5344d7737 100644 --- a/src/graphics/host_gpu/renderer/renderDraw.cpp +++ b/src/graphics/host_gpu/renderer/renderDraw.cpp @@ -524,10 +524,8 @@ struct DrawCallInfo { const char* name = nullptr; CommandBufferDebugOp debug_op = CommandBufferDebugOp::DrawIndex; uint32_t index_count = 0; - uint32_t flags = 0; uint32_t instance_count = 0; uint32_t first_instance = 0; - bool offsets_from_indirect_args = false; }; static bool ResolveDccAttachmentClear(TextureCache& cache, const RenderColorInfo& target, @@ -901,8 +899,8 @@ static void SetDrawDebugPhase(CommandBuffer& buffer, uint64_t submit_id, const D uint32_t phase) { EXIT_IF(draw.name == nullptr); - buffer.SetDebugInfo(static_cast(draw.debug_op), submit_id, phase, draw.index_count, - draw.flags, draw.instance_count, draw.first_instance); + buffer.SetDebugInfo(static_cast(draw.debug_op), submit_id, phase, draw.index_count, 0, + draw.instance_count, draw.first_instance); } static bool GetDrawTopology(const HW::UserConfig& ucfg, bool auto_draw, @@ -1014,7 +1012,7 @@ bool RenderExecutor::PrepareDrawRenderState(uint64_t submit_id, CommandBuffer& b static_cast(state.depth_info.image_id)); if (state.color_count == 0 && !with_depth && !state.ps_active) { LogFramebufferSkip(draw.name, state.color_info[0], state.depth_info, buffer, - draw.index_count, draw.flags); + draw.index_count, 0); return false; } @@ -1123,7 +1121,7 @@ static void LogDrawStateIfNeeded(const CommandBuffer& buffer, const DrawCallInfo if (state.ps_active) { LogDrawTargetState(draw.name, state.color_info[0], state.depth_info, buffer, - state.ps_input_info, draw.index_count, draw.flags); + state.ps_input_info, draw.index_count, 0); } LogDrawInputState(buffer, state.color_info[0], state.vs_input_info, index_type_and_size, draw.index_count, index_addr); @@ -1260,24 +1258,21 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff } void RenderExecutor::DrawIndex(uint64_t submit_id, CommandBuffer& buffer, - uint32_t index_type_and_size, uint32_t index_count, - const void* index_addr, uint32_t flags, uint32_t type, - uint32_t instance_count, uint32_t render_target_slice_offset, - int32_t vertex_offset_add, uint32_t first_instance, - bool offsets_from_indirect_args) { + const DrawIndexArgs& args) { KYTY_PROFILER_FUNCTION(); EXIT_IF(buffer.IsInvalid()); + EXIT_IF(args.offset_source == DrawOffsetSource::DrawState && args.first_instance != 0); m_context.GetCommandScheduler().PopPendingOperations(); auto& ucfg = buffer.GetUserConfig(); auto& sh_ctx = buffer.GetShaders(); buffer.SetDebugInfo(static_cast(CommandBufferDebugOp::DrawIndex), submit_id, - index_count, flags, type, instance_count, - reinterpret_cast(index_addr)); + args.index_count, 0, 1, args.instance_count, + reinterpret_cast(args.index_addr)); Common::LockGuard lock(m_context.GetMutex()); - if (index_count == 0 || instance_count == 0) { + if (args.index_count == 0 || args.instance_count == 0) { return; } @@ -1303,15 +1298,12 @@ void RenderExecutor::DrawIndex(uint64_t submit_id, CommandBuffer& buffer, "\t index_type_and_size = 0x%08" PRIx32 "\n" "\t index_count = 0x%08" PRIx32 "\n" "\t index_addr = 0x%016" PRIx64 "\n" - "\t flags = 0x%08" PRIx32 "\n" - "\t type = 0x%08" PRIx32 "\n" "\t instance_count = 0x%08" PRIx32 "\n" - "\t rt_slice_offset = 0x%08" PRIx32 "\n" - "\t vertex_offset_add = 0x%08" PRIx32 "\n" + "\t base_vertex = 0x%08" PRIx32 "\n" "\t first_instance = 0x%08" PRIx32 "\n", - index_type_and_size, index_count, reinterpret_cast(index_addr), flags, type, - instance_count, render_target_slice_offset, static_cast(vertex_offset_add), - first_instance); + args.index_type_and_size, args.index_count, + reinterpret_cast(args.index_addr), args.instance_count, + static_cast(args.base_vertex), args.first_instance); } uc_check(ucfg); @@ -1326,45 +1318,42 @@ void RenderExecutor::DrawIndex(uint64_t submit_id, CommandBuffer& buffer, vk::IndexType index_type = vk::IndexType::eUint16; uint64_t index_size = 0; bool expand_index8_to_u16 = false; - const bool primitive_restart = ResolvePrimitiveRestart(buffer, topology, index_type_and_size); + const bool primitive_restart = + ResolvePrimitiveRestart(buffer, topology, args.index_type_and_size); - switch (static_cast(index_type_and_size)) { + switch (static_cast(args.index_type_and_size)) { case Prospero::IndexType::kIndex16: index_type = vk::IndexType::eUint16; - index_size = 2 * static_cast(index_count); + index_size = 2 * static_cast(args.index_count); break; case Prospero::IndexType::kIndex32: index_type = vk::IndexType::eUint32; - index_size = 4 * static_cast(index_count); + index_size = 4 * static_cast(args.index_count); break; // Some games use it - need vulkan extension case Prospero::IndexType::kIndex8: index_type = vk::IndexType::eUint16; - index_size = static_cast(index_count); + index_size = static_cast(args.index_count); expand_index8_to_u16 = true; break; - default: EXIT("unknown index_type_and_size: %u\n", index_type_and_size); + default: EXIT("unknown index_type_and_size: %u\n", args.index_type_and_size); } - EXIT_NOT_IMPLEMENTED(flags != 0); - EXIT_NOT_IMPLEMENTED(type != 1); - const DrawCallInfo draw {"DrawIndex", CommandBufferDebugOp::DrawIndex, - index_count, flags, - instance_count, first_instance, - offsets_from_indirect_args}; + const DrawCallInfo draw {"DrawIndex", CommandBufferDebugOp::DrawIndex, args.index_count, + args.instance_count, args.first_instance}; std::vector expanded_indices; if (expand_index8_to_u16) { - EXIT_NOT_IMPLEMENTED(index_addr == nullptr); - const auto* src = static_cast(index_addr); - expanded_indices.resize(index_count); - for (uint32_t i = 0; i < index_count; i++) { + EXIT_NOT_IMPLEMENTED(args.index_addr == nullptr); + const auto* src = static_cast(args.index_addr); + expanded_indices.resize(args.index_count); + for (uint32_t i = 0; i < args.index_count; i++) { expanded_indices[i] = primitive_restart && src[i] == 0xffu ? 0xffffu : src[i]; } } DrawIndexBufferSource index_source {}; index_source.enabled = true; - index_source.address = reinterpret_cast(index_addr); + index_source.address = reinterpret_cast(args.index_addr); index_source.host_data = expanded_indices.empty() ? nullptr : static_cast(expanded_indices.data()); index_source.size = @@ -1372,26 +1361,28 @@ void RenderExecutor::DrawIndex(uint64_t submit_id, CommandBuffer& buffer, index_source.type = index_type; DrawRenderState state {}; - if (!PrepareDrawRenderState(submit_id, buffer, draw, render_target_slice_offset, true, state)) { + if (!PrepareDrawRenderState(submit_id, buffer, draw, args.render_target_slice_offset, true, + state)) { ResetBindings(); return; } RefreshShaders(buffer, draw, true, state); - LogDrawStateIfNeeded(buffer, draw, state, true, false, index_type_and_size, index_addr); + LogDrawStateIfNeeded(buffer, draw, state, true, false, args.index_type_and_size, + args.index_addr); + const bool indirect = args.offset_source == DrawOffsetSource::IndirectArgs; const auto vertex_offset = - draw.offsets_from_indirect_args - ? vertex_offset_add - : ResolveVertexOffset(ucfg.GetIndexOffset(), state.vs_input_info) + vertex_offset_add; + indirect + ? args.base_vertex + : ResolveVertexOffset(ucfg.GetIndexOffset(), state.vs_input_info) + args.base_vertex; DrawEmitInfo emit {}; - emit.indexed = true; - emit.vertex_offset = vertex_offset; - emit.first_instance = draw.offsets_from_indirect_args - ? draw.first_instance - : ResolveInstanceOffset(state.vs_input_info); + emit.indexed = true; + emit.vertex_offset = vertex_offset; + emit.first_instance = + indirect ? args.first_instance : ResolveInstanceOffset(state.vs_input_info); ExecutePreparedDraw(submit_id, buffer, draw, state, topology, emit, index_source, primitive_restart, true, true, false); @@ -1399,22 +1390,21 @@ void RenderExecutor::DrawIndex(uint64_t submit_id, CommandBuffer& buffer, } // NOLINTNEXTLINE(readability-function-cognitive-complexity) -void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_t index_count, - uint32_t flags, uint32_t render_target_slice_offset, - uint32_t instance_count, uint32_t first_vertex, - uint32_t first_instance, bool offsets_from_indirect_args) { +void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, const DrawAutoArgs& args) { KYTY_PROFILER_FUNCTION(); EXIT_IF(buffer.IsInvalid()); + EXIT_IF(args.offset_source == DrawOffsetSource::DrawState && args.first_instance != 0); m_context.GetCommandScheduler().PopPendingOperations(); auto& ucfg = buffer.GetUserConfig(); auto& sh_ctx = buffer.GetShaders(); buffer.SetDebugInfo(static_cast(CommandBufferDebugOp::DrawIndexAuto), submit_id, - index_count, flags, first_vertex, instance_count, first_instance); + args.vertex_count, 0, args.first_vertex, args.instance_count, + args.first_instance); Common::LockGuard lock(m_context.GetMutex()); - if (index_count == 0 || instance_count == 0) { + if (args.vertex_count == 0 || args.instance_count == 0) { return; } @@ -1437,28 +1427,22 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_ hw_print(buffer); LOGF("GraphicsRenderDrawIndexAuto():Parameters:\n" - "\t index_count = 0x%08" PRIx32 "\n" - "\t flags = 0x%08" PRIx32 "\n" - "\t rt_slice_offset = 0x%08" PRIx32 "\n" + "\t vertex_count = 0x%08" PRIx32 "\n" "\t instance_count = 0x%08" PRIx32 "\n" "\t first_vertex = 0x%08" PRIx32 "\n" "\t first_instance = 0x%08" PRIx32 "\n", - index_count, flags, render_target_slice_offset, instance_count, first_vertex, - first_instance); + args.vertex_count, args.instance_count, args.first_vertex, args.first_instance); } uc_check(ucfg); hw_check(buffer); - EXIT_NOT_IMPLEMENTED(flags != 0); const DrawCallInfo draw {"DrawIndexAuto", CommandBufferDebugOp::DrawIndexAuto, - index_count, flags, - instance_count, first_instance, - offsets_from_indirect_args}; + args.vertex_count, args.instance_count, args.first_instance}; DrawRenderState state {}; - if (!PrepareDrawRenderState(submit_id, buffer, draw, render_target_slice_offset, false, + if (!PrepareDrawRenderState(submit_id, buffer, draw, args.render_target_slice_offset, false, state)) { ResetBindings(); return; @@ -1489,16 +1473,15 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_ ucfg.GetPrimType() == Prospero::PrimitiveType::kRectListLegacy, 0, nullptr); + const bool indirect = args.offset_source == DrawOffsetSource::IndirectArgs; const auto vertex_offset = - draw.offsets_from_indirect_args - ? static_cast(first_vertex) - : ResolveVertexOffset(ucfg.GetIndexOffset(), state.vs_input_info) + - static_cast(first_vertex); + indirect ? static_cast(args.first_vertex) + : ResolveVertexOffset(ucfg.GetIndexOffset(), state.vs_input_info) + + static_cast(args.first_vertex); DrawEmitInfo emit {}; - emit.first_vertex = static_cast(vertex_offset); - emit.first_instance = draw.offsets_from_indirect_args - ? draw.first_instance - : ResolveInstanceOffset(state.vs_input_info); + emit.first_vertex = static_cast(vertex_offset); + emit.first_instance = + indirect ? args.first_instance : ResolveInstanceOffset(state.vs_input_info); DrawIndexBufferSource index_source {}; ExecutePreparedDraw(submit_id, buffer, draw, state, topology, emit, index_source, false, false,