diff options
| author | Braden <Bradenb95@gmail.com> | 2013-03-17 21:10:54 -0500 |
|---|---|---|
| committer | Braden <Bradenb95@gmail.com> | 2013-03-17 21:10:54 -0500 |
| commit | f21706bc178b1594be60c1ea3f12cdecbed41897 (patch) | |
| tree | e737cdde96fbce0afa924d713525135cc8720488 /Source | |
| parent | ae3c5a64cc404d4fa9051e8a159935081f57de7e (diff) | |
| parent | 9ae991049040348b2f0848ba3077426a38be4fdb (diff) | |
Git pull
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Core/Common/Src/ArmEmitter.cpp | 322 | ||||
| -rw-r--r-- | Source/Core/Common/Src/ArmEmitter.h | 15 | ||||
| -rw-r--r-- | Source/Core/Common/Src/StringUtil.cpp | 4 | ||||
| -rw-r--r-- | Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp | 14 | ||||
| -rw-r--r-- | Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h | 2 | ||||
| -rw-r--r-- | Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 57 | ||||
| -rw-r--r-- | Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp | 4 | ||||
| -rw-r--r-- | Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp | 8 |
8 files changed, 113 insertions, 313 deletions
diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp index 10c72cf39f..c3c9f0d0f8 100644 --- a/Source/Core/Common/Src/ArmEmitter.cpp +++ b/Source/Core/Common/Src/ArmEmitter.cpp @@ -820,25 +820,25 @@ void ARMXEmitter::VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) // VFP Specific struct VFPEnc { - u16 opc1; - u16 opc2; + s16 opc1; + s16 opc2; }; // Double/single, Neon const VFPEnc VFPOps[][2] = { - {{0xE0, 0xA0}, {0x20, 0xD1}}, // VMLA - {{0xE0, 0xA4}, {0x22, 0xD1}}, // VMLS - {{0xE3, 0xA0}, {0x20, 0xD0}}, // VADD - {{0xE3, 0xA4}, {0x22, 0xD0}}, // VSUB - {{0xE2, 0xA0}, {0x30, 0xD1}}, // VMUL - {{0xEB, 0xAC}, {0x3B, 0x30}}, // VABS - {{0xE8, 0xA0}, { -1, -1}}, // VDIV - {{0xEB, 0xA4}, { -1, -1}}, // VNEG - {{0xEB, 0xAC}, { -1, -1}}, // VSQRT - {{0xED, 0xA2}, { -1, -1}}, // VCMP - {{0xED, 0xAA}, { -1, -1}}, // VCMPE - {{ -1, -1}, {0x3B, 0x70}}, // VABSi + {{0xE0, 0xA0}, {0x20, 0xD1}}, // 0: VMLA + {{0xE0, 0xA4}, {0x22, 0xD1}}, // 1: VMLS + {{0xE3, 0xA0}, {0x20, 0xD0}}, // 2: VADD + {{0xE3, 0xA4}, {0x22, 0xD0}}, // 3: VSUB + {{0xE2, 0xA0}, {0x30, 0xD1}}, // 4: VMUL + {{0xEB, 0xAC}, { -1 /* 0x3B */, -1 /* 0x70 */}}, // 5: VABS(Vn(0x0) used for encoding) + {{0xE8, 0xA0}, { -1, -1}}, // 6: VDIV + {{0xEB, 0xA4}, { -1 /* 0x3B */, -1 /* 0x78 */}}, // 7: VNEG(Vn(0x1) used for encoding) + {{0xEB, 0xAC}, { -1, -1}}, // 8: VSQRT (Vn(0x1) used for encoding) + {{0xEB, 0xA4}, { -1, -1}}, // 9: VCMP (Vn(0x4 | #0 ? 1 : 0) used for encoding) + {{0xEB, 0xAC}, { -1, -1}}, // 10: VCMPE (Vn(0x4 | #0 ? 1 : 0) used for encoding) + {{ -1, -1}, {0x3B, 0x30}}, // 11: VABSi }; -const char *VFPOps[] = { +const char *VFPOpNames[] = { "VMLA", "VMLS", "VADD", @@ -861,10 +861,10 @@ u32 ARMXEmitter::EncodeVd(ARMReg Vd) ARMReg Reg = SubBase(Vd); if (quad_reg) - ((Reg & 0x10) << 18) | ((Reg & 0xF) << 12); + return ((Reg & 0x10) << 18) | ((Reg & 0xF) << 12); else if (double_reg) - return ((Reg & 0x10) << 18) | ((Reg & 0xF) << 16); + return ((Reg & 0x10) << 18) | ((Reg & 0xF) << 12); else return ((Reg & 0x1) << 22) | ((Reg & 0x1E) << 11); } @@ -875,7 +875,7 @@ u32 ARMXEmitter::EncodeVn(ARMReg Vn) ARMReg Reg = SubBase(Vn); if (quad_reg) - ((Reg & 0xF) << 16) | ((Reg & 0x10) << 3); + return ((Reg & 0xF) << 16) | ((Reg & 0x10) << 3); else if (double_reg) return ((Reg & 0xF) << 16) | ((Reg & 0x10) << 3); @@ -890,7 +890,7 @@ u32 ARMXEmitter::EncodeVm(ARMReg Vm) ARMReg Reg = SubBase(Vm); if (quad_reg) - ((Reg & 0x10) << 2) | (Reg & 0xF); + return ((Reg & 0x10) << 2) | (Reg & 0xF); else if (double_reg) return ((Reg & 0x10) << 2) | (Reg & 0xF); @@ -900,18 +900,31 @@ u32 ARMXEmitter::EncodeVm(ARMReg Vm) void ARMXEmitter::WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm) { bool quad_reg = Vd >= Q0; - bool double_reg = Vd >= D0; + bool double_reg = Vd >= D0 && Vd < Q0; VFPEnc enc = VFPOps[Op][quad_reg]; - if (enc.opc1 == (u16)-1 && enc.opc1 == (u16)-1) - _assert_msg_(DYNA_REC, false, "%s does not support %s", VFPOps[Op], quad_reg ? "NEON" : "VFP"); + if (enc.opc1 == -1 && enc.opc1 == -1) + _assert_msg_(DYNA_REC, false, "%s does not support %s", VFPOpNames[Op], quad_reg ? "NEON" : "VFP"); u32 VdEnc = EncodeVd(Vd); u32 VnEnc = EncodeVn(Vn); u32 VmEnc = EncodeVm(Vm); u32 cond = quad_reg ? (0xF << 28) : condition; - - Write32(cond | enc.opc1 | VnEnc | VdEnc | enc.opc2 | VmEnc); -} + + Write32(cond | (enc.opc1 << 20) | VnEnc | VdEnc | (enc.opc2 << 4) | (quad_reg << 6) | (double_reg << 8) | VmEnc); +} +void ARMXEmitter::VMLA(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(0, Vd, Vn, Vm); } +void ARMXEmitter::VMLS(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(1, Vd, Vn, Vm); } +void ARMXEmitter::VADD(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(2, Vd, Vn, Vm); } +void ARMXEmitter::VSUB(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(3, Vd, Vn, Vm); } +void ARMXEmitter::VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(4, Vd, Vn, Vm); } +void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(5, Vd, D0, Vm); } +void ARMXEmitter::VDIV(ARMReg Vd, ARMReg Vn, ARMReg Vm){ WriteVFPDataOp(6, Vd, Vn, Vm); } +void ARMXEmitter::VNEG(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(7, Vd, D1, Vm); } +void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(8, Vd, D1, Vm); } +void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(9, Vd, D4, Vm); } +void ARMXEmitter::VCMPE(ARMReg Vd, ARMReg Vm){ WriteVFPDataOp(10, Vd, D4, Vm); } +void ARMXEmitter::VCMP(ARMReg Vd){ WriteVFPDataOp(9, Vd, D5, D0); } +void ARMXEmitter::VCMPE(ARMReg Vd){ WriteVFPDataOp(10, Vd, D5, D0); } void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset) { @@ -970,43 +983,6 @@ void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, s16 offset) | ((Src & 0xF) << 12) | (11 << 8) | (imm >> 2)); } } -void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm, bool E) -{ - _assert_msg_(DYNA_REC, Vd < Q0, "Passed invalid Vd to VCMP"); - bool single_reg = Vd < D0; - - Vd = SubBase(Vd); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x34 << 16) | ((Vd & 0x1E) << 11) \ - | (E << 7) | (0x29 << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - Write32(condition | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x34 << 16) | ((Vd & 0xF) << 12) \ - | (E << 7) | (0x2C << 6) | ((Vm & 0x10) << 1) | (Vm & 0xF)); - } -} -void ARMXEmitter::VCMP(ARMReg Vd, bool E) -{ - _assert_msg_(DYNA_REC, Vd < Q0, "Passed invalid Vd to VCMP"); - bool single_reg = Vd < D0; - - Vd = SubBase(Vd); - - if (single_reg) - { - Write32(condition | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x35 << 16) | ((Vd & 0x1E) << 11) \ - | (E << 7) | (0x29 << 6)); - } - else - { - Write32(condition | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x35 << 16) | ((Vd & 0xF) << 12) \ - | (E << 7) | (0x2C << 6)); - } -} void ARMXEmitter::VMRS_APSR() { Write32(condition | 0xEF10A10 | (15 << 12)); @@ -1018,229 +994,7 @@ void ARMXEmitter::VMSR(ARMReg Rt) { Write32(condition | (0xEE << 20) | (1 << 16) | (Rt << 12) | 0xA10); } -void ARMXEmitter::VDIV(ARMReg Vd, ARMReg Vn, ARMReg Vm) -{ - _assert_msg_(DYNA_REC, Vd < Q0, "Pased invalid dest register to VSQRT"); - _assert_msg_(DYNA_REC, Vn < Q0, "Passed invalid Vn to VSQRT"); - _assert_msg_(DYNA_REC, Vm < Q0, "Passed invalid Vm to VSQRT"); - bool single_reg = Vd < D0; - - Vd = SubBase(Vd); - Vn = SubBase(Vn); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1D << 23) | ((Vd & 0x1) << 22) | ((Vn & 0x1E) << 15) \ - | ((Vd & 0x1E) << 11) | (0xA << 8) | ((Vn & 0x1) << 7) | ((Vm & 0x1) << 5) \ - | (Vm >> 1)); - } - else - { - Write32(condition | (0x1D << 23) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16) \ - | ((Vd & 0xF) << 12) | (0xB << 8) | ((Vn & 0x10) << 3) | ((Vm & 0x10) << 2) \ - | (Vm & 0xF)); - } -} -void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm) -{ - _assert_msg_(DYNA_REC, Vd < Q0, "Pased invalid dest register to VSQRT"); - _assert_msg_(DYNA_REC, Vm < Q0, "Passed invalid Vm to VSQRT"); - bool single_reg = Vd < D0; - - Vd = SubBase(Vd); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x31 << 16) \ - | ((Vd & 0x1E) << 11) | (0x2B << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - Write32(condition | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x31 << 16) \ - | ((Vd & 0xF) << 12) | (0x2F << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } -} - -// VFP and ASIMD -void ARMXEmitter::VADD(ARMReg Vd, ARMReg Vn, ARMReg Vm) -{ - _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VADD"); - _assert_msg_(DYNA_REC, Vn >= S0, "Passed invalid Vn to VADD"); - _assert_msg_(DYNA_REC, Vm >= S0, "Passed invalid Vm to VADD"); - bool single_reg = Vd < D0; - bool double_reg = Vd < Q0; - - Vd = SubBase(Vd); - Vn = SubBase(Vn); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1C << 23) | ((Vd & 0x1) << 22) | (0x3 << 20) \ - | ((Vn & 0x1E) << 15) | ((Vd & 0x1E) << 11) | (0x5 << 9) \ - | ((Vn & 0x1) << 7) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - if (double_reg) - { - Write32(condition | (0x1C << 23) | ((Vd & 0x10) << 18) | (0x3 << 20) \ - | ((Vn & 0xF) << 16) | ((Vd & 0xF) << 12) | (0xB << 8) \ - | ((Vn & 0x10) << 3) | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } - else - { - _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VADD with Quad Reg without support!"); - Write32((0xF2 << 24) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16) \ - | ((Vd & 0xF) << 12) | (0xD << 8) | ((Vn & 0x10) << 3) \ - | (1 << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } - } -} -void ARMXEmitter::VSUB(ARMReg Vd, ARMReg Vn, ARMReg Vm) -{ - _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VSUB"); - _assert_msg_(DYNA_REC, Vn >= S0, "Passed invalid Vn to VSUB"); - _assert_msg_(DYNA_REC, Vm >= S0, "Passed invalid Vm to VSUB"); - bool single_reg = Vd < D0; - bool double_reg = Vd < Q0; - - Vd = SubBase(Vd); - Vn = SubBase(Vn); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1C << 23) | ((Vd & 0x1) << 22) | (0x3 << 20) \ - | ((Vn & 0x1E) << 15) | ((Vd & 0x1E) << 11) | (0x5 << 9) \ - | ((Vn & 0x1) << 7) | (1 << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - if (double_reg) - { - Write32(condition | (0x1C << 23) | ((Vd & 0x10) << 18) | (0x3 << 20) \ - | ((Vn & 0xF) << 16) | ((Vd & 0xF) << 12) | (0xB << 8) \ - | ((Vn & 0x10) << 3) | (1 << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } - else - { - _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VADD with Quad Reg without support!"); - Write32((0xF2 << 24) | (1 << 21) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16) \ - | ((Vd & 0xF) << 12) | (0xD << 8) | ((Vn & 0x10) << 3) \ - | (1 << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } - } -} // VFP and ASIMD -void ARMXEmitter::VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm) -{ - _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VADD"); - _assert_msg_(DYNA_REC, Vn >= S0, "Passed invalid Vn to VADD"); - _assert_msg_(DYNA_REC, Vm >= S0, "Passed invalid Vm to VADD"); - bool single_reg = Vd < D0; - bool double_reg = Vd < Q0; - - Vd = SubBase(Vd); - Vn = SubBase(Vn); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1C << 23) | ((Vd & 0x1) << 22) | (0x2 << 20) \ - | ((Vn & 0x1E) << 15) | ((Vd & 0x1E) << 11) | (0x5 << 9) \ - | ((Vn & 0x1) << 7) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - if (double_reg) - { - Write32(condition | (0x1C << 23) | ((Vd & 0x10) << 18) | (0x2 << 20) \ - | ((Vn & 0xF) << 16) | ((Vd & 0xF) << 12) | (0xB << 8) \ - | ((Vn & 0x10) << 3) | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } - else - { - _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VMUL with Quad Reg without support!"); - } - } -} - -void ARMXEmitter::VMLA(ARMReg Vd, ARMReg Vn, ARMReg Vm) -{ - _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VMLA"); - _assert_msg_(DYNA_REC, Vn >= S0, "Passed invalid Vn to VMLA"); - _assert_msg_(DYNA_REC, Vm >= S0, "Passed invalid Vm to VMLA"); - bool single_reg = Vd < D0; - bool double_reg = Vd < Q0; - - Vd = SubBase(Vd); - Vn = SubBase(Vn); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1C << 23) | ((Vd & 0x1) << 22) | (0x0 << 20) \ - | ((Vn & 0x1E) << 15) | ((Vd & 0x1E) << 11) | (0x5 << 9) \ - | ((Vn & 0x1) << 7) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - _assert_msg_(DYNA_REC, false, "VMLA: Please implement!"); - } -} - -void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm) -{ - _assert_msg_(DYNA_REC, Vd < Q0, "VABS doesn't currently support Quad reg"); - _assert_msg_(DYNA_REC, Vd >= S0, "VABS doesn't support ARM Regs"); - bool single_reg = Vd < D0; - bool double_reg = Vd < Q0; - - Vd = SubBase(Vd); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0xEB << 20) | ((Vd & 0x1) << 22) | ((Vd & 0x1E) << 11) \ - | (0xAC << 4) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - if (double_reg) - { - Write32(condition | (0xEB << 20) | ((Vd & 0x10) << 18) | ((Vd & 0xF) << 12) \ - | (0xBC << 4) | ((Vm & 0x10) << 1) | (Vm & 0xF)); - } - else - { - _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VADD with Quad Reg without support!"); - // XXX: TODO - } - } -} - -void ARMXEmitter::VNEG(ARMReg Vd, ARMReg Vm) -{ - bool single_reg = Vd < D0; - - Vd = SubBase(Vd); - Vm = SubBase(Vm); - - if (single_reg) - { - Write32(condition | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x31 << 16) \ - | ((Vd & 0x1E) << 11) | (0x29 << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); - } - else - { - Write32(condition | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x31 << 16) \ - | ((Vd & 0xF) << 12) | (0x2D << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } -} - void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src, bool high) { _assert_msg_(DYNA_REC, Src < S0, "This VMOV doesn't support SRC other than ARM Reg"); diff --git a/Source/Core/Common/Src/ArmEmitter.h b/Source/Core/Common/Src/ArmEmitter.h index 0749d42c96..1117ce5ac9 100644 --- a/Source/Core/Common/Src/ArmEmitter.h +++ b/Source/Core/Common/Src/ArmEmitter.h @@ -357,8 +357,12 @@ private: void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, ARMReg op2); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2); void WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARMReg r1, ARMReg r2); - - + + u32 EncodeVd(ARMReg Vd); + u32 EncodeVn(ARMReg Vn); + u32 EncodeVm(ARMReg Vm); + void WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm); + void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); // New Ops @@ -528,9 +532,11 @@ public: // VFP Only void VLDR(ARMReg Dest, ARMReg Base, s16 offset); void VSTR(ARMReg Src, ARMReg Base, s16 offset); - void VCMP(ARMReg Vd, ARMReg Vm, bool E); + void VCMP(ARMReg Vd, ARMReg Vm); + void VCMPE(ARMReg Vd, ARMReg Vm); // Compares against zero - void VCMP(ARMReg Vd, bool E); + void VCMP(ARMReg Vd); + void VCMPE(ARMReg Vd); void VDIV(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VSQRT(ARMReg Vd, ARMReg Vm); @@ -541,6 +547,7 @@ public: void VNEG(ARMReg Vd, ARMReg Vm); void VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VMLA(ARMReg Vd, ARMReg Vn, ARMReg Vm); + void VMLS(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VMOV(ARMReg Dest, ARMReg Src, bool high); void VMOV(ARMReg Dest, ARMReg Src); void VCVT(ARMReg Dest, ARMReg Src, int flags); diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index c38184776b..a86b4f2b0a 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -395,7 +395,7 @@ std::string UTF16ToUTF8(const std::wstring& input) std::string output; output.resize(size); - if (size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) + if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) output.clear(); return output; @@ -408,7 +408,7 @@ std::wstring CPToUTF16(u32 code_page, const std::string& input) std::wstring output; output.resize(size); - if (size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) + if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) output.clear(); return output; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index a441ba2d64..1bc5e1fc14 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -27,6 +27,8 @@ namespace OGL static const u32 UBO_LENGTH = 32*1024*1024; +GLintptr ProgramShaderCache::s_vs_data_size; +GLintptr ProgramShaderCache::s_ps_data_size; GLintptr ProgramShaderCache::s_vs_data_offset; u8 *ProgramShaderCache::s_ubo_buffer; u32 ProgramShaderCache::s_ubo_buffer_size; @@ -169,8 +171,8 @@ void ProgramShaderCache::UploadConstants() if(s_ubo_dirty) { s_buffer->Alloc(s_ubo_buffer_size); size_t offset = s_buffer->Upload(s_ubo_buffer, s_ubo_buffer_size); - glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->getBuffer(), offset, s_vs_data_offset); - glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->getBuffer(), offset + s_vs_data_offset, s_ubo_buffer_size - s_vs_data_offset); + glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->getBuffer(), offset, s_ps_data_size); + glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->getBuffer(), offset + s_vs_data_offset, s_vs_data_size); s_ubo_dirty = false; } } @@ -388,10 +390,10 @@ void ProgramShaderCache::Init(void) GLint Align; glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &Align); - GLintptr const ps_data_size = ROUND_UP(C_PENVCONST_END * sizeof(float) * 4, Align); - GLintptr const vs_data_size = ROUND_UP(C_VENVCONST_END * sizeof(float) * 4, Align); - s_vs_data_offset = ps_data_size; - s_ubo_buffer_size = ps_data_size + vs_data_size; + s_ps_data_size = C_PENVCONST_END * sizeof(float) * 4; + s_vs_data_size = C_VENVCONST_END * sizeof(float) * 4; + s_vs_data_offset = ROUND_UP(s_ps_data_size, Align); + s_ubo_buffer_size = ROUND_UP(s_ps_data_size, Align) + ROUND_UP(s_vs_data_size, Align); // We multiply by *4*4 because we need to get down to basic machine units. // So multiply by four to get how many floats we have from vec4s diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h index 8903e800ba..c4b03c2973 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.h @@ -125,6 +125,8 @@ private: static PCacheEntry* last_entry; static SHADERUID last_uid; + static GLintptr s_vs_data_size; + static GLintptr s_ps_data_size; static GLintptr s_vs_data_offset; static u8 *s_ubo_buffer; static u32 s_ubo_buffer_size; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 11cb1d4a3b..33544d0c5e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -65,6 +65,7 @@ #include "ConfigManager.h" #include "VertexManager.h" #include "SamplerCache.h" +#include "StreamBuffer.h" #include "main.h" // Local #ifdef _WIN32 @@ -132,47 +133,62 @@ static std::vector<u32> s_efbCache[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; // 2 int GetNumMSAASamples(int MSAAMode) { + int samples, maxSamples; switch (MSAAMode) { case MULTISAMPLE_OFF: - return 1; + samples = 1; + break; case MULTISAMPLE_2X: - return 2; + samples = 2; + break; case MULTISAMPLE_4X: case MULTISAMPLE_CSAA_8X: case MULTISAMPLE_CSAA_16X: - return 4; + samples = 4; + break; case MULTISAMPLE_8X: case MULTISAMPLE_CSAA_8XQ: case MULTISAMPLE_CSAA_16XQ: - return 8; + samples = 8; + break; default: - return 1; + samples = 1; } + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + + if(samples <= maxSamples) return samples; + + ERROR_LOG(VIDEO, "MSAA Bug: %d samples selected, but only %d supported by gpu.", samples, maxSamples); + return maxSamples; } int GetNumMSAACoverageSamples(int MSAAMode) { - if (!s_bHaveCoverageMSAA) - return 0; - + int samples; switch (g_ActiveConfig.iMultisampleMode) { case MULTISAMPLE_CSAA_8X: case MULTISAMPLE_CSAA_8XQ: - return 8; + samples = 8; + break; case MULTISAMPLE_CSAA_16X: case MULTISAMPLE_CSAA_16XQ: - return 16; + samples = 16; + break; default: - return 0; + samples = 0; } + if(s_bHaveCoverageMSAA || samples == 0) return samples; + + ERROR_LOG(VIDEO, "MSAA Bug: CSAA selected, but not supported by gpu."); + return 0; } // Init functions @@ -244,9 +260,11 @@ Renderer::Renderer() bSuccess = false; } - if (!GLEW_ARB_sampler_objects) + if (!GLEW_ARB_sampler_objects && bSuccess) { - ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_sampler_objects."); + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_sampler_objects." + "GPU: Does your video card support OpenGL 3.2?" + "Please report this issue, then there will be a workaround"); bSuccess = false; } @@ -266,6 +284,13 @@ Renderer::Renderer() g_Config.backend_info.bSupportsGLSLUBO = false; ERROR_LOG(VIDEO, "buggy driver detected. Disable UBO"); } + +#ifndef _WIN32 + if(g_Config.backend_info.bSupportsGLPinnedMemory && !strcmp(gl_vendor, "Advanced Micro Devices, Inc.")) { + g_Config.backend_info.bSupportsGLPinnedMemory = false; + ERROR_LOG(VIDEO, "some fglrx versions have broken pinned memory support, so it's disabled for fglrx"); + } +#endif UpdateActiveConfig(); OSD::AddMessage(StringFromFormat("Missing Extensions: %s%s%s%s%s%s", @@ -276,14 +301,14 @@ Renderer::Renderer() g_ActiveConfig.backend_info.bSupportsGLBaseVertex ? "" : "BaseVertex ", g_ActiveConfig.backend_info.bSupportsGLSync ? "" : "Sync " ).c_str(), 5000); + + if (!bSuccess) + return; // TODO: fail s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode; s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode); s_MSAACoverageSamples = GetNumMSAACoverageSamples(s_LastMultisampleMode); - if (!bSuccess) - return; // TODO: fail - // Decide frambuffer size s_backbuffer_width = (int)GLInterface->GetBackBufferWidth(); s_backbuffer_height = (int)GLInterface->GetBackBufferHeight(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 1a1fee21a0..b0bc682f29 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -491,7 +491,9 @@ void TextureCache::DisableStage(unsigned int stage) void TextureCache::SetStage () { - glActiveTexture(GL_TEXTURE0 + s_ActiveTexture); + // -1 is the initial value as we don't know which testure should be bound + if(s_ActiveTexture != (u32)-1) + glActiveTexture(GL_TEXTURE0 + s_ActiveTexture); } void TextureCache::SetNextStage ( unsigned int stage ) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp index 91d35af849..f57d0b334b 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp @@ -20,6 +20,7 @@ #include "../../Plugin_VideoOGL/Src/GLUtil.h" #include "../../Plugin_VideoOGL/Src/RasterFont.h" +#include "../../Plugin_VideoOGL/Src/ProgramShaderCache.h" #include "SWRenderer.h" #include "SWStatistics.h" @@ -30,6 +31,7 @@ static GLint uni_tex = -1; static GLuint program; // Rasterfont isn't compatible with GLES +// degasus: I think it does, but I can't test it #ifndef USE_GLES OGL::RasterFont* s_pfont = NULL; #endif @@ -45,6 +47,7 @@ void SWRenderer::Shutdown() #ifndef USE_GLES delete s_pfont; s_pfont = 0; + OGL::ProgramShaderCache::Shutdown(); #endif } @@ -87,6 +90,8 @@ void SWRenderer::Prepare() CreateShaders(); // TODO: Enable for GLES once RasterFont supports GLES #ifndef USE_GLES + // ogl rasterfont depends on ogl programshadercache + OGL::ProgramShaderCache::Init(); s_pfont = new OGL::RasterFont(); glEnable(GL_TEXTURE_2D); #endif @@ -103,6 +108,9 @@ void SWRenderer::RenderText(const char* pstr, int left, int top, u32 color) left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight, 0, nBackbufferWidth, nBackbufferHeight, color); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); #endif } |
