mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-13 07:49:19 +01:00
Merge branch 'master' into android-new-control-input-overlay
Conflicts: Source/Android/src/org/dolphinemu/dolphinemu/settings/video/VideoSettingsFragment.java
This commit is contained in:
commit
7bdd8191db
@ -29,6 +29,7 @@
|
|||||||
<!-- Game List Activity - Device Compatibility AlertDialog -->
|
<!-- Game List Activity - Device Compatibility AlertDialog -->
|
||||||
<string name="device_compat_warning">デバイスの互換性の警告</string>
|
<string name="device_compat_warning">デバイスの互換性の警告</string>
|
||||||
<string name="device_compat_warning_msg">この電話は、NEON拡張をサポートしていません。 おそらくDolphinを実行することはできません。\nあなたはとにかくそれを実行してみますか?</string>
|
<string name="device_compat_warning_msg">この電話は、NEON拡張をサポートしていません。 おそらくDolphinを実行することはできません。\nあなたはとにかくそれを実行してみますか?</string>
|
||||||
|
<string name="device_gles3compat_warning_msg">デバイスはOpenGLES3のビデオドライバのバグがあります。\nあなたはとにかくそれを使用してみたいのですか?</string>
|
||||||
|
|
||||||
<!-- Game List Fragment -->
|
<!-- Game List Fragment -->
|
||||||
<string name="file_clicked">クリックされたファイル: %1$s</string>
|
<string name="file_clicked">クリックされたファイル: %1$s</string>
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
<!-- Game List Activity - Device Compatibility AlertDialog -->
|
<!-- Game List Activity - Device Compatibility AlertDialog -->
|
||||||
<string name="device_compat_warning">Device Compatibility Warning</string>
|
<string name="device_compat_warning">Device Compatibility Warning</string>
|
||||||
<string name="device_compat_warning_msg">Your phone doesn\'t support NEON which makes it incapable of running Dolphin Mobile?\nDo you want to try anyway?</string>
|
<string name="device_compat_warning_msg">Your phone doesn\'t support NEON which makes it incapable of running Dolphin Mobile?\nDo you want to try anyway?</string>
|
||||||
|
<string name="device_gles3compat_warning_msg">Your device has known buggy video drivers for OpenGL ES 3.\nDo you want to try anyway?</string>
|
||||||
|
|
||||||
<!-- Game List Fragment -->
|
<!-- Game List Fragment -->
|
||||||
<string name="file_clicked">File clicked: %1$s</string>
|
<string name="file_clicked">File clicked: %1$s</string>
|
||||||
|
@ -28,6 +28,8 @@ public final class VideoSettingsFragment extends PreferenceFragment
|
|||||||
public static String m_GLRenderer;
|
public static String m_GLRenderer;
|
||||||
public static String m_GLExtensions;
|
public static String m_GLExtensions;
|
||||||
public static float m_QualcommVersion;
|
public static float m_QualcommVersion;
|
||||||
|
public static boolean m_Inited = false;
|
||||||
|
private Activity m_activity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class which provides a means to retrieve various
|
* Class which provides a means to retrieve various
|
||||||
@ -145,20 +147,24 @@ public final class VideoSettingsFragment extends PreferenceFragment
|
|||||||
*/
|
*/
|
||||||
public static boolean SupportsGLES3()
|
public static boolean SupportsGLES3()
|
||||||
{
|
{
|
||||||
VersionCheck mbuffer = new VersionCheck();
|
|
||||||
m_GLVersion = mbuffer.getVersion();
|
|
||||||
m_GLVendor = mbuffer.getVendor();
|
|
||||||
m_GLRenderer = mbuffer.getRenderer();
|
|
||||||
m_GLExtensions = mbuffer.getExtensions();
|
|
||||||
|
|
||||||
boolean mSupportsGLES3 = false;
|
boolean mSupportsGLES3 = false;
|
||||||
|
if (!m_Inited)
|
||||||
|
{
|
||||||
|
VersionCheck mbuffer = new VersionCheck();
|
||||||
|
m_GLVersion = mbuffer.getVersion();
|
||||||
|
m_GLVendor = mbuffer.getVendor();
|
||||||
|
m_GLRenderer = mbuffer.getRenderer();
|
||||||
|
m_GLExtensions = mbuffer.getExtensions();
|
||||||
|
m_Inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check for OpenGL ES 3 support (General case).
|
// Check for OpenGL ES 3 support (General case).
|
||||||
if (m_GLVersion != null && m_GLVersion.contains("OpenGL ES 3.0"))
|
if (m_GLVersion != null && m_GLVersion.contains("OpenGL ES 3.0"))
|
||||||
mSupportsGLES3 = true;
|
mSupportsGLES3 = true;
|
||||||
|
|
||||||
// Checking for OpenGL ES 3 support for certain Qualcomm devices.
|
// Checking for OpenGL ES 3 support for certain Qualcomm devices.
|
||||||
if (!mSupportsGLES3 && m_GLVendor != null && m_GLVendor.equals("Qualcomm"))
|
if (m_GLVendor != null && m_GLVendor.equals("Qualcomm"))
|
||||||
{
|
{
|
||||||
if (m_GLRenderer.contains("Adreno (TM) 3"))
|
if (m_GLRenderer.contains("Adreno (TM) 3"))
|
||||||
{
|
{
|
||||||
@ -180,6 +186,7 @@ public final class VideoSettingsFragment extends PreferenceFragment
|
|||||||
mSupportsGLES3 = true;
|
mSupportsGLES3 = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mSupportsGLES3;
|
return mSupportsGLES3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,9 +255,36 @@ public final class VideoSettingsFragment extends PreferenceFragment
|
|||||||
}
|
}
|
||||||
else if (preference.getString(key, "Software Renderer").equals("OGL"))
|
else if (preference.getString(key, "Software Renderer").equals("OGL"))
|
||||||
{
|
{
|
||||||
mainScreen.getPreference(0).setEnabled(true);
|
// Create an alert telling them that their phone sucks
|
||||||
mainScreen.getPreference(1).setEnabled(true);
|
if (VideoSettingsFragment.SupportsGLES3()
|
||||||
mainScreen.getPreference(3).setEnabled(true);
|
&& VideoSettingsFragment.m_GLVendor != null
|
||||||
|
&& VideoSettingsFragment.m_GLVendor.equals("Qualcomm")
|
||||||
|
&& VideoSettingsFragment.m_QualcommVersion == 14.0f)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(m_activity);
|
||||||
|
builder.setTitle(R.string.device_compat_warning);
|
||||||
|
builder.setMessage(R.string.device_gles3compat_warning_msg);
|
||||||
|
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
mainScreen.getPreference(0).setEnabled(true);
|
||||||
|
mainScreen.getPreference(1).setEnabled(true);
|
||||||
|
mainScreen.getPreference(3).setEnabled(true);
|
||||||
|
//mainScreen.getPreference(4).setEnabled(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
// Get an editor.
|
||||||
|
SharedPreferences.Editor editor = sPrefs.edit();
|
||||||
|
editor.putString("gpuPref", "Software Renderer");
|
||||||
|
editor.commit();
|
||||||
|
videoBackends.setValue("Software Renderer");
|
||||||
|
videoBackends.setSummary("Software Renderer");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ void Jit64::Cleanup()
|
|||||||
ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
|
ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::WriteExit(u32 destination)
|
void Jit64::WriteExit(u32 destination, int exit_num)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
@ -284,9 +284,8 @@ void Jit64::WriteExit(u32 destination)
|
|||||||
|
|
||||||
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
||||||
JitBlock *b = js.curBlock;
|
JitBlock *b = js.curBlock;
|
||||||
JitBlock::LinkData linkData;
|
b->exitAddress[exit_num] = destination;
|
||||||
linkData.exitAddress = destination;
|
b->exitPtrs[exit_num] = GetWritableCodePtr();
|
||||||
linkData.exitPtrs = GetWritableCodePtr();
|
|
||||||
|
|
||||||
// Link opportunity!
|
// Link opportunity!
|
||||||
if (jo.enableBlocklink)
|
if (jo.enableBlocklink)
|
||||||
@ -296,14 +295,12 @@ void Jit64::WriteExit(u32 destination)
|
|||||||
{
|
{
|
||||||
// It exists! Joy of joy!
|
// It exists! Joy of joy!
|
||||||
JMP(blocks.GetBlock(block)->checkedEntry, true);
|
JMP(blocks.GetBlock(block)->checkedEntry, true);
|
||||||
linkData.linkStatus = true;
|
b->linkStatus[exit_num] = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MOV(32, M(&PC), Imm32(destination));
|
MOV(32, M(&PC), Imm32(destination));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
|
|
||||||
b->linkData.push_back(linkData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::WriteExitDestInEAX()
|
void Jit64::WriteExitDestInEAX()
|
||||||
@ -628,7 +625,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||||||
TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||||
FixupBranch noBreakpoint = J_CC(CC_Z);
|
FixupBranch noBreakpoint = J_CC(CC_Z);
|
||||||
|
|
||||||
WriteExit(ops[i].address);
|
WriteExit(ops[i].address, 0);
|
||||||
SetJumpTarget(noBreakpoint);
|
SetJumpTarget(noBreakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,7 +707,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||||||
{
|
{
|
||||||
gpr.Flush(FLUSH_ALL);
|
gpr.Flush(FLUSH_ALL);
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
WriteExit(nextPC);
|
WriteExit(nextPC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->flags = js.block_flags;
|
b->flags = js.block_flags;
|
||||||
|
@ -99,7 +99,7 @@ public:
|
|||||||
|
|
||||||
// Utilities for use by opcodes
|
// Utilities for use by opcodes
|
||||||
|
|
||||||
void WriteExit(u32 destination);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
void WriteExitDestInEAX();
|
void WriteExitDestInEAX();
|
||||||
void WriteExceptionExit();
|
void WriteExceptionExit();
|
||||||
void WriteExternalExceptionExit();
|
void WriteExternalExceptionExit();
|
||||||
|
@ -91,7 +91,7 @@ void Jit64::bx(UGeckoInstruction inst)
|
|||||||
// make idle loops go faster
|
// make idle loops go faster
|
||||||
js.downcountAmount += 8;
|
js.downcountAmount += 8;
|
||||||
}
|
}
|
||||||
WriteExit(destination);
|
WriteExit(destination, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - optimize to hell and beyond
|
// TODO - optimize to hell and beyond
|
||||||
@ -136,13 +136,13 @@ void Jit64::bcx(UGeckoInstruction inst)
|
|||||||
destination = SignExt16(inst.BD << 2);
|
destination = SignExt16(inst.BD << 2);
|
||||||
else
|
else
|
||||||
destination = js.compilerPC + SignExt16(inst.BD << 2);
|
destination = js.compilerPC + SignExt16(inst.BD << 2);
|
||||||
WriteExit(destination);
|
WriteExit(destination, 0);
|
||||||
|
|
||||||
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0)
|
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0)
|
||||||
SetJumpTarget( pConditionDontBranch );
|
SetJumpTarget( pConditionDontBranch );
|
||||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
SetJumpTarget( pCTRDontBranch );
|
SetJumpTarget( pCTRDontBranch );
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::bcctrx(UGeckoInstruction inst)
|
void Jit64::bcctrx(UGeckoInstruction inst)
|
||||||
@ -190,7 +190,7 @@ void Jit64::bcctrx(UGeckoInstruction inst)
|
|||||||
WriteExitDestInEAX();
|
WriteExitDestInEAX();
|
||||||
// Would really like to continue the block here, but it ends. TODO.
|
// Would really like to continue the block here, but it ends. TODO.
|
||||||
SetJumpTarget(b);
|
SetJumpTarget(b);
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,5 +245,5 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
|||||||
SetJumpTarget( pConditionDontBranch );
|
SetJumpTarget( pConditionDontBranch );
|
||||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
SetJumpTarget( pCTRDontBranch );
|
SetJumpTarget( pCTRDontBranch );
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
|||||||
destination = SignExt16(js.next_inst.BD << 2);
|
destination = SignExt16(js.next_inst.BD << 2);
|
||||||
else
|
else
|
||||||
destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2);
|
destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2);
|
||||||
WriteExit(destination);
|
WriteExit(destination, 0);
|
||||||
}
|
}
|
||||||
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx
|
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx
|
||||||
{
|
{
|
||||||
@ -424,7 +424,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteExit(js.next_compilerPC + 4);
|
WriteExit(js.next_compilerPC + 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
js.cancel = true;
|
js.cancel = true;
|
||||||
@ -507,7 +507,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
|||||||
destination = SignExt16(js.next_inst.BD << 2);
|
destination = SignExt16(js.next_inst.BD << 2);
|
||||||
else
|
else
|
||||||
destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2);
|
destination = js.next_compilerPC + SignExt16(js.next_inst.BD << 2);
|
||||||
WriteExit(destination);
|
WriteExit(destination, 0);
|
||||||
}
|
}
|
||||||
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx
|
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 528)) // bcctrx
|
||||||
{
|
{
|
||||||
@ -534,7 +534,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
|||||||
if (!!(4 & test_bit) == condition) SetJumpTarget(continue2);
|
if (!!(4 & test_bit) == condition) SetJumpTarget(continue2);
|
||||||
if (!!(2 & test_bit) == condition) SetJumpTarget(continue1);
|
if (!!(2 & test_bit) == condition) SetJumpTarget(continue1);
|
||||||
|
|
||||||
WriteExit(js.next_compilerPC + 4);
|
WriteExit(js.next_compilerPC + 4, 1);
|
||||||
|
|
||||||
js.cancel = true;
|
js.cancel = true;
|
||||||
}
|
}
|
||||||
@ -2221,5 +2221,5 @@ void Jit64::twx(UGeckoInstruction inst)
|
|||||||
SetJumpTarget(exit3);
|
SetJumpTarget(exit3);
|
||||||
SetJumpTarget(exit4);
|
SetJumpTarget(exit4);
|
||||||
SetJumpTarget(exit5);
|
SetJumpTarget(exit5);
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
}
|
}
|
||||||
|
@ -480,5 +480,5 @@ void Jit64::stmw(UGeckoInstruction inst)
|
|||||||
void Jit64::icbi(UGeckoInstruction inst)
|
void Jit64::icbi(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
Default(inst);
|
Default(inst);
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 0);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ void Jit64::mtmsr(UGeckoInstruction inst)
|
|||||||
SetJumpTarget(noExceptionsPending);
|
SetJumpTarget(noExceptionsPending);
|
||||||
SetJumpTarget(eeDisabled);
|
SetJumpTarget(eeDisabled);
|
||||||
|
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 0);
|
||||||
|
|
||||||
js.firstFPInstructionFound = false;
|
js.firstFPInstructionFound = false;
|
||||||
}
|
}
|
||||||
|
@ -552,8 +552,7 @@ static void regEmitICmpInst(RegInfo& RI, InstLoc I, CCFlags flag) {
|
|||||||
|
|
||||||
static void regWriteExit(RegInfo& RI, InstLoc dest) {
|
static void regWriteExit(RegInfo& RI, InstLoc dest) {
|
||||||
if (isImm(*dest)) {
|
if (isImm(*dest)) {
|
||||||
RI.exitNumber++;
|
RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++);
|
||||||
RI.Jit->WriteExit(RI.Build->GetImmValue(dest));
|
|
||||||
} else {
|
} else {
|
||||||
RI.Jit->WriteExitDestInOpArg(regLocForInst(RI, dest));
|
RI.Jit->WriteExitDestInOpArg(regLocForInst(RI, dest));
|
||||||
}
|
}
|
||||||
@ -565,7 +564,7 @@ static bool checkIsSNAN() {
|
|||||||
return MathUtil::IsSNAN(isSNANTemp[0][0]) || MathUtil::IsSNAN(isSNANTemp[1][0]);
|
return MathUtil::IsSNAN(isSNANTemp[0][0]) || MathUtil::IsSNAN(isSNANTemp[1][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
|
static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
|
||||||
//printf("Writing block: %x\n", js.blockStart);
|
//printf("Writing block: %x\n", js.blockStart);
|
||||||
RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts());
|
RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts());
|
||||||
RI.Build = ibuild;
|
RI.Build = ibuild;
|
||||||
@ -1792,7 +1791,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
|
|||||||
Jit->ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckBreakPoints));
|
Jit->ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckBreakPoints));
|
||||||
Jit->TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
Jit->TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||||
FixupBranch noBreakpoint = Jit->J_CC(CC_Z);
|
FixupBranch noBreakpoint = Jit->J_CC(CC_Z);
|
||||||
Jit->WriteExit(InstLoc);
|
Jit->WriteExit(InstLoc, 0);
|
||||||
Jit->SetJumpTarget(noBreakpoint);
|
Jit->SetJumpTarget(noBreakpoint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1820,10 +1819,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Jit->WriteExit(exitAddress);
|
Jit->WriteExit(jit->js.curBlock->exitAddress[0], 0);
|
||||||
Jit->UD2();
|
Jit->UD2();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::WriteCode(u32 exitAddress) {
|
void JitIL::WriteCode() {
|
||||||
DoWriteCode(&ibuild, this, exitAddress);
|
DoWriteCode(&ibuild, this);
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,7 @@ void JitIL::Cleanup()
|
|||||||
ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
|
ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::WriteExit(u32 destination)
|
void JitIL::WriteExit(u32 destination, int exit_num)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
||||||
@ -391,9 +391,8 @@ void JitIL::WriteExit(u32 destination)
|
|||||||
|
|
||||||
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
||||||
JitBlock *b = js.curBlock;
|
JitBlock *b = js.curBlock;
|
||||||
JitBlock::LinkData linkData;
|
b->exitAddress[exit_num] = destination;
|
||||||
linkData.exitAddress = destination;
|
b->exitPtrs[exit_num] = GetWritableCodePtr();
|
||||||
linkData.exitPtrs = GetWritableCodePtr();
|
|
||||||
|
|
||||||
// Link opportunity!
|
// Link opportunity!
|
||||||
int block = blocks.GetBlockNumberFromStartAddress(destination);
|
int block = blocks.GetBlockNumberFromStartAddress(destination);
|
||||||
@ -401,14 +400,13 @@ void JitIL::WriteExit(u32 destination)
|
|||||||
{
|
{
|
||||||
// It exists! Joy of joy!
|
// It exists! Joy of joy!
|
||||||
JMP(blocks.GetBlock(block)->checkedEntry, true);
|
JMP(blocks.GetBlock(block)->checkedEntry, true);
|
||||||
linkData.linkStatus = true;
|
b->linkStatus[exit_num] = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOV(32, M(&PC), Imm32(destination));
|
MOV(32, M(&PC), Imm32(destination));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, true);
|
||||||
}
|
}
|
||||||
b->linkData.push_back(linkData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg)
|
void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg)
|
||||||
@ -543,16 +541,14 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||||||
|
|
||||||
// Analyze the block, collect all instructions it is made of (including inlining,
|
// Analyze the block, collect all instructions it is made of (including inlining,
|
||||||
// if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
|
// if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
|
||||||
u32 exitAddress = em_address;
|
b->exitAddress[0] = em_address;
|
||||||
|
|
||||||
u32 merged_addresses[32];
|
u32 merged_addresses[32];
|
||||||
const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]);
|
const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]);
|
||||||
int size_of_merged_addresses = 0;
|
int size_of_merged_addresses = 0;
|
||||||
if (!memory_exception)
|
if (!memory_exception)
|
||||||
{
|
{
|
||||||
// If there is a memory exception inside a block (broken_block==true), compile up to that instruction.
|
// If there is a memory exception inside a block (broken_block==true), compile up to that instruction.
|
||||||
// TODO
|
b->exitAddress[0] = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses);
|
||||||
exitAddress = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses);
|
|
||||||
}
|
}
|
||||||
PPCAnalyst::CodeOp *ops = code_buf->codebuffer;
|
PPCAnalyst::CodeOp *ops = code_buf->codebuffer;
|
||||||
|
|
||||||
@ -711,7 +707,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform actual code generation
|
// Perform actual code generation
|
||||||
WriteCode(exitAddress);
|
WriteCode();
|
||||||
|
|
||||||
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
||||||
b->originalSize = size;
|
b->originalSize = size;
|
||||||
|
@ -105,7 +105,7 @@ public:
|
|||||||
|
|
||||||
// Utilities for use by opcodes
|
// Utilities for use by opcodes
|
||||||
|
|
||||||
void WriteExit(u32 destination);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
void WriteExitDestInOpArg(const Gen::OpArg& arg);
|
void WriteExitDestInOpArg(const Gen::OpArg& arg);
|
||||||
void WriteExceptionExit();
|
void WriteExceptionExit();
|
||||||
void WriteRfiExitDestInOpArg(const Gen::OpArg& arg);
|
void WriteRfiExitDestInOpArg(const Gen::OpArg& arg);
|
||||||
@ -121,7 +121,7 @@ public:
|
|||||||
void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (Gen::XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false);
|
void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (Gen::XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false);
|
||||||
void fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (Gen::XEmitter::*op)(Gen::X64Reg, Gen::OpArg));
|
void fp_tri_op(int d, int a, int b, bool reversible, bool dupe, void (Gen::XEmitter::*op)(Gen::X64Reg, Gen::OpArg));
|
||||||
|
|
||||||
void WriteCode(u32 exitAddress);
|
void WriteCode();
|
||||||
|
|
||||||
// OPCODES
|
// OPCODES
|
||||||
void unknown_instruction(UGeckoInstruction _inst) override;
|
void unknown_instruction(UGeckoInstruction _inst) override;
|
||||||
|
@ -186,16 +186,15 @@ void JitArm::WriteExceptionExit()
|
|||||||
MOVI2R(A, (u32)asm_routines.testExceptions);
|
MOVI2R(A, (u32)asm_routines.testExceptions);
|
||||||
B(A);
|
B(A);
|
||||||
}
|
}
|
||||||
void JitArm::WriteExit(u32 destination)
|
void JitArm::WriteExit(u32 destination, int exit_num)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
DoDownCount();
|
DoDownCount();
|
||||||
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
||||||
JitBlock *b = js.curBlock;
|
JitBlock *b = js.curBlock;
|
||||||
JitBlock::LinkData linkData;
|
b->exitAddress[exit_num] = destination;
|
||||||
linkData.exitAddress = destination;
|
b->exitPtrs[exit_num] = GetWritableCodePtr();
|
||||||
linkData.exitPtrs = GetWritableCodePtr();
|
|
||||||
|
|
||||||
// Link opportunity!
|
// Link opportunity!
|
||||||
int block = blocks.GetBlockNumberFromStartAddress(destination);
|
int block = blocks.GetBlockNumberFromStartAddress(destination);
|
||||||
@ -203,7 +202,7 @@ void JitArm::WriteExit(u32 destination)
|
|||||||
{
|
{
|
||||||
// It exists! Joy of joy!
|
// It exists! Joy of joy!
|
||||||
B(blocks.GetBlock(block)->checkedEntry);
|
B(blocks.GetBlock(block)->checkedEntry);
|
||||||
linkData.linkStatus = true;
|
b->linkStatus[exit_num] = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -213,8 +212,6 @@ void JitArm::WriteExit(u32 destination)
|
|||||||
MOVI2R(A, (u32)asm_routines.dispatcher);
|
MOVI2R(A, (u32)asm_routines.dispatcher);
|
||||||
B(A);
|
B(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->linkData.push_back(linkData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void STACKALIGN JitArm::Run()
|
void STACKALIGN JitArm::Run()
|
||||||
@ -499,7 +496,7 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo
|
|||||||
if (broken_block)
|
if (broken_block)
|
||||||
{
|
{
|
||||||
printf("Broken Block going to 0x%08x\n", nextPC);
|
printf("Broken Block going to 0x%08x\n", nextPC);
|
||||||
WriteExit(nextPC);
|
WriteExit(nextPC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->flags = js.block_flags;
|
b->flags = js.block_flags;
|
||||||
|
@ -109,7 +109,7 @@ public:
|
|||||||
|
|
||||||
// Utilities for use by opcodes
|
// Utilities for use by opcodes
|
||||||
|
|
||||||
void WriteExit(u32 destination);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
void WriteExitDestInR(ARMReg Reg);
|
void WriteExitDestInR(ARMReg Reg);
|
||||||
void WriteRfiExitDestInR(ARMReg Reg);
|
void WriteRfiExitDestInR(ARMReg Reg);
|
||||||
void WriteExceptionExit();
|
void WriteExceptionExit();
|
||||||
|
@ -154,7 +154,7 @@ void JitArm::bx(UGeckoInstruction inst)
|
|||||||
MOVI2R(R14, (u32)asm_routines.testExceptions);
|
MOVI2R(R14, (u32)asm_routines.testExceptions);
|
||||||
B(R14);
|
B(R14);
|
||||||
}
|
}
|
||||||
WriteExit(destination);
|
WriteExit(destination, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::bcx(UGeckoInstruction inst)
|
void JitArm::bcx(UGeckoInstruction inst)
|
||||||
@ -209,14 +209,14 @@ void JitArm::bcx(UGeckoInstruction inst)
|
|||||||
destination = SignExt16(inst.BD << 2);
|
destination = SignExt16(inst.BD << 2);
|
||||||
else
|
else
|
||||||
destination = js.compilerPC + SignExt16(inst.BD << 2);
|
destination = js.compilerPC + SignExt16(inst.BD << 2);
|
||||||
WriteExit(destination);
|
WriteExit(destination, 0);
|
||||||
|
|
||||||
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0)
|
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0)
|
||||||
SetJumpTarget( pConditionDontBranch );
|
SetJumpTarget( pConditionDontBranch );
|
||||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
SetJumpTarget( pCTRDontBranch );
|
SetJumpTarget( pCTRDontBranch );
|
||||||
|
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
}
|
}
|
||||||
void JitArm::bcctrx(UGeckoInstruction inst)
|
void JitArm::bcctrx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
@ -278,7 +278,7 @@ void JitArm::bcctrx(UGeckoInstruction inst)
|
|||||||
WriteExitDestInR(rA);
|
WriteExitDestInR(rA);
|
||||||
|
|
||||||
SetJumpTarget(b);
|
SetJumpTarget(b);
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void JitArm::bclrx(UGeckoInstruction inst)
|
void JitArm::bclrx(UGeckoInstruction inst)
|
||||||
@ -355,5 +355,5 @@ void JitArm::bclrx(UGeckoInstruction inst)
|
|||||||
SetJumpTarget( pConditionDontBranch );
|
SetJumpTarget( pConditionDontBranch );
|
||||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
SetJumpTarget( pCTRDontBranch );
|
SetJumpTarget( pCTRDontBranch );
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
}
|
}
|
||||||
|
@ -531,6 +531,6 @@ void JitArm::dcbst(UGeckoInstruction inst)
|
|||||||
void JitArm::icbi(UGeckoInstruction inst)
|
void JitArm::icbi(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
Default(inst);
|
Default(inst);
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ void JitArm::mtmsr(UGeckoInstruction inst)
|
|||||||
gpr.Flush();
|
gpr.Flush();
|
||||||
fpr.Flush();
|
fpr.Flush();
|
||||||
|
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::mfmsr(UGeckoInstruction inst)
|
void JitArm::mfmsr(UGeckoInstruction inst)
|
||||||
|
@ -156,8 +156,7 @@ static ARMReg regEnsureInReg(RegInfo& RI, InstLoc I) {
|
|||||||
|
|
||||||
static void regWriteExit(RegInfo& RI, InstLoc dest) {
|
static void regWriteExit(RegInfo& RI, InstLoc dest) {
|
||||||
if (isImm(*dest)) {
|
if (isImm(*dest)) {
|
||||||
RI.exitNumber++;
|
RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++);
|
||||||
RI.Jit->WriteExit(RI.Build->GetImmValue(dest));
|
|
||||||
} else {
|
} else {
|
||||||
RI.Jit->WriteExitDestInReg(regLocForInst(RI, dest));
|
RI.Jit->WriteExitDestInReg(regLocForInst(RI, dest));
|
||||||
}
|
}
|
||||||
@ -282,7 +281,7 @@ static void regEmitCmp(RegInfo& RI, InstLoc I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit, u32 exitAddress) {
|
static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit) {
|
||||||
RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts());
|
RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts());
|
||||||
RI.Build = ibuild;
|
RI.Build = ibuild;
|
||||||
|
|
||||||
@ -734,10 +733,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitArmIL* Jit, u32 exitAddress) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Jit->WriteExit(exitAddress);
|
Jit->WriteExit(jit->js.curBlock->exitAddress[0], 0);
|
||||||
Jit->BKPT(0x111);
|
Jit->BKPT(0x111);
|
||||||
|
|
||||||
}
|
}
|
||||||
void JitArmIL::WriteCode(u32 exitAddress) {
|
void JitArmIL::WriteCode() {
|
||||||
DoWriteCode(&ibuild, this, exitAddress);
|
DoWriteCode(&ibuild, this);
|
||||||
}
|
}
|
||||||
|
@ -117,14 +117,13 @@ void JitArmIL::WriteExceptionExit()
|
|||||||
MOVI2R(R14, (u32)asm_routines.testExceptions);
|
MOVI2R(R14, (u32)asm_routines.testExceptions);
|
||||||
B(R14);
|
B(R14);
|
||||||
}
|
}
|
||||||
void JitArmIL::WriteExit(u32 destination)
|
void JitArmIL::WriteExit(u32 destination, int exit_num)
|
||||||
{
|
{
|
||||||
DoDownCount();
|
DoDownCount();
|
||||||
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
||||||
JitBlock *b = js.curBlock;
|
JitBlock *b = js.curBlock;
|
||||||
JitBlock::LinkData linkData;
|
b->exitAddress[exit_num] = destination;
|
||||||
linkData.exitAddress = destination;
|
b->exitPtrs[exit_num] = GetWritableCodePtr();
|
||||||
linkData.exitPtrs = GetWritableCodePtr();
|
|
||||||
|
|
||||||
// Link opportunity!
|
// Link opportunity!
|
||||||
int block = blocks.GetBlockNumberFromStartAddress(destination);
|
int block = blocks.GetBlockNumberFromStartAddress(destination);
|
||||||
@ -132,7 +131,7 @@ void JitArmIL::WriteExit(u32 destination)
|
|||||||
{
|
{
|
||||||
// It exists! Joy of joy!
|
// It exists! Joy of joy!
|
||||||
B(blocks.GetBlock(block)->checkedEntry);
|
B(blocks.GetBlock(block)->checkedEntry);
|
||||||
linkData.linkStatus = true;
|
b->linkStatus[exit_num] = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -141,8 +140,6 @@ void JitArmIL::WriteExit(u32 destination)
|
|||||||
MOVI2R(R14, (u32)asm_routines.dispatcher);
|
MOVI2R(R14, (u32)asm_routines.dispatcher);
|
||||||
B(R14);
|
B(R14);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->linkData.push_back(linkData);
|
|
||||||
}
|
}
|
||||||
void JitArmIL::PrintDebug(UGeckoInstruction inst, u32 level)
|
void JitArmIL::PrintDebug(UGeckoInstruction inst, u32 level)
|
||||||
{
|
{
|
||||||
@ -350,12 +347,12 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
|||||||
if (broken_block)
|
if (broken_block)
|
||||||
{
|
{
|
||||||
printf("Broken Block going to 0x%08x\n", nextPC);
|
printf("Broken Block going to 0x%08x\n", nextPC);
|
||||||
WriteExit(nextPC);
|
WriteExit(nextPC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform actual code generation
|
// Perform actual code generation
|
||||||
|
|
||||||
WriteCode(nextPC);
|
WriteCode();
|
||||||
b->flags = js.block_flags;
|
b->flags = js.block_flags;
|
||||||
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
||||||
b->originalSize = size;
|
b->originalSize = size;
|
||||||
|
@ -64,8 +64,8 @@ public:
|
|||||||
void Run();
|
void Run();
|
||||||
void SingleStep();
|
void SingleStep();
|
||||||
//
|
//
|
||||||
void WriteCode(u32 exitAddress);
|
void WriteCode();
|
||||||
void WriteExit(u32 destination);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
void WriteExitDestInReg(ARMReg Reg);
|
void WriteExitDestInReg(ARMReg Reg);
|
||||||
void WriteRfiExitDestInR(ARMReg Reg);
|
void WriteRfiExitDestInR(ARMReg Reg);
|
||||||
void WriteExceptionExit();
|
void WriteExceptionExit();
|
||||||
|
@ -35,6 +35,8 @@ op_agent_t agent;
|
|||||||
|
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
|
||||||
|
#define INVALID_EXIT 0xFFFFFFFF
|
||||||
|
|
||||||
bool JitBaseBlockCache::IsFull() const
|
bool JitBaseBlockCache::IsFull() const
|
||||||
{
|
{
|
||||||
return GetNumBlocks() >= MAX_NUM_BLOCKS - 1;
|
return GetNumBlocks() >= MAX_NUM_BLOCKS - 1;
|
||||||
@ -165,6 +167,12 @@ using namespace Gen;
|
|||||||
JitBlock &b = blocks[num_blocks];
|
JitBlock &b = blocks[num_blocks];
|
||||||
b.invalid = false;
|
b.invalid = false;
|
||||||
b.originalAddress = em_address;
|
b.originalAddress = em_address;
|
||||||
|
b.exitAddress[0] = INVALID_EXIT;
|
||||||
|
b.exitAddress[1] = INVALID_EXIT;
|
||||||
|
b.exitPtrs[0] = 0;
|
||||||
|
b.exitPtrs[1] = 0;
|
||||||
|
b.linkStatus[0] = false;
|
||||||
|
b.linkStatus[1] = false;
|
||||||
num_blocks++; //commit the current block
|
num_blocks++; //commit the current block
|
||||||
return num_blocks - 1;
|
return num_blocks - 1;
|
||||||
}
|
}
|
||||||
@ -185,9 +193,10 @@ using namespace Gen;
|
|||||||
block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num;
|
block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num;
|
||||||
if (block_link)
|
if (block_link)
|
||||||
{
|
{
|
||||||
for (const auto& e : b.linkData)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
links_to.insert(std::pair<u32, int>(e.exitAddress, block_num));
|
if (b.exitAddress[i] != INVALID_EXIT)
|
||||||
|
links_to.insert(std::pair<u32, int>(b.exitAddress[i], block_num));
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkBlock(block_num);
|
LinkBlock(block_num);
|
||||||
@ -266,15 +275,15 @@ using namespace Gen;
|
|||||||
// This block is dead. Don't relink it.
|
// This block is dead. Don't relink it.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto& e : b.linkData)
|
for (int e = 0; e < 2; e++)
|
||||||
{
|
{
|
||||||
if (!e.linkStatus)
|
if (b.exitAddress[e] != INVALID_EXIT && !b.linkStatus[e])
|
||||||
{
|
{
|
||||||
int destinationBlock = GetBlockNumberFromStartAddress(e.exitAddress);
|
int destinationBlock = GetBlockNumberFromStartAddress(b.exitAddress[e]);
|
||||||
if (destinationBlock != -1)
|
if (destinationBlock != -1)
|
||||||
{
|
{
|
||||||
WriteLinkBlock(e.exitPtrs, blocks[destinationBlock].checkedEntry);
|
WriteLinkBlock(b.exitPtrs[e], blocks[destinationBlock].checkedEntry);
|
||||||
e.linkStatus = true;
|
b.linkStatus[e] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,10 +316,10 @@ using namespace Gen;
|
|||||||
return;
|
return;
|
||||||
for (multimap<u32, int>::iterator iter = ppp.first; iter != ppp.second; ++iter) {
|
for (multimap<u32, int>::iterator iter = ppp.first; iter != ppp.second; ++iter) {
|
||||||
JitBlock &sourceBlock = blocks[iter->second];
|
JitBlock &sourceBlock = blocks[iter->second];
|
||||||
for (auto& e : sourceBlock.linkData)
|
for (int e = 0; e < 2; e++)
|
||||||
{
|
{
|
||||||
if (e.exitAddress == b.originalAddress)
|
if (sourceBlock.exitAddress[e] == b.originalAddress)
|
||||||
e.linkStatus = false;
|
sourceBlock.linkStatus[e] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,9 @@ struct JitBlock
|
|||||||
const u8 *checkedEntry;
|
const u8 *checkedEntry;
|
||||||
const u8 *normalEntry;
|
const u8 *normalEntry;
|
||||||
|
|
||||||
|
u8 *exitPtrs[2]; // to be able to rewrite the exit jum
|
||||||
|
u32 exitAddress[2]; // 0xFFFFFFFF == unknown
|
||||||
|
|
||||||
u32 originalAddress;
|
u32 originalAddress;
|
||||||
u32 codeSize;
|
u32 codeSize;
|
||||||
u32 originalSize;
|
u32 originalSize;
|
||||||
@ -42,13 +45,7 @@ struct JitBlock
|
|||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
bool invalid;
|
bool invalid;
|
||||||
|
bool linkStatus[2];
|
||||||
struct LinkData {
|
|
||||||
u8 *exitPtrs; // to be able to rewrite the exit jum
|
|
||||||
u32 exitAddress;
|
|
||||||
bool linkStatus; // is it already linked?
|
|
||||||
};
|
|
||||||
std::vector<LinkData> linkData;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// we don't really need to save start and stop
|
// we don't really need to save start and stop
|
||||||
|
@ -1028,6 +1028,59 @@ void CFrame::OnMouse(wxMouseEvent& event)
|
|||||||
event.GetPosition().x, event.GetPosition().y, event.ButtonDown());
|
event.GetPosition().x, event.GetPosition().y, event.ButtonDown());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// next handlers are all for FreeLook, so we don't need to check them if disabled
|
||||||
|
if(!g_Config.bFreeLook)
|
||||||
|
{
|
||||||
|
event.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free look variables
|
||||||
|
static bool mouseLookEnabled = false;
|
||||||
|
static bool mouseMoveEnabled = false;
|
||||||
|
static float lastMouse[2];
|
||||||
|
|
||||||
|
if(event.MiddleDown())
|
||||||
|
{
|
||||||
|
lastMouse[0] = event.GetX();
|
||||||
|
lastMouse[1] = event.GetY();
|
||||||
|
mouseMoveEnabled = true;
|
||||||
|
}
|
||||||
|
else if(event.RightDown())
|
||||||
|
{
|
||||||
|
lastMouse[0] = event.GetX();
|
||||||
|
lastMouse[1] = event.GetY();
|
||||||
|
mouseLookEnabled = true;
|
||||||
|
}
|
||||||
|
else if(event.MiddleUp())
|
||||||
|
{
|
||||||
|
mouseMoveEnabled = false;
|
||||||
|
}
|
||||||
|
else if(event.RightUp())
|
||||||
|
{
|
||||||
|
mouseLookEnabled = false;
|
||||||
|
}
|
||||||
|
// no button, so it's a move event
|
||||||
|
else if(event.GetButton() == wxMOUSE_BTN_NONE)
|
||||||
|
{
|
||||||
|
if (mouseLookEnabled)
|
||||||
|
{
|
||||||
|
VertexShaderManager::RotateView((event.GetX() - lastMouse[0]) / 200.0f,
|
||||||
|
(event.GetY() - lastMouse[1]) / 200.0f);
|
||||||
|
lastMouse[0] = event.GetX();
|
||||||
|
lastMouse[1] = event.GetY();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouseMoveEnabled)
|
||||||
|
{
|
||||||
|
VertexShaderManager::TranslateView((event.GetX() - lastMouse[0]) / 50.0f,
|
||||||
|
(event.GetY() - lastMouse[1]) / 50.0f);
|
||||||
|
lastMouse[0] = event.GetX();
|
||||||
|
lastMouse[1] = event.GetY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "../GLInterface.h"
|
#include "../GLInterface.h"
|
||||||
#include "VertexShaderManager.h"
|
|
||||||
|
|
||||||
#if USE_EGL
|
#if USE_EGL
|
||||||
bool cXInterface::ServerConnect(void)
|
bool cXInterface::ServerConnect(void)
|
||||||
@ -166,10 +165,6 @@ void cX11Window::DestroyXWindow(void)
|
|||||||
void cX11Window::XEventThread()
|
void cX11Window::XEventThread()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Free look variables
|
|
||||||
static bool mouseLookEnabled = false;
|
|
||||||
static bool mouseMoveEnabled = false;
|
|
||||||
static float lastMouse[2];
|
|
||||||
while (GLWin.win)
|
while (GLWin.win)
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
@ -177,58 +172,6 @@ void cX11Window::XEventThread()
|
|||||||
{
|
{
|
||||||
XNextEvent(GLWin.evdpy, &event);
|
XNextEvent(GLWin.evdpy, &event);
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case ButtonPress:
|
|
||||||
if (g_Config.bFreeLook)
|
|
||||||
{
|
|
||||||
switch (event.xbutton.button)
|
|
||||||
{
|
|
||||||
case 2: // Middle button
|
|
||||||
lastMouse[0] = event.xbutton.x;
|
|
||||||
lastMouse[1] = event.xbutton.y;
|
|
||||||
mouseMoveEnabled = true;
|
|
||||||
break;
|
|
||||||
case 3: // Right button
|
|
||||||
lastMouse[0] = event.xbutton.x;
|
|
||||||
lastMouse[1] = event.xbutton.y;
|
|
||||||
mouseLookEnabled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
|
||||||
if (g_Config.bFreeLook)
|
|
||||||
{
|
|
||||||
switch (event.xbutton.button)
|
|
||||||
{
|
|
||||||
case 2: // Middle button
|
|
||||||
mouseMoveEnabled = false;
|
|
||||||
break;
|
|
||||||
case 3: // Right button
|
|
||||||
mouseLookEnabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MotionNotify:
|
|
||||||
if (g_Config.bFreeLook)
|
|
||||||
{
|
|
||||||
if (mouseLookEnabled)
|
|
||||||
{
|
|
||||||
VertexShaderManager::RotateView((event.xmotion.x - lastMouse[0]) / 200.0f,
|
|
||||||
(event.xmotion.y - lastMouse[1]) / 200.0f);
|
|
||||||
lastMouse[0] = event.xmotion.x;
|
|
||||||
lastMouse[1] = event.xmotion.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouseMoveEnabled)
|
|
||||||
{
|
|
||||||
VertexShaderManager::TranslateView((event.xmotion.x - lastMouse[0]) / 50.0f,
|
|
||||||
(event.xmotion.y - lastMouse[1]) / 50.0f);
|
|
||||||
lastMouse[0] = event.xmotion.x;
|
|
||||||
lastMouse[1] = event.xmotion.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
GLInterface->SetBackBufferDimensions(event.xconfigure.width, event.xconfigure.height);
|
GLInterface->SetBackBufferDimensions(event.xconfigure.width, event.xconfigure.height);
|
||||||
break;
|
break;
|
||||||
|
@ -200,7 +200,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
|||||||
|
|
||||||
char ps_rgba6_to_rgb8[] =
|
char ps_rgba6_to_rgb8[] =
|
||||||
"uniform sampler2DRect samp9;\n"
|
"uniform sampler2DRect samp9;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" ivec4 src6 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 63.f));\n"
|
" ivec4 src6 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 63.f));\n"
|
||||||
@ -214,7 +214,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
|
|||||||
|
|
||||||
char ps_rgb8_to_rgba6[] =
|
char ps_rgb8_to_rgba6[] =
|
||||||
"uniform sampler2DRect samp9;\n"
|
"uniform sampler2DRect samp9;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" ivec4 src8 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 255.f));\n"
|
" ivec4 src8 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 255.f));\n"
|
||||||
|
@ -127,7 +127,7 @@ static const char *s_fragmentShaderSrc =
|
|||||||
"uniform sampler2D samp8;\n"
|
"uniform sampler2D samp8;\n"
|
||||||
"uniform vec4 color;\n"
|
"uniform vec4 color;\n"
|
||||||
"VARYIN vec2 uv0;\n"
|
"VARYIN vec2 uv0;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" ocol0 = texture(samp8,uv0) * color;\n"
|
" ocol0 = texture(samp8,uv0) * color;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
@ -665,7 +665,7 @@ void Renderer::Init()
|
|||||||
" c = vec4(color0, 1.0);\n"
|
" c = vec4(color0, 1.0);\n"
|
||||||
"}\n",
|
"}\n",
|
||||||
"VARYIN vec4 c;\n"
|
"VARYIN vec4 c;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
" ocol0 = c;\n"
|
" ocol0 = c;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
|
@ -406,7 +406,7 @@ TextureCache::TextureCache()
|
|||||||
"uniform sampler2DRect samp9;\n"
|
"uniform sampler2DRect samp9;\n"
|
||||||
"uniform vec4 colmat[7];\n"
|
"uniform vec4 colmat[7];\n"
|
||||||
"VARYIN vec2 uv0;\n"
|
"VARYIN vec2 uv0;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void main(){\n"
|
"void main(){\n"
|
||||||
" vec4 texcol = texture2DRect(samp9, uv0);\n"
|
" vec4 texcol = texture2DRect(samp9, uv0);\n"
|
||||||
@ -418,7 +418,7 @@ TextureCache::TextureCache()
|
|||||||
"uniform sampler2DRect samp9;\n"
|
"uniform sampler2DRect samp9;\n"
|
||||||
"uniform vec4 colmat[5];\n"
|
"uniform vec4 colmat[5];\n"
|
||||||
"VARYIN vec2 uv0;\n"
|
"VARYIN vec2 uv0;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void main(){\n"
|
"void main(){\n"
|
||||||
" vec4 texcol = texture2DRect(samp9, uv0);\n"
|
" vec4 texcol = texture2DRect(samp9, uv0);\n"
|
||||||
|
@ -42,9 +42,10 @@ static SHADER s_encodingPrograms[NUM_ENCODING_PROGRAMS];
|
|||||||
|
|
||||||
static GLuint s_encode_VBO = 0;
|
static GLuint s_encode_VBO = 0;
|
||||||
static GLuint s_encode_VAO = 0;
|
static GLuint s_encode_VAO = 0;
|
||||||
static GLuint s_decode_VAO = 0;
|
|
||||||
static TargetRectangle s_cached_sourceRc;
|
static TargetRectangle s_cached_sourceRc;
|
||||||
|
|
||||||
|
static GLuint s_PBO = 0; // for readback with different strides
|
||||||
|
|
||||||
static const char *VProgram =
|
static const char *VProgram =
|
||||||
"ATTRIN vec2 rawpos;\n"
|
"ATTRIN vec2 rawpos;\n"
|
||||||
"ATTRIN vec2 tex0;\n"
|
"ATTRIN vec2 tex0;\n"
|
||||||
@ -77,7 +78,7 @@ void CreatePrograms()
|
|||||||
const char *FProgramRgbToYuyv =
|
const char *FProgramRgbToYuyv =
|
||||||
"uniform sampler2DRect samp9;\n"
|
"uniform sampler2DRect samp9;\n"
|
||||||
"VARYIN vec2 uv0;\n"
|
"VARYIN vec2 uv0;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" vec3 c0 = texture2DRect(samp9, uv0 - dFdx(uv0) * 0.25).rgb;\n"
|
" vec3 c0 = texture2DRect(samp9, uv0 - dFdx(uv0) * 0.25).rgb;\n"
|
||||||
@ -106,7 +107,7 @@ void CreatePrograms()
|
|||||||
const char *FProgramYuyvToRgb =
|
const char *FProgramYuyvToRgb =
|
||||||
"uniform sampler2DRect samp9;\n"
|
"uniform sampler2DRect samp9;\n"
|
||||||
"VARYIN vec2 uv0;\n"
|
"VARYIN vec2 uv0;\n"
|
||||||
"COLOROUT(ocol0)\n"
|
"out vec4 ocol0;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" ivec2 uv = ivec2(gl_FragCoord.xy);\n"
|
" ivec2 uv = ivec2(gl_FragCoord.xy);\n"
|
||||||
@ -118,7 +119,7 @@ void CreatePrograms()
|
|||||||
" ivec2 ts = textureSize(samp9);\n"
|
" ivec2 ts = textureSize(samp9);\n"
|
||||||
" vec4 c0 = texelFetch(samp9, ivec2(uv.x/2, ts.y-uv.y-1));\n"
|
" vec4 c0 = texelFetch(samp9, ivec2(uv.x/2, ts.y-uv.y-1));\n"
|
||||||
#endif
|
#endif
|
||||||
" float y = mix(c0.b, c0.r, uv.x & 1);\n"
|
" float y = mix(c0.b, c0.r, (uv.x & 1) == 1);\n"
|
||||||
" float yComp = 1.164 * (y - 0.0625);\n"
|
" float yComp = 1.164 * (y - 0.0625);\n"
|
||||||
" float uComp = c0.g - 0.5;\n"
|
" float uComp = c0.g - 0.5;\n"
|
||||||
" float vComp = c0.a - 0.5;\n"
|
" float vComp = c0.a - 0.5;\n"
|
||||||
@ -177,9 +178,6 @@ void Init()
|
|||||||
s_cached_sourceRc.left = -1;
|
s_cached_sourceRc.left = -1;
|
||||||
s_cached_sourceRc.right = -1;
|
s_cached_sourceRc.right = -1;
|
||||||
|
|
||||||
glGenVertexArrays(1, &s_decode_VAO );
|
|
||||||
glBindVertexArray( s_decode_VAO );
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + 9);
|
glActiveTexture(GL_TEXTURE0 + 9);
|
||||||
glGenTextures(1, &s_srcTexture);
|
glGenTextures(1, &s_srcTexture);
|
||||||
glBindTexture(getFbType(), s_srcTexture);
|
glBindTexture(getFbType(), s_srcTexture);
|
||||||
@ -190,6 +188,8 @@ void Init()
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderBufferWidth, renderBufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderBufferWidth, renderBufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
|
glGenBuffers(1, &s_PBO);
|
||||||
|
|
||||||
CreatePrograms();
|
CreatePrograms();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ void Shutdown()
|
|||||||
glDeleteFramebuffers(1, &s_texConvFrameBuffer);
|
glDeleteFramebuffers(1, &s_texConvFrameBuffer);
|
||||||
glDeleteBuffers(1, &s_encode_VBO );
|
glDeleteBuffers(1, &s_encode_VBO );
|
||||||
glDeleteVertexArrays(1, &s_encode_VAO );
|
glDeleteVertexArrays(1, &s_encode_VAO );
|
||||||
glDeleteVertexArrays(1, &s_decode_VAO );
|
glDeleteBuffers(1, &s_PBO);
|
||||||
|
|
||||||
s_rgbToYuyvProgram.Destroy();
|
s_rgbToYuyvProgram.Destroy();
|
||||||
s_yuyvToRgbProgram.Destroy();
|
s_yuyvToRgbProgram.Destroy();
|
||||||
@ -211,6 +211,7 @@ void Shutdown()
|
|||||||
s_srcTexture = 0;
|
s_srcTexture = 0;
|
||||||
s_dstTexture = 0;
|
s_dstTexture = 0;
|
||||||
s_texConvFrameBuffer = 0;
|
s_texConvFrameBuffer = 0;
|
||||||
|
s_PBO = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
|
void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||||
@ -272,25 +273,37 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
|
|||||||
// TODO: make this less slow.
|
// TODO: make this less slow.
|
||||||
|
|
||||||
int writeStride = bpmem.copyMipMapStrideChannels * 32;
|
int writeStride = bpmem.copyMipMapStrideChannels * 32;
|
||||||
|
int dstSize = dstWidth*dstHeight*4;
|
||||||
|
int readHeight = readStride / dstWidth / 4; // 4 bytes per pixel
|
||||||
|
int readLoops = dstHeight / readHeight;
|
||||||
|
|
||||||
if (writeStride != readStride && toTexture)
|
if (writeStride != readStride && readLoops > 1 && toTexture)
|
||||||
{
|
{
|
||||||
// writing to a texture of a different size
|
// writing to a texture of a different size
|
||||||
|
// also copy more then one block line, so the different strides matters
|
||||||
|
// copy into one pbo first, map this buffer, and then memcpy into gc memory
|
||||||
|
// in this way, we only have one vram->ram transfer, but maybe a bigger
|
||||||
|
// cpu overhead because of the pbo
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, s_PBO);
|
||||||
|
glBufferData(GL_PIXEL_PACK_BUFFER, dstSize, NULL, GL_STREAM_READ);
|
||||||
|
glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
u8* pbo = (u8*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, dstSize, GL_MAP_READ_BIT);
|
||||||
|
|
||||||
int readHeight = readStride / dstWidth;
|
//int readStart = 0;
|
||||||
readHeight /= 4; // 4 bytes per pixel
|
|
||||||
|
|
||||||
int readStart = 0;
|
|
||||||
int readLoops = dstHeight / readHeight;
|
|
||||||
for (int i = 0; i < readLoops; i++)
|
for (int i = 0; i < readLoops; i++)
|
||||||
{
|
{
|
||||||
glReadPixels(0, readStart, (GLsizei)dstWidth, (GLsizei)readHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
memcpy(destAddr, pbo, readStride);
|
||||||
readStart += readHeight;
|
pbo += readStride;
|
||||||
destAddr += writeStride;
|
destAddr += writeStride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
||||||
|
}
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
@ -405,7 +418,6 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
|||||||
glViewport(0, 0, srcWidth, srcHeight);
|
glViewport(0, 0, srcWidth, srcHeight);
|
||||||
s_yuyvToRgbProgram.Bind();
|
s_yuyvToRgbProgram.Bind();
|
||||||
|
|
||||||
glBindVertexArray( s_decode_VAO );
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "EmuWindow.h"
|
#include "EmuWindow.h"
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "VertexShaderManager.h"
|
|
||||||
#include "VideoBackendBase.h"
|
#include "VideoBackendBase.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
@ -41,60 +40,8 @@ HWND GetParentWnd()
|
|||||||
return m_hParent;
|
return m_hParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeLookInput( UINT iMsg, WPARAM wParam )
|
|
||||||
{
|
|
||||||
static bool mouseLookEnabled = false;
|
|
||||||
static bool mouseMoveEnabled = false;
|
|
||||||
static float lastMouse[2];
|
|
||||||
POINT point;
|
|
||||||
|
|
||||||
switch(iMsg)
|
|
||||||
{
|
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
if (mouseLookEnabled)
|
|
||||||
{
|
|
||||||
GetCursorPos(&point);
|
|
||||||
VertexShaderManager::RotateView((point.x - lastMouse[0]) / 200.0f, (point.y - lastMouse[1]) / 200.0f);
|
|
||||||
lastMouse[0] = (float)point.x;
|
|
||||||
lastMouse[1] = (float)point.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouseMoveEnabled)
|
|
||||||
{
|
|
||||||
GetCursorPos(&point);
|
|
||||||
VertexShaderManager::TranslateView((point.x - lastMouse[0]) / 50.0f, (point.y - lastMouse[1]) / 50.0f);
|
|
||||||
lastMouse[0] = (float)point.x;
|
|
||||||
lastMouse[1] = (float)point.y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
GetCursorPos(&point);
|
|
||||||
lastMouse[0] = (float)point.x;
|
|
||||||
lastMouse[1] = (float)point.y;
|
|
||||||
mouseLookEnabled= true;
|
|
||||||
break;
|
|
||||||
case WM_MBUTTONDOWN:
|
|
||||||
GetCursorPos(&point);
|
|
||||||
lastMouse[0] = (float)point.x;
|
|
||||||
lastMouse[1] = (float)point.y;
|
|
||||||
mouseMoveEnabled= true;
|
|
||||||
break;
|
|
||||||
case WM_RBUTTONUP:
|
|
||||||
mouseLookEnabled = false;
|
|
||||||
break;
|
|
||||||
case WM_MBUTTONUP:
|
|
||||||
mouseMoveEnabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
|
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bFreeLook)
|
|
||||||
FreeLookInput( iMsg, wParam );
|
|
||||||
|
|
||||||
switch( iMsg )
|
switch( iMsg )
|
||||||
{
|
{
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
|
@ -304,7 +304,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
|||||||
|
|
||||||
if (ApiType == API_OPENGL)
|
if (ApiType == API_OPENGL)
|
||||||
{
|
{
|
||||||
out.Write("COLOROUT(ocol0)\n");
|
out.Write("out vec4 ocol0;\n");
|
||||||
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
|
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
|
||||||
out.Write("out vec4 ocol1;\n");
|
out.Write("out vec4 ocol1;\n");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user