@@ -71,7 +71,7 @@ void Direct3DDevice9Ex_LSS<EnableSync>::onDestroy() {
7171}
7272
7373template <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>
481483HRESULT 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
527501template <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
32473229template <bool EnableSync>
@@ -3442,8 +3424,42 @@ template<bool EnableSync>
34423424HRESULT 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
34493465template <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 ;
0 commit comments