Merge pull request #287 from polybiusproxy/dev

gnmdriver: Implement shader functions
This commit is contained in:
georgemoralis 2024-07-15 07:47:33 +03:00 committed by GitHub
commit c49afb4c17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 216 additions and 60 deletions

View file

@ -1409,9 +1409,8 @@ s32 PS4_SYSV_ABI sceGnmSetEmbeddedPsShader(u32* cmdbuf, u32 size, u32 shader_id,
// repeat set shader functionality here as it is trivial.
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
cmdbuf =
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c4u, ps_regs[4],
ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
@ -1468,18 +1467,44 @@ s32 PS4_SYSV_ABI sceGnmSetEmbeddedVsShader(u32* cmdbuf, u32 size, u32 shader_id,
// pointer to a stack memory, so the check will likely fail. To workaround it we will
// repeat set shader functionality here as it is trivial.
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], vs_regs[1]); // SPI_SHADER_PGM_LO_VS
cmdbuf =
PM4CmdSetData::SetShReg(cmdbuf, 0x4au, vs_regs[2], vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b1u, vs_regs[4]); // SPI_VS_OUT_CONFIG
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c3u, vs_regs[5]); // SPI_SHADER_POS_FORMAT
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, vs_regs[2],
vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS/SPI_SHADER_PGM_RSRC2_VS
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b1u, vs_regs[4]); // SPI_VS_OUT_CONFIG
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c3u, vs_regs[5]); // SPI_SHADER_POS_FORMAT
WriteTrailingNop<11>(cmdbuf);
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmSetEsShader() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
s32 PS4_SYSV_ABI sceGnmSetEsShader(u32* cmdbuf, u32 size, const u32* es_regs, u32 shader_modifier) {
LOG_TRACE(Lib_GnmDriver, "called");
if (!cmdbuf || size < 0x14) {
return -1;
}
if (!es_regs) {
LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument");
return -1;
}
if (shader_modifier & 0xfcfffc3f) {
LOG_ERROR(Lib_GnmDriver, "Invalid modifier mask");
return -1;
}
if (es_regs[1] != 0) {
LOG_ERROR(Lib_GnmDriver, "Invalid shader address");
return -1;
}
const u32 var =
shader_modifier == 0 ? es_regs[2] : ((es_regs[2] & 0xfcfffc3f) | shader_modifier);
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0xc8u, es_regs[0], 0u); // SPI_SHADER_PGM_LO_ES
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0xcau, var, es_regs[3]); // SPI_SHADER_PGM_RSRC1_ES
WriteTrailingNop<11>(cmdbuf);
return ORBIS_OK;
}
@ -1488,18 +1513,93 @@ int PS4_SYSV_ABI sceGnmSetGsRingSizes() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmSetGsShader() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
s32 PS4_SYSV_ABI sceGnmSetGsShader(u32* cmdbuf, u32 size, const u32* gs_regs) {
LOG_TRACE(Lib_GnmDriver, "called");
if (!cmdbuf || size < 0x1d) {
return -1;
}
if (!gs_regs) {
LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument");
return -1;
}
if (gs_regs[1] != 0) {
LOG_ERROR(Lib_GnmDriver, "Invalid shader address");
return -1;
}
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x88u, gs_regs[0], 0u); // SPI_SHADER_PGM_LO_GS
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x8au, gs_regs[2],
gs_regs[3]); // SPI_SHADER_PGM_RSRC1_GS/SPI_SHADER_PGM_RSRC2_GS
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2e5u, gs_regs[4]); // VGT_STRMOUT_CONFIG
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x29bu, gs_regs[5]); // VGT_GS_OUT_PRIM_TYPE
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2e4u, gs_regs[6]); // VGT_GS_INSTANCE_CNT
WriteTrailingNop<11>(cmdbuf);
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmSetHsShader() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
s32 PS4_SYSV_ABI sceGnmSetHsShader(u32* cmdbuf, u32 size, const u32* hs_regs, u32 param4) {
LOG_TRACE(Lib_GnmDriver, "called");
if (!cmdbuf || size < 0x1E) {
return -1;
}
if (!hs_regs) {
LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument");
return -1;
}
if (hs_regs[1] != 0) {
LOG_ERROR(Lib_GnmDriver, "Invalid shader address");
return -1;
}
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x108u, hs_regs[0], 0u); // SPI_SHADER_PGM_LO_HS
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x10au, hs_regs[2],
hs_regs[3]); // SPI_SHADER_PGM_RSRC1_HS/SPI_SHADER_PGM_RSRC2_HS
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x286u, hs_regs[5],
hs_regs[5]); // VGT_HOS_MAX_TESS_LEVEL
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2dbu, hs_regs[4]); // VGT_TF_PARAM
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x2d6u, param4); // VGT_LS_HS_CONFIG
WriteTrailingNop<11>(cmdbuf);
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmSetLsShader() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
s32 PS4_SYSV_ABI sceGnmSetLsShader(u32* cmdbuf, u32 size, const u32* ls_regs, u32 shader_modifier) {
LOG_TRACE(Lib_GnmDriver, "called");
if (!cmdbuf || size < 0x17) {
return -1;
}
if (!ls_regs) {
LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument");
return -1;
}
const auto modifier_mask = ((shader_modifier & 0xfffffc3f) == 0) ? 0xfffffc3f : 0xfcfffc3f;
if (shader_modifier & modifier_mask) {
LOG_ERROR(Lib_GnmDriver, "Invalid modifier mask");
return -1;
}
if (ls_regs[1] != 0) {
LOG_ERROR(Lib_GnmDriver, "Invalid shader address");
return -1;
}
const u32 var =
shader_modifier == 0 ? ls_regs[2] : ((ls_regs[2] & modifier_mask) | shader_modifier);
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x148u, ls_regs[0], 0u); // SPI_SHADER_PGM_LO_LS
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x14bu, ls_regs[3]); // SPI_SHADER_PGM_RSRC2_LS
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x14au, var, ls_regs[3]); // SPI_SHADER_PGM_RSRC1_LS
WriteTrailingNop<11>(cmdbuf);
return ORBIS_OK;
}
@ -1523,9 +1623,9 @@ s32 PS4_SYSV_ABI sceGnmSetPsShader(u32* cmdbuf, u32 size, const u32* ps_regs) {
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
cmdbuf = PM4CmdSetData::SetShReg(
cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
cmdbuf =
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
cmdbuf = PM4CmdSetData::SetContextReg(
cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
@ -1561,9 +1661,9 @@ s32 PS4_SYSV_ABI sceGnmSetPsShader350(u32* cmdbuf, u32 size, const u32* ps_regs)
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
cmdbuf = PM4CmdSetData::SetShReg(
cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
cmdbuf =
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
cmdbuf = PM4CmdSetData::SetContextReg(
cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
@ -2052,8 +2152,34 @@ int PS4_SYSV_ABI sceGnmUnregisterResource() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmUpdateGsShader() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
s32 PS4_SYSV_ABI sceGnmUpdateGsShader(u32* cmdbuf, u32 size, const u32* gs_regs) {
LOG_TRACE(Lib_GnmDriver, "called");
if (!cmdbuf || size < 0x1d) {
return -1;
}
if (!gs_regs) {
LOG_ERROR(Lib_GnmDriver, "Null pointer passed as argument");
return -1;
}
if (gs_regs[1] != 0) {
LOG_ERROR(Lib_GnmDriver, "Invalid shader address");
return -1;
}
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x88u, gs_regs[0], 0u); // SPI_SHADER_PGM_LO_GS
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x8au, gs_regs[2],
gs_regs[3]); // SPI_SHADER_PGM_RSRC1_GS/SPI_SHADER_PGM_RSRC2_GS
cmdbuf = WritePacket<PM4ItOpcode::Nop>(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e02e5u,
gs_regs[4]);
cmdbuf = WritePacket<PM4ItOpcode::Nop>(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e029bu,
gs_regs[5]);
cmdbuf = WritePacket<PM4ItOpcode::Nop>(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e02e4u,
gs_regs[6]);
WriteTrailingNop<11>(cmdbuf);
return ORBIS_OK;
}
@ -2082,9 +2208,9 @@ s32 PS4_SYSV_ABI sceGnmUpdatePsShader(u32* cmdbuf, u32 size, const u32* ps_regs)
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
cmdbuf = PM4CmdSetData::SetShReg(
cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
cmdbuf =
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
cmdbuf = WritePacket<PM4ItOpcode::Nop>(
cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4],
ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT update
@ -2127,9 +2253,9 @@ s32 PS4_SYSV_ABI sceGnmUpdatePsShader350(u32* cmdbuf, u32 size, const u32* ps_re
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
cmdbuf = PM4CmdSetData::SetShReg(
cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
cmdbuf =
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
cmdbuf = WritePacket<PM4ItOpcode::Nop>(
cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4],
ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT update
@ -2173,7 +2299,8 @@ s32 PS4_SYSV_ABI sceGnmUpdateVsShader(u32* cmdbuf, u32 size, const u32* vs_regs,
return -1;
}
const u32 var = shader_modifier == 0 ? vs_regs[2] : (vs_regs[2] & 0xfcfffc3f | shader_modifier);
const u32 var =
shader_modifier == 0 ? vs_regs[2] : ((vs_regs[2] & 0xfcfffc3f) | shader_modifier);
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], 0u); // SPI_SHADER_PGM_LO_VS
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS
cmdbuf = WritePacket<PM4ItOpcode::Nop>(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0207u,

View file

@ -149,11 +149,11 @@ s32 PS4_SYSV_ABI sceGnmSetCsShaderWithModifier(u32* cmdbuf, u32 size, const u32*
s32 PS4_SYSV_ABI sceGnmSetEmbeddedPsShader(u32* cmdbuf, u32 size, u32 shader_id,
u32 shader_modifier);
s32 PS4_SYSV_ABI sceGnmSetEmbeddedVsShader(u32* cmdbuf, u32 size, u32 shader_id, u32 modifier);
int PS4_SYSV_ABI sceGnmSetEsShader();
s32 PS4_SYSV_ABI sceGnmSetEsShader(u32* cmdbuf, u32 size, const u32* es_regs, u32 shader_modifier);
int PS4_SYSV_ABI sceGnmSetGsRingSizes();
int PS4_SYSV_ABI sceGnmSetGsShader();
int PS4_SYSV_ABI sceGnmSetHsShader();
int PS4_SYSV_ABI sceGnmSetLsShader();
s32 PS4_SYSV_ABI sceGnmSetGsShader(u32* cmdbuf, u32 size, const u32* gs_regs);
s32 PS4_SYSV_ABI sceGnmSetHsShader(u32* cmdbuf, u32 size, const u32* hs_regs, u32 param4);
s32 PS4_SYSV_ABI sceGnmSetLsShader(u32* cmdbuf, u32 size, const u32* ls_regs, u32 shader_modifier);
s32 PS4_SYSV_ABI sceGnmSetPsShader(u32* cmdbuf, u32 size, const u32* ps_regs);
s32 PS4_SYSV_ABI sceGnmSetPsShader350(u32* cmdbuf, u32 size, const u32* ps_regs);
int PS4_SYSV_ABI sceGnmSetResourceRegistrationUserMemory();
@ -216,7 +216,7 @@ int PS4_SYSV_ABI sceGnmUnmapComputeQueue();
int PS4_SYSV_ABI sceGnmUnregisterAllResourcesForOwner();
int PS4_SYSV_ABI sceGnmUnregisterOwnerAndResources();
int PS4_SYSV_ABI sceGnmUnregisterResource();
int PS4_SYSV_ABI sceGnmUpdateGsShader();
s32 PS4_SYSV_ABI sceGnmUpdateGsShader(u32* cmdbuf, u32 size, const u32* gs_regs);
int PS4_SYSV_ABI sceGnmUpdateHsShader();
s32 PS4_SYSV_ABI sceGnmUpdatePsShader(u32* cmdbuf, u32 size, const u32* ps_regs);
s32 PS4_SYSV_ABI sceGnmUpdatePsShader350(u32* cmdbuf, u32 size, const u32* ps_regs);