Merge pull request #287 from polybiusproxy/dev
gnmdriver: Implement shader functions
This commit is contained in:
commit
c49afb4c17
|
@ -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.
|
// repeat set shader functionality here as it is trivial.
|
||||||
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
|
||||||
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
||||||
cmdbuf =
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
|
||||||
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
|
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
|
||||||
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
|
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c4u, ps_regs[4],
|
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c4u, ps_regs[4],
|
||||||
ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
|
ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
|
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
|
||||||
|
@ -1468,8 +1467,8 @@ 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
|
// 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.
|
// 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, 0x48u, vs_regs[0], vs_regs[1]); // SPI_SHADER_PGM_LO_VS
|
||||||
cmdbuf =
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, vs_regs[2],
|
||||||
PM4CmdSetData::SetShReg(cmdbuf, 0x4au, vs_regs[2], vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS
|
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, 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, 0x1b1u, vs_regs[4]); // SPI_VS_OUT_CONFIG
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c3u, vs_regs[5]); // SPI_SHADER_POS_FORMAT
|
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1c3u, vs_regs[5]); // SPI_SHADER_POS_FORMAT
|
||||||
|
@ -1478,8 +1477,34 @@ s32 PS4_SYSV_ABI sceGnmSetEmbeddedVsShader(u32* cmdbuf, u32 size, u32 shader_id,
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmSetEsShader() {
|
s32 PS4_SYSV_ABI sceGnmSetEsShader(u32* cmdbuf, u32 size, const u32* es_regs, u32 shader_modifier) {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
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;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1488,18 +1513,93 @@ int PS4_SYSV_ABI sceGnmSetGsRingSizes() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmSetGsShader() {
|
s32 PS4_SYSV_ABI sceGnmSetGsShader(u32* cmdbuf, u32 size, const u32* gs_regs) {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
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;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmSetHsShader() {
|
s32 PS4_SYSV_ABI sceGnmSetHsShader(u32* cmdbuf, u32 size, const u32* hs_regs, u32 param4) {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
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;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmSetLsShader() {
|
s32 PS4_SYSV_ABI sceGnmSetLsShader(u32* cmdbuf, u32 size, const u32* ls_regs, u32 shader_modifier) {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
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;
|
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],
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
|
||||||
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
||||||
cmdbuf = PM4CmdSetData::SetShReg(
|
cmdbuf =
|
||||||
cmdbuf, 10u, ps_regs[2],
|
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
|
||||||
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
|
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(
|
cmdbuf = PM4CmdSetData::SetContextReg(
|
||||||
cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
|
cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
|
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],
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
|
||||||
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
||||||
cmdbuf = PM4CmdSetData::SetShReg(
|
cmdbuf =
|
||||||
cmdbuf, 10u, ps_regs[2],
|
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
|
||||||
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
|
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(
|
cmdbuf = PM4CmdSetData::SetContextReg(
|
||||||
cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
|
cmdbuf, 0x1c4u, ps_regs[4], ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
|
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x1b3u, ps_regs[6],
|
||||||
|
@ -2052,8 +2152,34 @@ int PS4_SYSV_ABI sceGnmUnregisterResource() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmUpdateGsShader() {
|
s32 PS4_SYSV_ABI sceGnmUpdateGsShader(u32* cmdbuf, u32 size, const u32* gs_regs) {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
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;
|
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],
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
|
||||||
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
||||||
cmdbuf = PM4CmdSetData::SetShReg(
|
cmdbuf =
|
||||||
cmdbuf, 10u, ps_regs[2],
|
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
|
||||||
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
|
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
|
||||||
cmdbuf = WritePacket<PM4ItOpcode::Nop>(
|
cmdbuf = WritePacket<PM4ItOpcode::Nop>(
|
||||||
cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4],
|
cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4],
|
||||||
ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT update
|
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],
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 8u, ps_regs[0],
|
||||||
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
0u); // SPI_SHADER_PGM_LO_PS/SPI_SHADER_PGM_HI_PS
|
||||||
cmdbuf = PM4CmdSetData::SetShReg(
|
cmdbuf =
|
||||||
cmdbuf, 10u, ps_regs[2],
|
PM4CmdSetData::SetShReg(cmdbuf, 10u, ps_regs[2],
|
||||||
ps_regs[3]); // SPI_SHADER_USER_DATA_PS_4/SPI_SHADER_USER_DATA_PS_5
|
ps_regs[3]); // SPI_SHADER_PGM_RSRC1_PS/SPI_SHADER_PGM_RSRC2_PS
|
||||||
cmdbuf = WritePacket<PM4ItOpcode::Nop>(
|
cmdbuf = WritePacket<PM4ItOpcode::Nop>(
|
||||||
cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4],
|
cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e01c4u, ps_regs[4],
|
||||||
ps_regs[5]); // SPI_SHADER_Z_FORMAT/SPI_SHADER_COL_FORMAT update
|
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;
|
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, 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 = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS
|
||||||
cmdbuf = WritePacket<PM4ItOpcode::Nop>(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0207u,
|
cmdbuf = WritePacket<PM4ItOpcode::Nop>(cmdbuf, PM4ShaderType::ShaderGraphics, 0xc01e0207u,
|
||||||
|
|
|
@ -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,
|
s32 PS4_SYSV_ABI sceGnmSetEmbeddedPsShader(u32* cmdbuf, u32 size, u32 shader_id,
|
||||||
u32 shader_modifier);
|
u32 shader_modifier);
|
||||||
s32 PS4_SYSV_ABI sceGnmSetEmbeddedVsShader(u32* cmdbuf, u32 size, u32 shader_id, u32 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 sceGnmSetGsRingSizes();
|
||||||
int PS4_SYSV_ABI sceGnmSetGsShader();
|
s32 PS4_SYSV_ABI sceGnmSetGsShader(u32* cmdbuf, u32 size, const u32* gs_regs);
|
||||||
int PS4_SYSV_ABI sceGnmSetHsShader();
|
s32 PS4_SYSV_ABI sceGnmSetHsShader(u32* cmdbuf, u32 size, const u32* hs_regs, u32 param4);
|
||||||
int PS4_SYSV_ABI sceGnmSetLsShader();
|
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 sceGnmSetPsShader(u32* cmdbuf, u32 size, const u32* ps_regs);
|
||||||
s32 PS4_SYSV_ABI sceGnmSetPsShader350(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();
|
int PS4_SYSV_ABI sceGnmSetResourceRegistrationUserMemory();
|
||||||
|
@ -216,7 +216,7 @@ int PS4_SYSV_ABI sceGnmUnmapComputeQueue();
|
||||||
int PS4_SYSV_ABI sceGnmUnregisterAllResourcesForOwner();
|
int PS4_SYSV_ABI sceGnmUnregisterAllResourcesForOwner();
|
||||||
int PS4_SYSV_ABI sceGnmUnregisterOwnerAndResources();
|
int PS4_SYSV_ABI sceGnmUnregisterOwnerAndResources();
|
||||||
int PS4_SYSV_ABI sceGnmUnregisterResource();
|
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();
|
int PS4_SYSV_ABI sceGnmUpdateHsShader();
|
||||||
s32 PS4_SYSV_ABI sceGnmUpdatePsShader(u32* cmdbuf, u32 size, const u32* ps_regs);
|
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);
|
s32 PS4_SYSV_ABI sceGnmUpdatePsShader350(u32* cmdbuf, u32 size, const u32* ps_regs);
|
||||||
|
|
|
@ -13,10 +13,12 @@ std::string_view StageName(Stage stage) {
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case Stage::Vertex:
|
case Stage::Vertex:
|
||||||
return "vs";
|
return "vs";
|
||||||
case Stage::TessellationControl:
|
case Stage::Local:
|
||||||
return "tcs";
|
return "ls";
|
||||||
case Stage::TessellationEval:
|
case Stage::Export:
|
||||||
return "tes";
|
return "es";
|
||||||
|
case Stage::Hull:
|
||||||
|
return "hs";
|
||||||
case Stage::Geometry:
|
case Stage::Geometry:
|
||||||
return "gs";
|
return "gs";
|
||||||
case Stage::Fragment:
|
case Stage::Fragment:
|
||||||
|
|
|
@ -17,11 +17,12 @@ namespace Shader {
|
||||||
static constexpr size_t NumUserDataRegs = 16;
|
static constexpr size_t NumUserDataRegs = 16;
|
||||||
|
|
||||||
enum class Stage : u32 {
|
enum class Stage : u32 {
|
||||||
Vertex,
|
|
||||||
TessellationControl,
|
|
||||||
TessellationEval,
|
|
||||||
Geometry,
|
|
||||||
Fragment,
|
Fragment,
|
||||||
|
Vertex,
|
||||||
|
Geometry,
|
||||||
|
Export,
|
||||||
|
Hull,
|
||||||
|
Local,
|
||||||
Compute,
|
Compute,
|
||||||
};
|
};
|
||||||
constexpr u32 MaxStageTypes = 6;
|
constexpr u32 MaxStageTypes = 6;
|
||||||
|
@ -204,7 +205,7 @@ struct fmt::formatter<Shader::Stage> {
|
||||||
return ctx.begin();
|
return ctx.begin();
|
||||||
}
|
}
|
||||||
auto format(const Shader::Stage& stage, format_context& ctx) const {
|
auto format(const Shader::Stage& stage, format_context& ctx) const {
|
||||||
constexpr static std::array names = {"vs", "tc", "te", "gs", "fs", "cs"};
|
constexpr static std::array names = {"fs", "vs", "gs", "es", "hs", "ls", "cs"};
|
||||||
return fmt::format_to(ctx.out(), "{}", names[static_cast<size_t>(stage)]);
|
return fmt::format_to(ctx.out(), "{}", names[static_cast<size_t>(stage)]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -837,7 +837,15 @@ struct Liverpool {
|
||||||
ShaderProgram ps_program;
|
ShaderProgram ps_program;
|
||||||
INSERT_PADDING_WORDS(0x2C);
|
INSERT_PADDING_WORDS(0x2C);
|
||||||
ShaderProgram vs_program;
|
ShaderProgram vs_program;
|
||||||
INSERT_PADDING_WORDS(0x2E00 - 0x2C4C - 16);
|
INSERT_PADDING_WORDS(0x2C);
|
||||||
|
ShaderProgram gs_program;
|
||||||
|
INSERT_PADDING_WORDS(0x2C);
|
||||||
|
ShaderProgram es_program;
|
||||||
|
INSERT_PADDING_WORDS(0x2C);
|
||||||
|
ShaderProgram hs_program;
|
||||||
|
INSERT_PADDING_WORDS(0x2C);
|
||||||
|
ShaderProgram ls_program;
|
||||||
|
INSERT_PADDING_WORDS(0xA4);
|
||||||
ComputeProgram cs_program;
|
ComputeProgram cs_program;
|
||||||
INSERT_PADDING_WORDS(0xA008 - 0x2E00 - 80 - 3 - 5);
|
INSERT_PADDING_WORDS(0xA008 - 0x2E00 - 80 - 3 - 5);
|
||||||
DepthRenderControl depth_render_control;
|
DepthRenderControl depth_render_control;
|
||||||
|
@ -916,12 +924,19 @@ struct Liverpool {
|
||||||
const ShaderProgram* ProgramForStage(u32 index) const {
|
const ShaderProgram* ProgramForStage(u32 index) const {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
return &vs_program;
|
|
||||||
case 4:
|
|
||||||
return &ps_program;
|
return &ps_program;
|
||||||
default:
|
case 1:
|
||||||
return nullptr;
|
return &vs_program;
|
||||||
|
case 2:
|
||||||
|
return &gs_program;
|
||||||
|
case 3:
|
||||||
|
return &es_program;
|
||||||
|
case 4:
|
||||||
|
return &hs_program;
|
||||||
|
case 5:
|
||||||
|
return &ls_program;
|
||||||
}
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1026,6 +1041,10 @@ private:
|
||||||
static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08);
|
static_assert(GFX6_3D_REG_INDEX(ps_program) == 0x2C08);
|
||||||
static_assert(GFX6_3D_REG_INDEX(vs_program) == 0x2C48);
|
static_assert(GFX6_3D_REG_INDEX(vs_program) == 0x2C48);
|
||||||
static_assert(GFX6_3D_REG_INDEX(vs_program.user_data) == 0x2C4C);
|
static_assert(GFX6_3D_REG_INDEX(vs_program.user_data) == 0x2C4C);
|
||||||
|
static_assert(GFX6_3D_REG_INDEX(gs_program) == 0x2C88);
|
||||||
|
static_assert(GFX6_3D_REG_INDEX(es_program) == 0x2CC8);
|
||||||
|
static_assert(GFX6_3D_REG_INDEX(hs_program) == 0x2D08);
|
||||||
|
static_assert(GFX6_3D_REG_INDEX(ls_program) == 0x2D48);
|
||||||
static_assert(GFX6_3D_REG_INDEX(cs_program) == 0x2E00);
|
static_assert(GFX6_3D_REG_INDEX(cs_program) == 0x2E00);
|
||||||
static_assert(GFX6_3D_REG_INDEX(cs_program.dim_z) == 0x2E03);
|
static_assert(GFX6_3D_REG_INDEX(cs_program.dim_z) == 0x2E03);
|
||||||
static_assert(GFX6_3D_REG_INDEX(cs_program.address_lo) == 0x2E0C);
|
static_assert(GFX6_3D_REG_INDEX(cs_program.address_lo) == 0x2E0C);
|
||||||
|
|
|
@ -48,7 +48,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
|
||||||
|
|
||||||
boost::container::static_vector<vk::VertexInputBindingDescription, 32> bindings;
|
boost::container::static_vector<vk::VertexInputBindingDescription, 32> bindings;
|
||||||
boost::container::static_vector<vk::VertexInputAttributeDescription, 32> attributes;
|
boost::container::static_vector<vk::VertexInputAttributeDescription, 32> attributes;
|
||||||
const auto& vs_info = stages[0];
|
const auto& vs_info = stages[u32(Shader::Stage::Vertex)];
|
||||||
for (const auto& input : vs_info.vs_inputs) {
|
for (const auto& input : vs_info.vs_inputs) {
|
||||||
if (input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate0 ||
|
if (input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate0 ||
|
||||||
input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate1) {
|
input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate1) {
|
||||||
|
@ -179,20 +179,21 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
|
||||||
.maxDepthBounds = key.depth_bounds_max,
|
.maxDepthBounds = key.depth_bounds_max,
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 shader_count = 1;
|
u32 shader_count{};
|
||||||
|
auto stage = u32(Shader::Stage::Vertex);
|
||||||
std::array<vk::PipelineShaderStageCreateInfo, MaxShaderStages> shader_stages;
|
std::array<vk::PipelineShaderStageCreateInfo, MaxShaderStages> shader_stages;
|
||||||
shader_stages[0] = vk::PipelineShaderStageCreateInfo{
|
shader_stages[shader_count++] = vk::PipelineShaderStageCreateInfo{
|
||||||
.stage = vk::ShaderStageFlagBits::eVertex,
|
.stage = vk::ShaderStageFlagBits::eVertex,
|
||||||
.module = modules[0],
|
.module = modules[stage],
|
||||||
.pName = "main",
|
.pName = "main",
|
||||||
};
|
};
|
||||||
if (modules[4]) {
|
stage = u32(Shader::Stage::Fragment);
|
||||||
shader_stages[1] = vk::PipelineShaderStageCreateInfo{
|
if (modules[stage]) {
|
||||||
|
shader_stages[shader_count++] = vk::PipelineShaderStageCreateInfo{
|
||||||
.stage = vk::ShaderStageFlagBits::eFragment,
|
.stage = vk::ShaderStageFlagBits::eFragment,
|
||||||
.module = modules[4],
|
.module = modules[stage],
|
||||||
.pName = "main",
|
.pName = "main",
|
||||||
};
|
};
|
||||||
++shader_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto it = std::ranges::find(key.color_formats, vk::Format::eUndefined);
|
const auto it = std::ranges::find(key.color_formats, vk::Format::eUndefined);
|
||||||
|
@ -411,7 +412,7 @@ void GraphicsPipeline::BindResources(Core::MemoryManager* memory, StreamBuffer&
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPipeline::BindVertexBuffers(StreamBuffer& staging) const {
|
void GraphicsPipeline::BindVertexBuffers(StreamBuffer& staging) const {
|
||||||
const auto& vs_info = stages[0];
|
const auto& vs_info = stages[u32(Shader::Stage::Vertex)];
|
||||||
if (vs_info.vs_inputs.empty()) {
|
if (vs_info.vs_inputs.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
bool IsEmbeddedVs() const noexcept {
|
bool IsEmbeddedVs() const noexcept {
|
||||||
static constexpr size_t EmbeddedVsHash = 0x9b2da5cf47f8c29f;
|
static constexpr size_t EmbeddedVsHash = 0x9b2da5cf47f8c29f;
|
||||||
return key.stage_hashes[0] == EmbeddedVsHash;
|
return key.stage_hashes[u32(Shader::Stage::Vertex)] == EmbeddedVsHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GetWriteMasks() const {
|
auto GetWriteMasks() const {
|
||||||
|
|
|
@ -256,6 +256,12 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
|
||||||
block_pool.ReleaseContents();
|
block_pool.ReleaseContents();
|
||||||
inst_pool.ReleaseContents();
|
inst_pool.ReleaseContents();
|
||||||
|
|
||||||
|
if (stage != Shader::Stage::Compute && stage != Shader::Stage::Fragment &&
|
||||||
|
stage != Shader::Stage::Vertex) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Unsupported shader stage {}. PL creation skipped.", stage);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// Recompile shader to IR.
|
// Recompile shader to IR.
|
||||||
try {
|
try {
|
||||||
LOG_INFO(Render_Vulkan, "Compiling {} shader {:#x}", stage, hash);
|
LOG_INFO(Render_Vulkan, "Compiling {} shader {:#x}", stage, hash);
|
||||||
|
|
Loading…
Reference in New Issue