Feature/mpeg decoder (#120)

* feat: added ffmepg as dependency

* feat: wip decoder video

* feat: some perf and cleanup

* feat:  added generic MPEG stream notification

* feat: CMakeLists.txt in ps2xStudio to configure SDL2 build options for static linking.
fix: fix ffmpeg setup for linux
fix: now MPEG decoder now identify that movie has ended and can play again anytime
feat: better audio stub to not block games

* feat: fix expansion test

* feat: foo

* a

* feat: finally added a helper to to prevent thread starvation

* feat: added basic  vu0 code execution

* feat: added yield Guest Execution After Wake to prevent deadlock

* feat: added  options  on  cmake for logs
feat: better input for keyboard pad

* feat: small corrections like top and itop vu branches etc

* feat: changes

* feat: working feature

* feat: fatal frame iop

* feat: test fix
feat: z buffer fix

* fix: gix GsPutIMR IMR

* feat: added rl imgui

* feat: added helper to get snapshot

* feat: added debug panel consuming snapshots

* feat: added pad snapshot
feat: added RCP debug events

* feat: final cleanup from old code

* feat: added EE timer counter
feat: applyed sound driver for Lotr
feat: better check for sound driver compat layout
feat: enquee and cosumed DMa cause
feat: added Pad execCMd
feat: update GS vsync signal flag
feat: custom IOPs for LotR

* feat: small cleanups

* fix: fix wrong import
This commit is contained in:
Ranieri
2026-06-26 21:04:39 -03:00
committed by GitHub
parent a111059a70
commit 8c8a97af65
65 changed files with 10749 additions and 1766 deletions
+96 -50
View File
@@ -65,6 +65,15 @@ namespace ps2recomp
return literal;
}
static std::string vuMaskExpr(uint8_t dest_mask)
{
return fmt::format("_mm_castsi128_ps(_mm_set_epi32({}, {}, {}, {}))",
(dest_mask & 0x1) ? -1 : 0,
(dest_mask & 0x2) ? -1 : 0,
(dest_mask & 0x4) ? -1 : 0,
(dest_mask & 0x8) ? -1 : 0);
}
static std::string sanitizeIdentifierBody(const std::string &name)
{
std::string sanitized;
@@ -2532,9 +2541,31 @@ namespace ps2recomp
inst.rt, inst.rt);
}
case VU0_S2_VMOVE:
return fmt::format("ctx->vu0_vf[{}] = ctx->vu0_vf[{}];", inst.rt, inst.rd);
{
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format(
"{{ __m128i mask = _mm_set_epi32({}, {}, {}, {}); "
"ctx->vu0_vf[{}] = _mm_blendv_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], _mm_castsi128_ps(mask)); }}",
(dest_mask & 0x1) ? -1 : 0,
(dest_mask & 0x2) ? -1 : 0,
(dest_mask & 0x4) ? -1 : 0,
(dest_mask & 0x8) ? -1 : 0,
inst.rt, inst.rt, inst.rd);
}
case VU0_S2_VMR32:
return fmt::format("ctx->vu0_vf[{}] = _mm_shuffle_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], _MM_SHUFFLE(0,0,0,1));", inst.rt, inst.rd, inst.rd);
{
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format(
"{{ __m128 res = _mm_shuffle_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], _MM_SHUFFLE(0,3,2,1)); "
"__m128i mask = _mm_set_epi32({}, {}, {}, {}); "
"ctx->vu0_vf[{}] = _mm_blendv_ps(ctx->vu0_vf[{}], res, _mm_castsi128_ps(mask)); }}",
inst.rd, inst.rd,
(dest_mask & 0x1) ? -1 : 0,
(dest_mask & 0x2) ? -1 : 0,
(dest_mask & 0x4) ? -1 : 0,
(dest_mask & 0x8) ? -1 : 0,
inst.rt, inst.rt);
}
case VU0_S2_VCLIPw:
{
uint8_t field = inst.function & 0x3;
@@ -3519,186 +3550,201 @@ namespace ps2recomp
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
uint8_t dest_mask = inst.vectorInfo.vectorField;
uint8_t field = inst.function & 0x3;
std::string shuffle_pattern = fmt::format("_MM_SHUFFLE({},{},{},{})", field, field, field, field);
return fmt::format("{{ __m128 res = PS2_VADD(ctx->vu0_vf[{}], _mm_shuffle_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], {})); "
"ctx->vu0_acc = res; }}",
vfs, vft, vft, shuffle_pattern);
"ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vft, shuffle_pattern, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VSUBA_Field(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
uint8_t dest_mask = inst.vectorInfo.vectorField;
uint8_t field = inst.function & 0x3;
std::string shuffle_pattern = fmt::format("_MM_SHUFFLE({},{},{},{})", field, field, field, field);
return fmt::format("{{ __m128 res = PS2_VSUB(ctx->vu0_vf[{}], _mm_shuffle_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], {})); "
"ctx->vu0_acc = res; }}",
vfs, vft, vft, shuffle_pattern);
"ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vft, shuffle_pattern, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMADDA_Field(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
uint8_t dest_mask = inst.vectorInfo.vectorField;
uint8_t field = inst.function & 0x3;
std::string shuffle_pattern = fmt::format("_MM_SHUFFLE({},{},{},{})", field, field, field, field);
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_shuffle_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], {})); "
"__m128 res = PS2_VADD(ctx->vu0_acc, mul_res); "
"ctx->vu0_acc = res; }}",
vfs, vft, vft, shuffle_pattern);
"ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vft, shuffle_pattern, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMSUBA_Field(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
uint8_t dest_mask = inst.vectorInfo.vectorField;
uint8_t field = inst.function & 0x3;
std::string shuffle_pattern = fmt::format("_MM_SHUFFLE({},{},{},{})", field, field, field, field);
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_shuffle_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], {})); "
"__m128 res = PS2_VSUB(ctx->vu0_acc, mul_res); "
"ctx->vu0_acc = res; }}",
vfs, vft, vft, shuffle_pattern);
"ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vft, shuffle_pattern, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMULA_Field(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
uint8_t dest_mask = inst.vectorInfo.vectorField;
uint8_t field = inst.function & 0x3;
std::string shuffle_pattern = fmt::format("_MM_SHUFFLE({},{},{},{})", field, field, field, field);
return fmt::format("{{ __m128 res = PS2_VMUL(ctx->vu0_vf[{}], _mm_shuffle_ps(ctx->vu0_vf[{}], ctx->vu0_vf[{}], {})); "
"ctx->vu0_acc = res; }}",
vfs, vft, vft, shuffle_pattern);
"ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vft, shuffle_pattern, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VADDA(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
return fmt::format("ctx->vu0_acc = PS2_VADD(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
vfs, vft);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VADD(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VADDAq(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("ctx->vu0_acc = PS2_VADD(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q));",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VADD(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q)); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VADDAi(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("ctx->vu0_acc = PS2_VADD(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i));",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VADD(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i)); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VSUBA(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
return fmt::format("ctx->vu0_acc = PS2_VSUB(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
vfs, vft);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VSUB(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VSUBAq(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("ctx->vu0_acc = PS2_VSUB(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q));",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VSUB(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q)); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VSUBAi(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("ctx->vu0_acc = PS2_VSUB(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i));",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VSUB(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i)); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMADDA(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); "
"ctx->vu0_acc = PS2_VADD(ctx->vu0_acc, mul_res); }}",
vfs, vft);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); __m128 res = PS2_VADD(ctx->vu0_acc, mul_res); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMADDAq(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q)); "
"ctx->vu0_acc = PS2_VADD(ctx->vu0_acc, mul_res); }}",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q)); __m128 res = PS2_VADD(ctx->vu0_acc, mul_res); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMADDAi(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i)); "
"ctx->vu0_acc = PS2_VADD(ctx->vu0_acc, mul_res); }}",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i)); __m128 res = PS2_VADD(ctx->vu0_acc, mul_res); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMSUBA(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); "
"ctx->vu0_acc = PS2_VSUB(ctx->vu0_acc, mul_res); }}",
vfs, vft);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); __m128 res = PS2_VSUB(ctx->vu0_acc, mul_res); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMSUBAq(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q)); "
"ctx->vu0_acc = PS2_VSUB(ctx->vu0_acc, mul_res); }}",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q)); __m128 res = PS2_VSUB(ctx->vu0_acc, mul_res); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMSUBAi(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i)); "
"ctx->vu0_acc = PS2_VSUB(ctx->vu0_acc, mul_res); }}",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 mul_res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i)); __m128 res = PS2_VSUB(ctx->vu0_acc, mul_res); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMULA(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
return fmt::format("ctx->vu0_acc = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
vfs, vft);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMULAq(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("ctx->vu0_acc = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q));",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_q)); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VMULAi(const Instruction &inst)
{
uint8_t vfs = inst.rd;
return fmt::format("ctx->vu0_acc = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i));",
vfs);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VMUL(ctx->vu0_vf[{}], _mm_set1_ps(ctx->vu0_i)); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VOPMULA(const Instruction &inst)
{
uint8_t vfs = inst.rd;
uint8_t vft = inst.rt;
return fmt::format("ctx->vu0_acc = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
vfs, vft);
uint8_t dest_mask = inst.vectorInfo.vectorField;
return fmt::format("{{ __m128 res = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]); ctx->vu0_acc = _mm_blendv_ps(ctx->vu0_acc, res, {}); }}",
vfs, vft, vuMaskExpr(dest_mask));
}
std::string CodeGenerator::translateVU_VITOF(const Instruction &inst, int shift)