From 6bb0234dc899c69c819eeda4ac69965f6db69d21 Mon Sep 17 00:00:00 2001 From: jackchentwkh Date: Sun, 23 May 2021 15:58:39 +0800 Subject: [PATCH 1/3] Fix DSoundBufferResizeSetSize with DSBuffer creation failure when remained hos buffer bytes is less then DSBSIZE_MIN, also correct a wrongly used argument with call to DSound3DBufferCreate. add more sanity checks. this fixs PGR2, now release build can enter the race. but debug build has different issue with vector/iterator. --- .../DSOUND/DirectSound/DirectSoundInline.hpp | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index 66c6a2714..a965800f8 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -371,12 +371,19 @@ static inline void DSoundGenericUnlock( static inline HRESULT DSoundBufferCreate(LPDSBUFFERDESC pDSBufferDesc, LPDIRECTSOUNDBUFFER8 &pDSBuffer) { LPDIRECTSOUNDBUFFER pTempBuffer; + //Todo:shall we check the pDSBufferDesc->dwBufferBytes with legal ranges between DSBSIZE_MIN and DSBSIZE_MAX again? HRESULT hRetDS = g_pDSound8->CreateSoundBuffer(pDSBufferDesc, &pTempBuffer, nullptr); - if (hRetDS == DS_OK) { - hRetDS = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&(pDSBuffer)); - pTempBuffer->Release(); - } + if (hRetDS == DS_OK) { + hRetDS = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&(pDSBuffer)); + pTempBuffer->Release(); + if (pDSBuffer == nullptr) { + EmuLog(LOG_LEVEL::WARNING, "CreateSoundBuffer:QueryInterface Failed!"); + } + } + else { + EmuLog(LOG_LEVEL::WARNING, "CreateSoundBuffer Failed!"); + } return hRetDS; } @@ -456,13 +463,17 @@ static inline void DSoundBufferReCreate( xbox::CDirectSoundVoice* Xb_Voice) { - DSoundBufferCreate(&DSBufferDesc, pDSBufferNew); - - if (pDS3DBuffer != nullptr) { + HRESULT hretDS = DSoundBufferCreate(&DSBufferDesc, pDSBufferNew); + //create new DS3DBuffer from the new DSBuffer if the new DSBuffer is created successfully. + if (pDSBufferNew != nullptr) { DSound3DBufferCreate(pDSBufferNew, pDS3DBufferNew); - } + DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Voice);//Sanity checks inside. + } + else { + EmuLog(LOG_LEVEL::WARNING, "DSoundBufferReCreate Failed!"); + } - DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Voice); + } static inline void DSoundBufferRelease( @@ -503,8 +514,12 @@ static inline void DSoundBufferResizeSetSize( return; } - pThis->EmuBufferDesc.dwBufferBytes = Host_dwByteLength; - + if (Host_dwByteLength< DSBSIZE_MIN) { //the min. buffer bytes must be equal or greater then DSBSIZE_MIN + pThis->EmuBufferDesc.dwBufferBytes = DSBSIZE_MIN; + } + else { + pThis->EmuBufferDesc.dwBufferBytes = Host_dwByteLength; + } // NOTE: Test case JSRF, if we allow to re-alloc without checking allocated buffer size. // Then it is somehow binded to IDirectSound_SetPosition control for any allocated audio afterward. @@ -534,7 +549,7 @@ static inline void DSoundBufferResizeUpdate( DWORD Xb_dwByteLength) { xbox::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; - DSoundBufferResizeSetSize(pHybridThis, hRet, Xb_dwByteLength); + DSoundBufferResizeSetSize(pHybridThis, hRet, Xb_dwByteLength); hRet = pThis->EmuDirectSoundBuffer8->Lock(0, 0, &pThis->Host_lock.pLockPtr1, &pThis->Host_lock.dwLockBytes1, nullptr, nullptr, DSBLOCK_ENTIREBUFFER); From ea55dfa45d320886862bfc0cab000b58503c5a1e Mon Sep 17 00:00:00 2001 From: jackchentwkh Date: Sun, 23 May 2021 18:15:35 +0800 Subject: [PATCH 2/3] remove extra space in end of line, replace tabs with spaces. --- .../DSOUND/DirectSound/DirectSoundInline.hpp | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp index a965800f8..ec5a8d9ed 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSoundInline.hpp @@ -371,19 +371,19 @@ static inline void DSoundGenericUnlock( static inline HRESULT DSoundBufferCreate(LPDSBUFFERDESC pDSBufferDesc, LPDIRECTSOUNDBUFFER8 &pDSBuffer) { LPDIRECTSOUNDBUFFER pTempBuffer; - //Todo:shall we check the pDSBufferDesc->dwBufferBytes with legal ranges between DSBSIZE_MIN and DSBSIZE_MAX again? + //Todo:shall we check the pDSBufferDesc->dwBufferBytes with legal ranges between DSBSIZE_MIN and DSBSIZE_MAX again? HRESULT hRetDS = g_pDSound8->CreateSoundBuffer(pDSBufferDesc, &pTempBuffer, nullptr); - if (hRetDS == DS_OK) { - hRetDS = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&(pDSBuffer)); - pTempBuffer->Release(); - if (pDSBuffer == nullptr) { - EmuLog(LOG_LEVEL::WARNING, "CreateSoundBuffer:QueryInterface Failed!"); - } - } - else { - EmuLog(LOG_LEVEL::WARNING, "CreateSoundBuffer Failed!"); - } + if (hRetDS == DS_OK) { + hRetDS = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&(pDSBuffer)); + pTempBuffer->Release(); + if (pDSBuffer == nullptr) { + EmuLog(LOG_LEVEL::WARNING, "CreateSoundBuffer:QueryInterface Failed!"); + } + } + else { + EmuLog(LOG_LEVEL::WARNING, "CreateSoundBuffer Failed!"); + } return hRetDS; } @@ -433,9 +433,9 @@ static inline void DSoundBufferTransferSettings( LONG lVolume, lPan; DS3DBUFFER ds3dBuffer; - if (pDSBufferOld == nullptr) { - return; - } + if (pDSBufferOld == nullptr) { + return; + } // if sync current frequency used (then use pitch only). uint32_t freq = converter_pitch2freq(Xb_Voice->GetPitch()); @@ -464,14 +464,14 @@ static inline void DSoundBufferReCreate( HRESULT hretDS = DSoundBufferCreate(&DSBufferDesc, pDSBufferNew); - //create new DS3DBuffer from the new DSBuffer if the new DSBuffer is created successfully. + //create new DS3DBuffer from the new DSBuffer if the new DSBuffer is created successfully. if (pDSBufferNew != nullptr) { DSound3DBufferCreate(pDSBufferNew, pDS3DBufferNew); - DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Voice);//Sanity checks inside. - } - else { - EmuLog(LOG_LEVEL::WARNING, "DSoundBufferReCreate Failed!"); - } + DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Voice);//Sanity checks inside. + } + else { + EmuLog(LOG_LEVEL::WARNING, "DSoundBufferReCreate Failed!"); + } } @@ -514,12 +514,12 @@ static inline void DSoundBufferResizeSetSize( return; } - if (Host_dwByteLength< DSBSIZE_MIN) { //the min. buffer bytes must be equal or greater then DSBSIZE_MIN - pThis->EmuBufferDesc.dwBufferBytes = DSBSIZE_MIN; - } - else { - pThis->EmuBufferDesc.dwBufferBytes = Host_dwByteLength; - } + if (Host_dwByteLength< DSBSIZE_MIN) { //the min. buffer bytes must be equal or greater then DSBSIZE_MIN + pThis->EmuBufferDesc.dwBufferBytes = DSBSIZE_MIN; + } + else { + pThis->EmuBufferDesc.dwBufferBytes = Host_dwByteLength; + } // NOTE: Test case JSRF, if we allow to re-alloc without checking allocated buffer size. // Then it is somehow binded to IDirectSound_SetPosition control for any allocated audio afterward. @@ -549,7 +549,7 @@ static inline void DSoundBufferResizeUpdate( DWORD Xb_dwByteLength) { xbox::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer; - DSoundBufferResizeSetSize(pHybridThis, hRet, Xb_dwByteLength); + DSoundBufferResizeSetSize(pHybridThis, hRet, Xb_dwByteLength); hRet = pThis->EmuDirectSoundBuffer8->Lock(0, 0, &pThis->Host_lock.pLockPtr1, &pThis->Host_lock.dwLockBytes1, nullptr, nullptr, DSBLOCK_ENTIREBUFFER); From fa1f4d4c50586ce80d090c6cea949f87914c7a23 Mon Sep 17 00:00:00 2001 From: jackchentwkh Date: Sun, 23 May 2021 21:57:52 +0800 Subject: [PATCH 3/3] Make sure packet iterator is validate after DSStream_Packet_Clear() calls erase(). this fixs debug builds with PGR2 --- src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp b/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp index f8cc13daf..d31da5ffc 100644 --- a/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp +++ b/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp @@ -308,6 +308,8 @@ bool DSStream_Packet_Process( } return 0; } + //the iterator might be invalidated, so we update it again. + packetCurrent = pThis->Host_BufferPacketArray.begin(); #if 0 // Extend debug verification EmuLog(LOG_LEVEL::DEBUG, "nextBuffer: %08X; packetCurrent->bufPlayed: %08X; bufPlayed: %08X;\n", packetCurrent._Ptr,