Skip to content

Commit

Permalink
Add new speedhack: Render Directly to Host BackBuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeUsher committed Jun 9, 2018
1 parent 6a0a025 commit ef351ee
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 27 deletions.
8 changes: 6 additions & 2 deletions resource/Cxbx.rc
Expand Up @@ -482,9 +482,13 @@ BEGIN
END
POPUP "Hacks", 65535,MFT_STRING,MFS_ENABLED
BEGIN
POPUP "Speed Hacks", ID_HACKS_SPEEDHACKS,MFT_STRING,MFS_ENABLED
BEGIN
MENUITEM "Run Xbox threads on all cores", ID_HACKS_RUNXBOXTHREADSONALLCORES,MFT_STRING,MFS_ENABLED
MENUITEM "Render directly to Host Backbuffer", ID_HACKS_RENDERDIRECTLYTOHOSTBACKBUFFER,MFT_STRING,MFS_ENABLED
MENUITEM "Uncap Framerate", ID_HACKS_UNCAPFRAMERATE,MFT_STRING,MFS_ENABLED
END
MENUITEM "Disable Pixel Shaders", ID_HACKS_DISABLEPIXELSHADERS,MFT_STRING,MFS_ENABLED
MENUITEM "Uncap Framerate", ID_HACKS_UNCAPFRAMERATE,MFT_STRING,MFS_ENABLED
MENUITEM "Run Xbox threads on all cores", ID_HACKS_RUNXBOXTHREADSONALLCORES,MFT_STRING,MFS_ENABLED
MENUITEM "Skip rdtsc patching", ID_HACKS_SKIPRDTSCPATCHING,MFT_STRING,MFS_ENABLED
MENUITEM "Scale Xbox viewport to host (and back)", ID_HACKS_SCALEVIEWPORT,MFT_STRING,MFS_ENABLED
END
Expand Down
6 changes: 4 additions & 2 deletions src/Cxbx/ResCxbx.h
@@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by C:\Work\Cxbx-Reloaded\resource\Cxbx.rc
// Used by C:\Users\lukeu\Desktop\Projects\cxbx-reloaded\resource\Cxbx.rc
//
#define IDI_CXBX 101
#define IDB_SPLASH 102
Expand Down Expand Up @@ -277,14 +277,16 @@
#define ID_HACKS_SKIPRDTSCPATCHING 40099
#define ID_HACKS_SCALEVIEWPORT 40100
#define ID_SETTINGS_CONFIG_XBOX_CONTROLLER_MAPPING 40101
#define ID_HACKS_RENDERDIRECTLYTOHOSTBACKBUFFER 40102
#define ID_HACKS_SPEEDHACKS 40103
#define IDC_STATIC -1

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 135
#define _APS_NEXT_COMMAND_VALUE 40102
#define _APS_NEXT_COMMAND_VALUE 40104
#define _APS_NEXT_CONTROL_VALUE 1256
#define _APS_NEXT_SYMED_VALUE 104
#endif
Expand Down
19 changes: 19 additions & 0 deletions src/Cxbx/WndMain.cpp
Expand Up @@ -225,6 +225,13 @@ WndMain::WndMain(HINSTANCE x_hInstance) :
m_ScaleViewport = 0;
}

dwType = REG_DWORD; dwSize = sizeof(DWORD);
result = RegQueryValueEx(hKey, "HackDirectBackBufferAccess", NULL, &dwType, (PBYTE)&m_DirectHostBackBufferAccess, &dwSize);
if (result != ERROR_SUCCESS) {
m_DirectHostBackBufferAccess = 0;
}


dwType = REG_DWORD; dwSize = sizeof(DWORD);
result = RegQueryValueEx(hKey, "CxbxDebug", NULL, &dwType, (PBYTE)&m_CxbxDebug, &dwSize);
if (result != ERROR_SUCCESS) {
Expand Down Expand Up @@ -390,6 +397,9 @@ WndMain::~WndMain()
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "HackScaleViewport", 0, dwType, (PBYTE)&m_ScaleViewport, dwSize);

dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "HackDirectBackBufferAccess", 0, dwType, (PBYTE)&m_DirectHostBackBufferAccess, dwSize);

dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "CxbxDebug", 0, dwType, (PBYTE)&m_CxbxDebug, dwSize);

Expand Down Expand Up @@ -1367,6 +1377,11 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
RefreshMenus();
break;

case ID_HACKS_RENDERDIRECTLYTOHOSTBACKBUFFER:
m_DirectHostBackBufferAccess = !m_DirectHostBackBufferAccess;
RefreshMenus();
break;

