mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-03-28 06:29:41 -06:00
Lib.GnmDriver: Implement sceGnmDrawIndirectMulti (#4083)
This commit is contained in:
parent
8bb29695ed
commit
aae10ecdf7
@ -627,10 +627,30 @@ int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti() {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceGnmDrawIndirectMulti() {
|
||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
||||
UNREACHABLE();
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count,
|
||||
u32 shader_stage, u32 vertex_sgpr_offset,
|
||||
u32 instance_sgpr_offset, u32 flags) {
|
||||
LOG_TRACE(Lib_GnmDriver, "called");
|
||||
|
||||
if (cmdbuf && size == 11 && shader_stage < ShaderStages::Max && vertex_sgpr_offset < 0x10 &&
|
||||
instance_sgpr_offset < 0x10) {
|
||||
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndirectMulti>(
|
||||
cmdbuf, 4, PM4ShaderType::ShaderGraphics, predicate);
|
||||
|
||||
const auto sgpr_offset = indirect_sgpr_offsets[shader_stage];
|
||||
cmdbuf[0] = data_offset;
|
||||
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[3] = max_count;
|
||||
cmdbuf[4] = sizeof(DrawIndirectArgs);
|
||||
cmdbuf[5] = sceKernelIsNeoMode() ? flags & 0xe0000000u | 2u : 2u; // auto index
|
||||
|
||||
cmdbuf += 6;
|
||||
WriteTrailingNop<3>(cmdbuf);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size) {
|
||||
|
||||
@ -60,7 +60,9 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset,
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||
u32 vertex_sgpr_offset, u32 instance_sgpr_offset, u32 flags);
|
||||
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti();
|
||||
int PS4_SYSV_ABI sceGnmDrawIndirectMulti();
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count,
|
||||
u32 shader_stage, u32 vertex_sgpr_offset,
|
||||
u32 instance_sgpr_offset, u32 flags);
|
||||
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size);
|
||||
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size);
|
||||
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size);
|
||||
|
||||
@ -501,6 +501,28 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::DrawIndirectMulti: {
|
||||
const auto* draw_indirect =
|
||||
reinterpret_cast<const PM4CmdDrawIndirectMulti*>(header);
|
||||
const auto offset = draw_indirect->data_offset;
|
||||
if (DebugState.DumpingCurrentReg()) {
|
||||
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||
}
|
||||
if (rasterizer) {
|
||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||
if (host_markers_enabled) {
|
||||
rasterizer->ScopeMarkerBegin(
|
||||
fmt::format("gfx:{}:DrawIndirectMulti", cmd_address));
|
||||
rasterizer->DrawIndirect(false, indirect_args_addr, offset,
|
||||
draw_indirect->stride, draw_indirect->count, 0);
|
||||
rasterizer->ScopeMarkerEnd();
|
||||
} else {
|
||||
rasterizer->DrawIndirect(false, indirect_args_addr, offset,
|
||||
draw_indirect->stride, draw_indirect->count, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::DrawIndexIndirect: {
|
||||
const auto* draw_index_indirect =
|
||||
reinterpret_cast<const PM4CmdDrawIndexIndirect*>(header);
|
||||
|
||||
@ -1051,6 +1051,24 @@ struct PM4CmdDrawIndirect {
|
||||
u32 draw_initiator; ///< Draw Initiator Register
|
||||
};
|
||||
|
||||
struct PM4CmdDrawIndirectMulti {
|
||||
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
|
||||
};
|
||||
u32 count; ///< Count of data structures to loop through before going to next packet
|
||||
u32 stride; ///< Stride in memory from one data structure to the next
|
||||
u32 draw_initiator; ///< Draw Initiator Register
|
||||
};
|
||||
|
||||
struct DrawIndexedIndirectArgs {
|
||||
u32 index_count_per_instance;
|
||||
u32 instance_count;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user