mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-14 08:12:16 +00:00
gnm: Implement sceGnmDrawIndexIndirectMulti (#2889)
This commit is contained in:
parent
8d7cbf9943
commit
a1439b15cf
5 changed files with 86 additions and 20 deletions
|
@ -505,9 +505,10 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 da
|
||||||
u32 flags) {
|
u32 flags) {
|
||||||
LOG_TRACE(Lib_GnmDriver, "called");
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
if ((!sceKernelIsNeoMode() || !UseNeoCompatSequences) && !cmdbuf && (size == 16) &&
|
if ((!sceKernelIsNeoMode() || !UseNeoCompatSequences) && cmdbuf && (size == 16) &&
|
||||||
(shader_stage < ShaderStages::Max) && (vertex_sgpr_offset < 0x10u) &&
|
(vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u) &&
|
||||||
(instance_sgpr_offset < 0x10u)) {
|
(shader_stage == ShaderStages::Vs || shader_stage == ShaderStages::Es ||
|
||||||
|
shader_stage == ShaderStages::Ls)) {
|
||||||
|
|
||||||
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 2);
|
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 2);
|
||||||
cmdbuf = WriteBody(cmdbuf, 0u);
|
cmdbuf = WriteBody(cmdbuf, 0u);
|
||||||
|
@ -535,10 +536,33 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 da
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti() {
|
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count,
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
u32 shader_stage, u32 vertex_sgpr_offset,
|
||||||
UNREACHABLE();
|
u32 instance_sgpr_offset, u32 flags) {
|
||||||
return ORBIS_OK;
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
|
if (cmdbuf && (size == 11) && (vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u) &&
|
||||||
|
(shader_stage == ShaderStages::Vs || shader_stage == ShaderStages::Es ||
|
||||||
|
shader_stage == ShaderStages::Ls)) {
|
||||||
|
|
||||||
|
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||||
|
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndexIndirectMulti>(
|
||||||
|
cmdbuf, 6, 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(DrawIndexedIndirectArgs);
|
||||||
|
cmdbuf[5] = sceKernelIsNeoMode() ? flags & 0xe0000000u : 0;
|
||||||
|
|
||||||
|
cmdbuf += 6;
|
||||||
|
WriteTrailingNop<3>(cmdbuf);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced() {
|
int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced() {
|
||||||
|
|
|
@ -51,7 +51,9 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti(u32* cmdbuf, u32 size, u32 da
|
||||||
u32 max_count, u64 count_addr, u32 shader_stage,
|
u32 max_count, u64 count_addr, u32 shader_stage,
|
||||||
u32 vertex_sgpr_offset, u32 instance_sgpr_offset,
|
u32 vertex_sgpr_offset, u32 instance_sgpr_offset,
|
||||||
u32 flags);
|
u32 flags);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti(u32* cmdbuf, u32 size, u32 data_offset, u32 max_count,
|
||||||
|
u32 shader_stage, u32 vertex_sgpr_offset,
|
||||||
|
u32 instance_sgpr_offset, u32 flags);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced();
|
int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced();
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset, u32 index_count,
|
s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset, u32 index_count,
|
||||||
u32 flags);
|
u32 flags);
|
||||||
|
|
|
@ -455,14 +455,14 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
case PM4ItOpcode::DrawIndirect: {
|
case PM4ItOpcode::DrawIndirect: {
|
||||||
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 size = sizeof(DrawIndirectArgs);
|
const auto stride = 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);
|
||||||
}
|
}
|
||||||
if (rasterizer) {
|
if (rasterizer) {
|
||||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||||
rasterizer->ScopeMarkerBegin(fmt::format("gfx:{}:DrawIndirect", cmd_address));
|
rasterizer->ScopeMarkerBegin(fmt::format("gfx:{}:DrawIndirect", cmd_address));
|
||||||
rasterizer->DrawIndirect(false, indirect_args_addr, offset, size, 1, 0);
|
rasterizer->DrawIndirect(false, indirect_args_addr, offset, stride, 1, 0);
|
||||||
rasterizer->ScopeMarkerEnd();
|
rasterizer->ScopeMarkerEnd();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -471,7 +471,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
const auto* draw_index_indirect =
|
const auto* draw_index_indirect =
|
||||||
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 size = sizeof(DrawIndexedIndirectArgs);
|
const auto stride = 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);
|
||||||
}
|
}
|
||||||
|
@ -479,25 +479,46 @@ 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("gfx:{}:DrawIndexIndirect", cmd_address));
|
fmt::format("gfx:{}:DrawIndexIndirect", cmd_address));
|
||||||
rasterizer->DrawIndirect(true, indirect_args_addr, offset, size, 1, 0);
|
rasterizer->DrawIndirect(true, indirect_args_addr, offset, stride, 1, 0);
|
||||||
rasterizer->ScopeMarkerEnd();
|
rasterizer->ScopeMarkerEnd();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM4ItOpcode::DrawIndexIndirectCountMulti: {
|
case PM4ItOpcode::DrawIndexIndirectMulti: {
|
||||||
const auto* draw_index_indirect =
|
const auto* draw_index_indirect =
|
||||||
reinterpret_cast<const PM4CmdDrawIndexIndirectMulti*>(header);
|
reinterpret_cast<const PM4CmdDrawIndexIndirectMulti*>(header);
|
||||||
const auto offset = draw_index_indirect->data_offset;
|
const auto offset = draw_index_indirect->data_offset;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
if (rasterizer) {
|
||||||
|
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||||
|
rasterizer->ScopeMarkerBegin(
|
||||||
|
fmt::format("gfx:{}:DrawIndexIndirectMulti", cmd_address));
|
||||||
|
rasterizer->DrawIndirect(true, indirect_args_addr, offset,
|
||||||
|
draw_index_indirect->stride,
|
||||||
|
draw_index_indirect->count, 0);
|
||||||
|
rasterizer->ScopeMarkerEnd();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM4ItOpcode::DrawIndexIndirectCountMulti: {
|
||||||
|
const auto* draw_index_indirect =
|
||||||
|
reinterpret_cast<const PM4CmdDrawIndexIndirectCountMulti*>(header);
|
||||||
|
const auto offset = draw_index_indirect->data_offset;
|
||||||
|
if (DebugState.DumpingCurrentReg()) {
|
||||||
|
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs);
|
||||||
|
}
|
||||||
if (rasterizer) {
|
if (rasterizer) {
|
||||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||||
rasterizer->ScopeMarkerBegin(
|
rasterizer->ScopeMarkerBegin(
|
||||||
fmt::format("gfx:{}:DrawIndexIndirectCountMulti", cmd_address));
|
fmt::format("gfx:{}:DrawIndexIndirectCountMulti", cmd_address));
|
||||||
rasterizer->DrawIndirect(
|
rasterizer->DrawIndirect(true, indirect_args_addr, offset,
|
||||||
true, indirect_args_addr, offset, draw_index_indirect->stride,
|
draw_index_indirect->stride,
|
||||||
draw_index_indirect->count, draw_index_indirect->countAddr);
|
draw_index_indirect->count,
|
||||||
|
draw_index_indirect->count_indirect_enable.Value()
|
||||||
|
? draw_index_indirect->count_addr
|
||||||
|
: 0);
|
||||||
rasterizer->ScopeMarkerEnd();
|
rasterizer->ScopeMarkerEnd();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -860,6 +860,24 @@ struct PM4CmdDrawIndexIndirect {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PM4CmdDrawIndexIndirectMulti {
|
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
|
||||||
|
};
|
||||||
|
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 PM4CmdDrawIndexIndirectCountMulti {
|
||||||
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 {
|
||||||
|
@ -874,14 +892,14 @@ struct PM4CmdDrawIndexIndirectMulti {
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
u32 dw4;
|
u32 dw4;
|
||||||
BitField<0, 16, u32> drawIndexLoc; ///< register offset to write the Draw Index count
|
BitField<0, 16, u32> draw_index_loc; ///< 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
|
count_indirect_enable; ///< 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
|
draw_index_enable; ///< 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 count_addr; ///< DWord aligned Address[31:2]; Valid if countIndirectEnable is set
|
||||||
u32 stride; ///< Stride in memory from one data structure to the next
|
u32 stride; ///< Stride in memory from one data structure to the next
|
||||||
u32 draw_initiator; ///< Draw Initiator Register
|
u32 draw_initiator; ///< Draw Initiator Register
|
||||||
};
|
};
|
||||||
|
|
|
@ -338,6 +338,7 @@ bool Instance::CreateDevice() {
|
||||||
.geometryShader = features.geometryShader,
|
.geometryShader = features.geometryShader,
|
||||||
.tessellationShader = features.tessellationShader,
|
.tessellationShader = features.tessellationShader,
|
||||||
.logicOp = features.logicOp,
|
.logicOp = features.logicOp,
|
||||||
|
.multiDrawIndirect = features.multiDrawIndirect,
|
||||||
.depthBiasClamp = features.depthBiasClamp,
|
.depthBiasClamp = features.depthBiasClamp,
|
||||||
.fillModeNonSolid = features.fillModeNonSolid,
|
.fillModeNonSolid = features.fillModeNonSolid,
|
||||||
.depthBounds = features.depthBounds,
|
.depthBounds = features.depthBounds,
|
||||||
|
|
Loading…
Add table
Reference in a new issue