case ID_HELP_ABOUT:
{
ShowAboutDialog(hwnd);
Expand Down Expand Up @@ -1800,6 +1815,9 @@ void WndMain::RefreshMenus()

chk_flag = (m_ScaleViewport) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_HACKS_SCALEVIEWPORT, chk_flag);

chk_flag = (m_DirectHostBackBufferAccess) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_HACKS_RENDERDIRECTLYTOHOSTBACKBUFFER, chk_flag);
}

// emulation menu
Expand Down Expand Up @@ -2175,6 +2193,7 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /
g_EmuShared->SetUseAllCores(&m_UseAllCores);
g_EmuShared->SetSkipRdtscPatching(&m_SkipRdtscPatching);
g_EmuShared->SetScaleViewport(&m_ScaleViewport);
g_EmuShared->SetDirectHostBackBufferAccess(&m_DirectHostBackBufferAccess);

if (m_ScaleViewport) {
// Set the window size to emulation dimensions
Expand Down
5 changes: 3 additions & 2 deletions src/Cxbx/WndMain.h
Expand Up @@ -222,7 +222,8 @@ class WndMain : public Wnd
int m_UncapFramerate;
int m_UseAllCores;
int m_SkipRdtscPatching;
int m_ScaleViewport;
int m_ScaleViewport;
int m_DirectHostBackBufferAccess;

// ******************************************************************
// * debug output filenames
Expand All @@ -232,4 +233,4 @@ class WndMain : public Wnd

};

#endif
#endif
3 changes: 3 additions & 0 deletions src/CxbxKrnl/CxbxKrnl.cpp
Expand Up @@ -607,6 +607,7 @@ void PrintCurrentConfigurationLog()
printf("Run Xbox threads on all cores: %s\n", g_UseAllCores == 1 ? "On" : "Off");
printf("Skip RDTSC Patching: %s\n", g_SkipRdtscPatching == 1 ? "On" : "Off");
printf("Scale Xbox to host viewport (and back): %s\n", g_ScaleViewport == 1 ? "On" : "Off");
printf("Render directly to Host BackBuffer: %s\n", g_DirectHostBackBufferAccess == 1 ? "On" : "Off");
}

printf("------------------------- END OF CONFIG LOG ------------------------\n");
Expand Down Expand Up @@ -1252,6 +1253,8 @@ __declspec(noreturn) void CxbxKrnlInit
g_SkipRdtscPatching = !!HackEnabled;
g_EmuShared->GetScaleViewport(&HackEnabled);
g_ScaleViewport = !!HackEnabled;
g_EmuShared->GetDirectHostBackBufferAccess(&HackEnabled);
g_DirectHostBackBufferAccess = !!HackEnabled;
}

#ifdef _DEBUG_PRINT_CURRENT_CONF
Expand Down
3 changes: 2 additions & 1 deletion src/CxbxKrnl/Emu.cpp
Expand Up @@ -68,7 +68,8 @@ bool g_DisablePixelShaders = false;
bool g_UncapFramerate = false;
bool g_UseAllCores = false;
bool g_SkipRdtscPatching = false;
bool g_ScaleViewport = false;
bool g_ScaleViewport = false;
bool g_DirectHostBackBufferAccess = false;

// Delta added to host SystemTime, used in xboxkrnl::KeQuerySystemTime and xboxkrnl::NtSetSystemTime
LARGE_INTEGER HostSystemTimeDelta = {};
Expand Down
3 changes: 2 additions & 1 deletion src/CxbxKrnl/Emu.h
Expand Up @@ -111,5 +111,6 @@ extern bool g_DisablePixelShaders;
extern bool g_UncapFramerate;
extern bool g_UseAllCores;
extern bool g_SkipRdtscPatching;
extern bool g_ScaleViewport;
extern bool g_ScaleViewport;
extern bool g_DirectHostBackBufferAccess;
#endif
53 changes: 36 additions & 17 deletions src/CxbxKrnl/EmuD3D8.cpp
Expand Up @@ -4601,24 +4601,26 @@ DWORD WINAPI XTL::EMUPATCH(D3DDevice_Swap)
// Previously we used D3DX_FILTER_POINT here, but that gave jagged edges in Dashboard.
// Dxbx note : D3DX_FILTER_LINEAR gives a smoother image, but 'bleeds' across borders

