Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit 12eb1e1

Browse files
committed
Merge branch 'dev/lvengesanam/implement_missing_apis' into 'main'
Implement missing APIs on bridge See merge request lightspeedrtx/bridge-remix-nv!141
2 parents 5faf22a + 17b17c6 commit 12eb1e1

File tree

3 files changed

+97
-56
lines changed

3 files changed

+97
-56
lines changed

src/client/d3d9_device.cpp

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void Direct3DDevice9Ex_LSS<EnableSync>::onDestroy() {
7171
}
7272

7373
template<bool EnableSync>
74-
void Direct3DDevice9Ex_LSS<EnableSync>::releaseInternalObjects() {
74+
void Direct3DDevice9Ex_LSS<EnableSync>::releaseInternalObjects(bool resetState) {
7575
// Take references first so that the device won't be
7676
// destroyed unintentionally and to prevent releaseInternalObjects()
7777
// recursion.
@@ -82,23 +82,25 @@ void Direct3DDevice9Ex_LSS<EnableSync>::releaseInternalObjects() {
8282

8383
destroyImplicitObjects();
8484

85-
for (auto& texture : m_state.textures) {
86-
texture.reset(nullptr);
87-
}
85+
if (resetState) {
86+
for (auto& texture : m_state.textures) {
87+
texture.reset(nullptr);
88+
}
8889

89-
for (auto& rt : m_state.renderTargets) {
90-
rt.reset(nullptr);
91-
}
90+
for (auto& rt : m_state.renderTargets) {
91+
rt.reset(nullptr);
92+
}
9293

93-
for (auto& st : m_state.streams) {
94-
st.reset(nullptr);
95-
}
94+
for (auto& st : m_state.streams) {
95+
st.reset(nullptr);
96+
}
9697

97-
m_state.indices.reset(nullptr);
98-
m_state.depthStencil.reset(nullptr);
99-
m_state.vertexShader.reset(nullptr);
100-
m_state.pixelShader.reset(nullptr);
101-
m_state.vertexDecl.reset(nullptr);
98+
m_state.indices.reset(nullptr);
99+
m_state.depthStencil.reset(nullptr);
100+
m_state.vertexShader.reset(nullptr);
101+
m_state.pixelShader.reset(nullptr);
102+
m_state.vertexDecl.reset(nullptr);
103+
}
102104

103105
for (uint32_t n = 0; n < implicitRefCnt; n++) {
104106
D3DBase::Release();
@@ -481,47 +483,19 @@ template<bool EnableSync>
481483
HRESULT Direct3DDevice9Ex_LSS<EnableSync>::Present(CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) {
482484
ZoneScoped;
483485
LogFunctionCall();
484-
#ifdef ENABLE_PRESENT_SEMAPHORE_TRACE
485-
Logger::trace(format_string("Present(): ClientMessage counter is at %d.", ClientMessage::get_counter()));
486-
#endif
487-
ClientMessage::reset_counter();
488-
gSceneState = WaitBeginScene;
489-
490-
const auto hresult = D3D_OK;
491486

492487
// If the bridge was disabled in the meantime for some reason we want to bail
493488
// out here so we don't spend time waiting on the Present semaphore or trying
494489
// to send keyboard state to the server.
495490
if (!gbBridgeRunning) {
496-
return hresult;
491+
return D3D_OK;
497492
}
498493

499-
if(remixapi::g_bInterfaceInitialized && remixapi::g_presentCallback) {
494+
if (remixapi::g_bInterfaceInitialized && remixapi::g_presentCallback) {
500495
remixapi::g_presentCallback();
501496
}
502497

503-
504-
if (SUCCEEDED(hresult)) {
505-
BRIDGE_DEVICE_LOCKGUARD();
506-
507-
// Send present first
508-
{
509-
ClientMessage c(Commands::IDirect3DDevice9Ex_Present, getId());
510-
c.send_data(sizeof(RECT), (void*) pSourceRect);
511-
c.send_data(sizeof(RECT), (void*) pDestRect);
512-
c.send_data((uint32_t) hDestWindowOverride);
513-
c.send_data(sizeof(RGNDATA), (void*) pDirtyRegion);
514-
}
515-
516-
const auto syncResult = syncOnPresent();
517-
if (syncResult == ERROR_SEM_TIMEOUT) {
518-
return ERROR_SEM_TIMEOUT;
519-
}
520-
}
521-
522-
FrameMark;
523-
524-
return hresult;
498+
return m_pSwapchain->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
525499
}
526500

527501
template<bool EnableSync>
@@ -3241,7 +3215,15 @@ HRESULT Direct3DDevice9Ex_LSS<EnableSync>::PresentEx(CONST RECT* pSourceRect, CO
32413215
ZoneScoped;
32423216
LogMissingFunctionCall();
32433217
assert(m_ex);
3244-
return D3D_OK;
3218+
3219+
// If the bridge was disabled in the meantime for some reason we want to bail
3220+
// out here so we don't spend time waiting on the Present semaphore or trying
3221+
// to send keyboard state to the server.
3222+
if (!gbBridgeRunning) {
3223+
return D3D_OK;
3224+
}
3225+
3226+
return m_pSwapchain->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
32453227
}
32463228

32473229
template<bool EnableSync>
@@ -3442,8 +3424,42 @@ template<bool EnableSync>
34423424
HRESULT Direct3DDevice9Ex_LSS<EnableSync>::ResetEx(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode) {
34433425
ZoneScoped;
34443426
assert(m_ex);
3445-
LogMissingFunctionCall();
3446-
return D3D_OK;
3427+
LogFunctionCall();
3428+
HRESULT res = S_OK;
3429+
{
3430+
BRIDGE_DEVICE_LOCKGUARD();
3431+
// Clear all device state and release implicit/internal objects
3432+
releaseInternalObjects(false);
3433+
3434+
const auto presParam = Direct3DSwapChain9_LSS::sanitizePresentationParameters(*pPresentationParameters, getCreateParams());
3435+
m_presParams = presParam;
3436+
WndProc::unset();
3437+
WndProc::set(getWinProcHwnd());
3438+
// Tell Server to do the Reset
3439+
size_t currentUID = 0;
3440+
{
3441+
ClientMessage c(Commands::IDirect3DDevice9Ex_ResetEx, getId());
3442+
currentUID = c.get_uid();
3443+
c.send_data(sizeof(D3DPRESENT_PARAMETERS), &presParam);
3444+
c.send_data(sizeof(D3DDISPLAYMODEEX), pFullscreenDisplayMode);
3445+
}
3446+
3447+
// Perform an WAIT_FOR_OPTIONAL_SERVER_RESPONSE but don't return since we still have work to do.
3448+
if (GlobalOptions::getSendAllServerResponses()) {
3449+
const uint32_t timeoutMs = GlobalOptions::getAckTimeout();
3450+
if (Result::Success != DeviceBridge::waitForCommand(Commands::Bridge_Response, timeoutMs, nullptr, true, currentUID)) {
3451+
Logger::err("Direct3DDevice9Ex_LSS::ResetEx() failed with : no response from server.");
3452+
}
3453+
res = (HRESULT) DeviceBridge::get_data();
3454+
DeviceBridge::pop_front();
3455+
}
3456+
3457+
// Reset swapchain and link server backbuffer/depth buffer after the server reset its swapchain, or we will link to the old backbuffer/depth resources
3458+
initImplicitObjects(presParam);
3459+
// Keeping a track of previous present parameters, to detect and handle mode changes
3460+
m_previousPresentParams = *pPresentationParameters;
3461+
}
3462+
return res;
34473463
}
34483464

34493465
template<bool EnableSync>
@@ -3861,13 +3877,15 @@ void Direct3DDevice9Ex_LSS<EnableSync>::destroyImplicitObjects() {
38613877
assert(rtRefCnt == 0 && "Implicit RenderTarget has not been released!");
38623878
m_pImplicitRenderTarget = nullptr;
38633879
--m_implicitRefCnt;
3880+
m_state.renderTargets[0].reset(nullptr);
38643881

38653882
// Release implicit DepthStencil
38663883
if (GET_PRES_PARAM().EnableAutoDepthStencil) {
38673884
const auto dsRefCnt = m_pImplicitDepthStencil->Release();
38683885
assert(dsRefCnt == 0 && "Implicit DepthStencil has not been released!");
38693886
m_pImplicitDepthStencil = nullptr;
38703887
--m_implicitRefCnt;
3888+
m_state.depthStencil.reset(nullptr);
38713889
}
38723890

38733891
const size_t nBackBuf = GET_PRES_PARAM().BackBufferCount;

src/client/d3d9_device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class Direct3DDevice9Ex_LSS: public BaseDirect3DDevice9Ex_LSS {
5858

5959
protected:
6060
// Releases the internal objects, if any.
61-
void releaseInternalObjects();
61+
void releaseInternalObjects(bool resetState = true);
6262
void onDestroy() override;
6363

6464
public:

src/server/main.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -651,18 +651,41 @@ void ProcessDeviceCommandQueue() {
651651
done = true;
652652
}
653653

654-
UINT cnt = pD3DDevice->GetNumberOfSwapChains();
655-
for (int iSwapChain = 0; iSwapChain < cnt; iSwapChain++) {
656-
IDirect3DSwapChain9* pSwapChain = nullptr;
657-
pD3DDevice->GetSwapChain(iSwapChain, &pSwapChain);
658-
pSwapChain->Release();
659-
}
654+
//Release implicit swapchain
655+
IDirect3DSwapChain9* pSwapChain = nullptr;
656+
pD3DDevice->GetSwapChain(0, &pSwapChain);
657+
pSwapChain->Release();
660658

661659
const auto hresult = pD3DDevice->Reset(&PresentationParameters);
662660
assert(SUCCEEDED(hresult));
663661
SEND_OPTIONAL_SERVER_RESPONSE(hresult, currentUID);
664662
break;
665663
}
664+
case IDirect3DDevice9Ex_ResetEx:
665+
{
666+
GET_RES(pD3DDevice, gpD3DDevices);
667+
uint32_t* rawPresentationParameters = nullptr;
668+
DeviceBridge::get_data((void**) &rawPresentationParameters);
669+
670+
D3DDISPLAYMODEEX* pFullscreenDisplayMode = nullptr;
671+
PULL_DATA(sizeof(D3DDISPLAYMODEEX), pFullscreenDisplayMode);
672+
673+
D3DPRESENT_PARAMETERS PresentationParameters = getPresParamFromRaw(rawPresentationParameters);
674+
if (!PresentationParameters.Windowed && !bDxvkModuleLoaded) {
675+
bridge_util::Logger::err("Fullscreen is not yet supported for non-DXVK uses of the bridge. This is not recoverable. Exiting.");
676+
done = true;
677+
}
678+
679+
//Release implicit swapchain
680+
IDirect3DSwapChain9* pSwapChain = nullptr;
681+
pD3DDevice->GetSwapChain(0, &pSwapChain);
682+
pSwapChain->Release();
683+
684+
const auto hresult = ((IDirect3DDevice9Ex*) pD3DDevice)->ResetEx(&PresentationParameters, pFullscreenDisplayMode);
685+
assert(SUCCEEDED(hresult));
686+
SEND_OPTIONAL_SERVER_RESPONSE(hresult, currentUID);
687+
break;
688+
}
666689
case IDirect3DDevice9Ex_Present:
667690
{
668691
FrameMark;

0 commit comments

Comments
 (0)