mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-28 10:36:06 +00:00
video_core: clean-up of indirect draws logic (#1589)
This commit is contained in:
parent
fde1726af5
commit
16e1d679dc
|
@ -703,7 +703,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 da
|
||||||
cmdbuf[3] = (count_addr != 0 ? 1u : 0u) << 0x1e;
|
cmdbuf[3] = (count_addr != 0 ? 1u : 0u) << 0x1e;
|
||||||
cmdbuf[4] = max_count;
|
cmdbuf[4] = max_count;
|
||||||
*(u64*)(&cmdbuf[5]) = count_addr;
|
*(u64*)(&cmdbuf[5]) = count_addr;
|
||||||
cmdbuf[7] = AmdGpu::Liverpool::DrawIndexedIndirectArgsSize;
|
cmdbuf[7] = sizeof(DrawIndexedIndirectArgs);
|
||||||
cmdbuf[8] = 0;
|
cmdbuf[8] = 0;
|
||||||
|
|
||||||
cmdbuf += 9;
|
cmdbuf += 9;
|
||||||
|
|
|
@ -410,7 +410,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
const auto* draw_indirect = reinterpret_cast<const PM4CmdDrawIndirect*>(header);
|
const auto* draw_indirect = reinterpret_cast<const PM4CmdDrawIndirect*>(header);
|
||||||
const auto offset = draw_indirect->data_offset;
|
const auto offset = draw_indirect->data_offset;
|
||||||
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
||||||
const auto size = sizeof(PM4CmdDrawIndirect::DrawInstancedArgs);
|
const auto size = sizeof(DrawIndirectArgs);
|
||||||
if (DebugState.DumpingCurrentReg()) {
|
if (DebugState.DumpingCurrentReg()) {
|
||||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
reinterpret_cast<const PM4CmdDrawIndexIndirect*>(header);
|
reinterpret_cast<const PM4CmdDrawIndexIndirect*>(header);
|
||||||
const auto offset = draw_index_indirect->data_offset;
|
const auto offset = draw_index_indirect->data_offset;
|
||||||
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
||||||
const auto size = sizeof(PM4CmdDrawIndexIndirect::DrawIndexInstancedArgs);
|
const auto size = sizeof(DrawIndexedIndirectArgs);
|
||||||
if (DebugState.DumpingCurrentReg()) {
|
if (DebugState.DumpingCurrentReg()) {
|
||||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||||
}
|
}
|
||||||
|
@ -442,10 +442,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
}
|
}
|
||||||
case PM4ItOpcode::DrawIndexIndirectCountMulti: {
|
case PM4ItOpcode::DrawIndexIndirectCountMulti: {
|
||||||
const auto* draw_index_indirect =
|
const auto* draw_index_indirect =
|
||||||
reinterpret_cast<const PM4CmdDrawIndexIndirect*>(header);
|
reinterpret_cast<const PM4CmdDrawIndexIndirectMulti*>(header);
|
||||||
const auto offset = draw_index_indirect->data_offset;
|
const auto offset = draw_index_indirect->data_offset;
|
||||||
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
||||||
const auto size = sizeof(PM4CmdDrawIndexIndirect::DrawIndexInstancedArgs);
|
|
||||||
if (DebugState.DumpingCurrentReg()) {
|
if (DebugState.DumpingCurrentReg()) {
|
||||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||||
}
|
}
|
||||||
|
@ -453,7 +452,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||||
rasterizer->ScopeMarkerBegin(
|
rasterizer->ScopeMarkerBegin(
|
||||||
fmt::format("dcb:{}:DrawIndexIndirectCountMulti", cmd_address));
|
fmt::format("dcb:{}:DrawIndexIndirectCountMulti", cmd_address));
|
||||||
rasterizer->DrawIndirect(true, ib_address, offset, size,
|
rasterizer->DrawIndirect(true, ib_address, offset, draw_index_indirect->stride,
|
||||||
draw_index_indirect->count,
|
draw_index_indirect->count,
|
||||||
draw_index_indirect->countAddr);
|
draw_index_indirect->countAddr);
|
||||||
rasterizer->ScopeMarkerEnd();
|
rasterizer->ScopeMarkerEnd();
|
||||||
|
|
|
@ -57,8 +57,6 @@ struct Liverpool {
|
||||||
static constexpr u32 ConfigRegWordOffset = 0x2000;
|
static constexpr u32 ConfigRegWordOffset = 0x2000;
|
||||||
static constexpr u32 ShRegWordOffset = 0x2C00;
|
static constexpr u32 ShRegWordOffset = 0x2C00;
|
||||||
static constexpr u32 NumRegs = 0xD000;
|
static constexpr u32 NumRegs = 0xD000;
|
||||||
static constexpr u32 DrawIndirectArgsSize = 0x10u;
|
|
||||||
static constexpr u32 DrawIndexedIndirectArgsSize = 0x14u;
|
|
||||||
|
|
||||||
using UserData = std::array<u32, NumShaderUserData>;
|
using UserData = std::array<u32, NumShaderUserData>;
|
||||||
|
|
||||||
|
|
|
@ -778,14 +778,15 @@ struct PM4CmdDispatchIndirect {
|
||||||
u32 dispatch_initiator; ///< Dispatch Initiator Register
|
u32 dispatch_initiator; ///< Dispatch Initiator Register
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PM4CmdDrawIndirect {
|
struct DrawIndirectArgs {
|
||||||
struct DrawInstancedArgs {
|
u32 vertex_count_per_instance;
|
||||||
u32 vertex_count_per_instance;
|
u32 instance_count;
|
||||||
u32 instance_count;
|
u32 start_vertex_location;
|
||||||
u32 start_vertex_location;
|
u32 start_instance_location;
|
||||||
u32 start_instance_location;
|
};
|
||||||
};
|
static_assert(sizeof(DrawIndirectArgs) == 0x10u);
|
||||||
|
|
||||||
|
struct PM4CmdDrawIndirect {
|
||||||
PM4Type3Header header; ///< header
|
PM4Type3Header header; ///< header
|
||||||
u32 data_offset; ///< Byte aligned offset where the required data structure starts
|
u32 data_offset; ///< Byte aligned offset where the required data structure starts
|
||||||
union {
|
union {
|
||||||
|
@ -801,15 +802,16 @@ struct PM4CmdDrawIndirect {
|
||||||
u32 draw_initiator; ///< Draw Initiator Register
|
u32 draw_initiator; ///< Draw Initiator Register
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PM4CmdDrawIndexIndirect {
|
struct DrawIndexedIndirectArgs {
|
||||||
struct DrawIndexInstancedArgs {
|
u32 index_count_per_instance;
|
||||||
u32 index_count_per_instance;
|
u32 instance_count;
|
||||||
u32 instance_count;
|
u32 start_index_location;
|
||||||
u32 start_index_location;
|
u32 base_vertex_location;
|
||||||
u32 base_vertex_location;
|
u32 start_instance_location;
|
||||||
u32 start_instance_location;
|
};
|
||||||
};
|
static_assert(sizeof(DrawIndexedIndirectArgs) == 0x14u);
|
||||||
|
|
||||||
|
struct PM4CmdDrawIndexIndirect {
|
||||||
PM4Type3Header header; ///< header
|
PM4Type3Header header; ///< header
|
||||||
u32 data_offset; ///< Byte aligned offset where the required data structure starts
|
u32 data_offset; ///< Byte aligned offset where the required data structure starts
|
||||||
union {
|
union {
|
||||||
|
@ -822,16 +824,29 @@ struct PM4CmdDrawIndexIndirect {
|
||||||
BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the
|
BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the
|
||||||
///< StartInstanceLocation it fetched from memory
|
///< StartInstanceLocation it fetched from memory
|
||||||
};
|
};
|
||||||
|
u32 draw_initiator; ///< Draw Initiator Register
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PM4CmdDrawIndexIndirectMulti {
|
||||||
|
PM4Type3Header header; ///< header
|
||||||
|
u32 data_offset; ///< Byte aligned offset where the required data structure starts
|
||||||
|
union {
|
||||||
|
u32 dw2;
|
||||||
|
BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the
|
||||||
|
///< BaseVertexLocation it fetched from memory
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
u32 dw3;
|
||||||
|
BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the
|
||||||
|
///< StartInstanceLocation it fetched from memory
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
u32 dw4;
|
u32 dw4;
|
||||||
struct {
|
BitField<0, 16, u32> drawIndexLoc; ///< register offset to write the Draw Index count
|
||||||
BitField<0, 16, u32> drawIndexLoc; ///< register offset to write the Draw Index count
|
BitField<30, 1, u32>
|
||||||
BitField<30, 1, u32>
|
countIndirectEnable; ///< Indicates the data structure count is in memory
|
||||||
countIndirectEnable; ///< Indicates the data structure count is in memory
|
BitField<31, 1, u32>
|
||||||
BitField<31, 1, u32>
|
drawIndexEnable; ///< Enables writing of Draw Index count to DRAW_INDEX_LOC
|
||||||
drawIndexEnable; ///< Enables writing of Draw Index count to DRAW_INDEX_LOC
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
u32 count; ///< Count of data structures to loop through before going to next packet
|
u32 count; ///< Count of data structures to loop through before going to next packet
|
||||||
u64 countAddr; ///< DWord aligned Address[31:2]; Valid if countIndirectEnable is set
|
u64 countAddr; ///< DWord aligned Address[31:2]; Valid if countIndirectEnable is set
|
||||||
|
|
|
@ -115,7 +115,7 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u32 size,
|
void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u32 stride,
|
||||||
u32 max_count, VAddr count_address) {
|
u32 max_count, VAddr count_address) {
|
||||||
RENDERER_TRACE;
|
RENDERER_TRACE;
|
||||||
|
|
||||||
|
@ -142,7 +142,8 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
|
||||||
buffer_cache.BindVertexBuffers(vs_info);
|
buffer_cache.BindVertexBuffers(vs_info);
|
||||||
buffer_cache.BindIndexBuffer(is_indexed, 0);
|
buffer_cache.BindIndexBuffer(is_indexed, 0);
|
||||||
|
|
||||||
const auto [buffer, base] = buffer_cache.ObtainBuffer(arg_address + offset, size, false);
|
const auto [buffer, base] =
|
||||||
|
buffer_cache.ObtainBuffer(arg_address + offset, stride * max_count, false);
|
||||||
|
|
||||||
VideoCore::Buffer* count_buffer{};
|
VideoCore::Buffer* count_buffer{};
|
||||||
u32 count_base{};
|
u32 count_base{};
|
||||||
|
@ -158,26 +159,22 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
|
||||||
|
|
||||||
const auto cmdbuf = scheduler.CommandBuffer();
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
if (is_indexed) {
|
if (is_indexed) {
|
||||||
static_assert(sizeof(VkDrawIndexedIndirectCommand) ==
|
ASSERT(sizeof(VkDrawIndexedIndirectCommand) == stride);
|
||||||
AmdGpu::Liverpool::DrawIndexedIndirectArgsSize);
|
|
||||||
|
|
||||||
if (count_address != 0) {
|
if (count_address != 0) {
|
||||||
cmdbuf.drawIndexedIndirectCount(buffer->Handle(), base, count_buffer->Handle(),
|
cmdbuf.drawIndexedIndirectCount(buffer->Handle(), base, count_buffer->Handle(),
|
||||||
count_base, max_count,
|
count_base, max_count, stride);
|
||||||
AmdGpu::Liverpool::DrawIndexedIndirectArgsSize);
|
|
||||||
} else {
|
} else {
|
||||||
cmdbuf.drawIndexedIndirect(buffer->Handle(), base, max_count,
|
cmdbuf.drawIndexedIndirect(buffer->Handle(), base, max_count, stride);
|
||||||
AmdGpu::Liverpool::DrawIndexedIndirectArgsSize);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
static_assert(sizeof(VkDrawIndirectCommand) == AmdGpu::Liverpool::DrawIndirectArgsSize);
|
ASSERT(sizeof(VkDrawIndirectCommand) == stride);
|
||||||
|
|
||||||
if (count_address != 0) {
|
if (count_address != 0) {
|
||||||
cmdbuf.drawIndirectCount(buffer->Handle(), base, count_buffer->Handle(), count_base,
|
cmdbuf.drawIndirectCount(buffer->Handle(), base, count_buffer->Handle(), count_base,
|
||||||
max_count, AmdGpu::Liverpool::DrawIndirectArgsSize);
|
max_count, stride);
|
||||||
} else {
|
} else {
|
||||||
cmdbuf.drawIndirect(buffer->Handle(), base, max_count,
|
cmdbuf.drawIndirect(buffer->Handle(), base, max_count, stride);
|
||||||
AmdGpu::Liverpool::DrawIndirectArgsSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue