libraries: gnm_driver: added `sceGnmDrawIndexIndirect` and `sceGnmDrawIndirect`
This commit is contained in:
parent
508d034263
commit
c04fbb75d8
|
@ -24,6 +24,20 @@ using namespace AmdGpu;
|
||||||
|
|
||||||
static std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
static std::unique_ptr<AmdGpu::Liverpool> liverpool;
|
||||||
|
|
||||||
|
enum ShaderStages : u32 {
|
||||||
|
Cs,
|
||||||
|
Ps,
|
||||||
|
Vs,
|
||||||
|
Gs,
|
||||||
|
Es,
|
||||||
|
Hs,
|
||||||
|
Ls,
|
||||||
|
|
||||||
|
Max
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr std::array indirect_sgpr_offsets{0u, 0u, 0x4cu, 0u, 0xccu, 0u, 0x14cu};
|
||||||
|
|
||||||
// In case of precise gnm driver emulation we need to send a bunch of HW-specific
|
// In case of precise gnm driver emulation we need to send a bunch of HW-specific
|
||||||
// initialization commands. It may slowdown development at early stage as their
|
// initialization commands. It may slowdown development at early stage as their
|
||||||
// support is not important and can be ignored for a while.
|
// support is not important and can be ignored for a while.
|
||||||
|
@ -347,10 +361,30 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirect() {
|
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
u32 vertex_sgpr_offset, u32 instance_vgpr_offset,
|
||||||
|
u32 flags) {
|
||||||
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
|
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
||||||
|
(vertex_sgpr_offset < 0x10u) && (instance_vgpr_offset < 0x10u)) {
|
||||||
|
|
||||||
|
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||||
|
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndexIndirect>(
|
||||||
|
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_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
|
||||||
|
cmdbuf[3] = 0;
|
||||||
|
|
||||||
|
WriteTrailingNop<3>(cmdbuf);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti() {
|
int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti() {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
||||||
|
@ -383,10 +417,29 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndirect() {
|
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
u32 vertex_sgpr_offset, u32 instance_vgpr_offset, u32 flags) {
|
||||||
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
|
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
||||||
|
(vertex_sgpr_offset < 0x10u) && (instance_vgpr_offset < 0x10u)) {
|
||||||
|
|
||||||
|
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||||
|
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndirect>(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_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
|
||||||
|
cmdbuf[3] = 2; // auto index
|
||||||
|
|
||||||
|
WriteTrailingNop<3>(cmdbuf);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti() {
|
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti() {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
||||||
|
|
|
@ -44,13 +44,16 @@ u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size);
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr_t index_addr,
|
s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr_t index_addr,
|
||||||
u32 flags, u32 type);
|
u32 flags, u32 type);
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32 flags);
|
s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32 flags);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirect();
|
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
|
u32 vertex_sgpr_offset, u32 instance_vgpr_offset,
|
||||||
|
u32 flags);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti();
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti();
|
||||||
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);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndirect();
|
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
|
u32 vertex_sgpr_offset, u32 instance_vgpr_offset, u32 flags);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti();
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndirectMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndirectMulti();
|
||||||
int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState();
|
int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState();
|
||||||
|
|
|
@ -253,6 +253,20 @@ struct PM4CmdDrawIndexAuto {
|
||||||
u32 draw_initiator;
|
u32 draw_initiator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PM4CmdDrawIndirect {
|
||||||
|
PM4Type3Header header; ///< header
|
||||||
|
u32 data_offset; ///< DWORD aligned offset
|
||||||
|
union {
|
||||||
|
u32 dw2;
|
||||||
|
BitField<0, 16, u32> base_vtx_loc; ///< base vertex location
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
u32 dw3;
|
||||||
|
BitField<0, 16, u32> start_inst_loc; ///< start instance location
|
||||||
|
};
|
||||||
|
u32 draw_initiator; ///< Draw Initiator Register
|
||||||
|
};
|
||||||
|
|
||||||
enum class DataSelect : u32 {
|
enum class DataSelect : u32 {
|
||||||
None = 0,
|
None = 0,
|
||||||
Data32Low = 1,
|
Data32Low = 1,
|
||||||
|
|
Loading…
Reference in New Issue