auto pXboxBackBufferHostSurface = GetHostSurface(g_XboxBackBufferSurface);
if (pXboxBackBufferHostSurface) {
// Blit Xbox BackBuffer to host BackBuffer
// TODO: This could be much faster if we used the XboxBackBufferSurface as a texture and blitted with a fullscreen quad
// This way, the scaling/format conversion would be handled by the GPU instead
// If we were using native D3D9, we could just use StretchRects instead, but D3D8 doesn't have that feature!
hRet = D3DXLoadSurfaceFromSurface(
/* pDestSurface = */ pCurrentHostBackBuffer,
/* pDestPalette = */ nullptr,
/* pDestRect = */ nullptr,
/* pSrcSurface = */ pXboxBackBufferHostSurface,
/* pSrcPalette = */ nullptr,
/* pSrcRect = */ nullptr,
/* Filter = */ LoadSurfaceFilter,
/* ColorKey = */ 0);
if (!g_DirectHostBackBufferAccess) {
auto pXboxBackBufferHostSurface = GetHostSurface(g_XboxBackBufferSurface);
if (pXboxBackBufferHostSurface) {
// Blit Xbox BackBuffer to host BackBuffer
// TODO: This could be much faster if we used the XboxBackBufferSurface as a texture and blitted with a fullscreen quad
// This way, the scaling/format conversion would be handled by the GPU instead
// If we were using native D3D9, we could just use StretchRects instead, but D3D8 doesn't have that feature!
hRet = D3DXLoadSurfaceFromSurface(
/* pDestSurface = */ pCurrentHostBackBuffer,
/* pDestPalette = */ nullptr,
/* pDestRect = */ nullptr,
/* pSrcSurface = */ pXboxBackBufferHostSurface,
/* pSrcPalette = */ nullptr,
/* pSrcRect = */ nullptr,
/* Filter = */ LoadSurfaceFilter,
/* ColorKey = */ 0);

if (hRet != D3D_OK) {
EmuWarning("Couldn't blit Xbox BackBuffer to host BackBuffer : %X", hRet);
if (hRet != D3D_OK) {
EmuWarning("Couldn't blit Xbox BackBuffer to host BackBuffer : %X", hRet);
}
}
}

Expand Down Expand Up @@ -8087,6 +8089,19 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderTarget)
g_pXboxDepthStencil = pNewZStencil;
pHostDepthStencil = GetHostSurface(g_pXboxDepthStencil, D3DUSAGE_DEPTHSTENCIL);

if (g_DirectHostBackBufferAccess && pRenderTarget == g_XboxBackBufferSurface) {
HRESULT hRet = g_pD3DDevice->GetBackBuffer(
#ifdef CXBX_USE_D3D9
0, // iSwapChain
#endif
0, D3DBACKBUFFER_TYPE_MONO, &pHostRenderTarget);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetBackBuffer");

if (FAILED(hRet)) {
CxbxKrnlCleanup("Could not get host backbuffer");
}
}

HRESULT hRet;
#ifdef CXBX_USE_D3D9
// Mimick Direct3D 8 SetRenderTarget by only setting render target if non-null
Expand All @@ -8106,6 +8121,10 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderTarget)
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderTarget");
#endif

if (g_DirectHostBackBufferAccess && pRenderTarget == g_XboxBackBufferSurface) {
pHostRenderTarget->Release();
}

if (SUCCEEDED(hRet)) {
// Once we're sure the host depth-stencil is activated...
UpdateDepthStencilFlags(pHostDepthStencil);
Expand Down
7 changes: 5 additions & 2 deletions src/CxbxKrnl/EmuShared.h
Expand Up @@ -129,7 +129,9 @@ class EmuShared : public Mutex
void GetSkipRdtscPatching(int* value) { Lock(); *value = m_SkipRdtscPatching; Unlock(); }
void SetSkipRdtscPatching(int* value) { Lock(); m_SkipRdtscPatching = *value; Unlock(); }
void GetScaleViewport(int* value) { Lock(); *value = m_ScaleViewport; Unlock(); }
void SetScaleViewport(int* value) { Lock(); m_ScaleViewport = *value; Unlock(); }
void SetScaleViewport(int* value) { Lock(); m_ScaleViewport = *value; Unlock(); }
void GetDirectHostBackBufferAccess(int* value) { Lock(); *value = m_DirectHostBackBufferAccess; Unlock(); }
void SetDirectHostBackBufferAccess(int* value) { Lock(); m_DirectHostBackBufferAccess = *value; Unlock(); }

// ******************************************************************
// * MSpF/Benchmark values Accessors
Expand Down Expand Up @@ -204,7 +206,8 @@ class EmuShared : public Mutex
bool m_bMultiXbeFlag;
bool m_bDebugging;
int m_LedSequence[4];
int m_ScaleViewport;
int m_ScaleViewport;
int m_DirectHostBackBufferAccess;
};

// ******************************************************************
Expand Down

0 comments on commit ef351ee

Please sign in to comment.