mirror of
https://github.com/izzy2lost/WeeU.git
synced 2026-07-06 00:19:59 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ada8bbb3b4 | ||
|
|
a19ed46b2a |
@@ -1005,8 +1005,67 @@ void LatteBufferCache_getStats(uint32& heapSize, uint32& allocationSize, uint32&
|
|||||||
}
|
}
|
||||||
|
|
||||||
FSpinlock g_spinlockDCFlushQueue;
|
FSpinlock g_spinlockDCFlushQueue;
|
||||||
std::unordered_set<uint32>* g_DCFlushQueue = new std::unordered_set<uint32>(); // queued pages
|
|
||||||
std::unordered_set<uint32>* g_DCFlushQueueAlternate = new std::unordered_set<uint32>();
|
class SparseBitset
|
||||||
|
{
|
||||||
|
static inline constexpr size_t TABLE_MASK = 0xFF;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool Empty() const
|
||||||
|
{
|
||||||
|
return m_numNonEmptyVectors == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set(uint32 index)
|
||||||
|
{
|
||||||
|
auto& v = m_bits[index & TABLE_MASK];
|
||||||
|
if (std::find(v.cbegin(), v.cend(), index) != v.end())
|
||||||
|
return;
|
||||||
|
if (v.empty())
|
||||||
|
{
|
||||||
|
m_nonEmptyVectors[m_numNonEmptyVectors] = &v;
|
||||||
|
m_numNonEmptyVectors++;
|
||||||
|
}
|
||||||
|
v.emplace_back(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TFunc>
|
||||||
|
void ForAllAndClear(TFunc callbackFunc)
|
||||||
|
{
|
||||||
|
auto vCurrent = m_nonEmptyVectors + 0;
|
||||||
|
auto vEnd = m_nonEmptyVectors + m_numNonEmptyVectors;
|
||||||
|
while (vCurrent < vEnd)
|
||||||
|
{
|
||||||
|
std::vector<uint32>* vec = *vCurrent;
|
||||||
|
vCurrent++;
|
||||||
|
for (const auto& it : *vec)
|
||||||
|
callbackFunc(it);
|
||||||
|
vec->clear();
|
||||||
|
}
|
||||||
|
m_numNonEmptyVectors = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
auto vCurrent = m_nonEmptyVectors + 0;
|
||||||
|
auto vEnd = m_nonEmptyVectors + m_numNonEmptyVectors;
|
||||||
|
while (vCurrent < vEnd)
|
||||||
|
{
|
||||||
|
std::vector<uint32>* vec = *vCurrent;
|
||||||
|
vCurrent++;
|
||||||
|
vec->clear();
|
||||||
|
}
|
||||||
|
m_numNonEmptyVectors = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint32> m_bits[TABLE_MASK + 1];
|
||||||
|
std::vector<uint32>* m_nonEmptyVectors[TABLE_MASK + 1];
|
||||||
|
size_t m_numNonEmptyVectors{ 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
SparseBitset* s_DCFlushQueue = new SparseBitset();
|
||||||
|
SparseBitset* s_DCFlushQueueAlternate = new SparseBitset();
|
||||||
|
|
||||||
void LatteBufferCache_notifyDCFlush(MPTR address, uint32 size)
|
void LatteBufferCache_notifyDCFlush(MPTR address, uint32 size)
|
||||||
{
|
{
|
||||||
@@ -1017,20 +1076,18 @@ void LatteBufferCache_notifyDCFlush(MPTR address, uint32 size)
|
|||||||
uint32 lastPage = (address + size - 1) / CACHE_PAGE_SIZE;
|
uint32 lastPage = (address + size - 1) / CACHE_PAGE_SIZE;
|
||||||
g_spinlockDCFlushQueue.acquire();
|
g_spinlockDCFlushQueue.acquire();
|
||||||
for (uint32 i = firstPage; i <= lastPage; i++)
|
for (uint32 i = firstPage; i <= lastPage; i++)
|
||||||
g_DCFlushQueue->emplace(i);
|
s_DCFlushQueue->Set(i);
|
||||||
g_spinlockDCFlushQueue.release();
|
g_spinlockDCFlushQueue.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LatteBufferCache_processDCFlushQueue()
|
void LatteBufferCache_processDCFlushQueue()
|
||||||
{
|
{
|
||||||
if (g_DCFlushQueue->empty()) // accessing this outside of the lock is technically undefined/unsafe behavior but on all known implementations this is fine and we can avoid the spinlock
|
if (s_DCFlushQueue->Empty()) // quick check to avoid locking if there is no work to do
|
||||||
return;
|
return;
|
||||||
g_spinlockDCFlushQueue.acquire();
|
g_spinlockDCFlushQueue.acquire();
|
||||||
std::swap(g_DCFlushQueue, g_DCFlushQueueAlternate);
|
std::swap(s_DCFlushQueue, s_DCFlushQueueAlternate);
|
||||||
g_spinlockDCFlushQueue.release();
|
g_spinlockDCFlushQueue.release();
|
||||||
for (auto& itr : *g_DCFlushQueueAlternate)
|
s_DCFlushQueueAlternate->ForAllAndClear([](uint32 index) {LatteBufferCache_invalidatePage(index * CACHE_PAGE_SIZE); });
|
||||||
LatteBufferCache_invalidatePage(itr * CACHE_PAGE_SIZE);
|
|
||||||
g_DCFlushQueueAlternate->clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LatteBufferCache_notifyDrawDone()
|
void LatteBufferCache_notifyDrawDone()
|
||||||
|
|||||||
@@ -167,25 +167,11 @@ void CubebAPI::SetVolume(sint32 volume)
|
|||||||
|
|
||||||
bool CubebAPI::InitializeStatic()
|
bool CubebAPI::InitializeStatic()
|
||||||
{
|
{
|
||||||
#if BOOST_OS_WINDOWS
|
|
||||||
s_com_initialized = (SUCCEEDED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cubeb_init(&s_context, "Cemu Cubeb", nullptr))
|
if (cubeb_init(&s_context, "Cemu Cubeb", nullptr))
|
||||||
{
|
{
|
||||||
cemuLog_force("can't create cubeb audio api");
|
cemuLog_force("can't create cubeb audio api");
|
||||||
|
|
||||||
#if BOOST_OS_WINDOWS
|
|
||||||
if (s_com_initialized)
|
|
||||||
{
|
|
||||||
CoUninitialize();
|
|
||||||
s_com_initialized = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,10 +179,6 @@ void CubebAPI::Destroy()
|
|||||||
{
|
{
|
||||||
if (s_context)
|
if (s_context)
|
||||||
cubeb_destroy(s_context);
|
cubeb_destroy(s_context);
|
||||||
#if BOOST_OS_WINDOWS
|
|
||||||
if (s_com_initialized)
|
|
||||||
CoUninitialize();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IAudioAPI::DeviceDescriptionPtr> CubebAPI::GetDevices()
|
std::vector<IAudioAPI::DeviceDescriptionPtr> CubebAPI::GetDevices()
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ public:
|
|||||||
static void Destroy();
|
static void Destroy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static bool s_com_initialized = false;
|
|
||||||
inline static cubeb* s_context = nullptr;
|
inline static cubeb* s_context = nullptr;
|
||||||
|
|
||||||
cubeb_stream* m_stream = nullptr;
|
cubeb_stream* m_stream = nullptr;
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
static_assert(IAudioAPI::kBlockCount < XAUDIO2_MAX_QUEUED_BUFFERS, "too many xaudio2 buffers");
|
static_assert(IAudioAPI::kBlockCount < XAUDIO2_MAX_QUEUED_BUFFERS, "too many xaudio2 buffers");
|
||||||
|
|
||||||
HMODULE XAudio27API::s_xaudio_dll = nullptr;
|
HMODULE XAudio27API::s_xaudio_dll = nullptr;
|
||||||
bool XAudio27API::s_com_initialized = false;
|
|
||||||
std::unique_ptr<IXAudio2, XAudio27API::XAudioDeleter> XAudio27API::s_xaudio;
|
std::unique_ptr<IXAudio2, XAudio27API::XAudioDeleter> XAudio27API::s_xaudio;
|
||||||
|
|
||||||
XAudio27API::XAudio27API(uint32 device_id, uint32 samplerate, uint32 channels, uint32 samples_per_block, uint32 bits_per_sample)
|
XAudio27API::XAudio27API(uint32 device_id, uint32 samplerate, uint32 channels, uint32 samples_per_block, uint32 bits_per_sample)
|
||||||
@@ -115,8 +114,6 @@ bool XAudio27API::InitializeStatic()
|
|||||||
if (s_xaudio)
|
if (s_xaudio)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
s_com_initialized = (SUCCEEDED(CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE)));
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
s_xaudio_dll = LoadLibraryExW(L"XAudioD2_7.DLL", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
s_xaudio_dll = LoadLibraryExW(L"XAudioD2_7.DLL", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||||
if(!s_xaudio_dll)
|
if(!s_xaudio_dll)
|
||||||
@@ -142,9 +139,6 @@ bool XAudio27API::InitializeStatic()
|
|||||||
if (s_xaudio_dll)
|
if (s_xaudio_dll)
|
||||||
FreeLibrary(s_xaudio_dll);
|
FreeLibrary(s_xaudio_dll);
|
||||||
|
|
||||||
if (s_com_initialized)
|
|
||||||
CoUninitialize();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,9 +149,6 @@ void XAudio27API::Destroy()
|
|||||||
|
|
||||||
if (s_xaudio_dll)
|
if (s_xaudio_dll)
|
||||||
FreeLibrary(s_xaudio_dll);
|
FreeLibrary(s_xaudio_dll);
|
||||||
|
|
||||||
if (s_com_initialized)
|
|
||||||
CoUninitialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<XAudio27API::DeviceDescriptionPtr> XAudio27API::GetDevices()
|
std::vector<XAudio27API::DeviceDescriptionPtr> XAudio27API::GetDevices()
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static HMODULE s_xaudio_dll;
|
static HMODULE s_xaudio_dll;
|
||||||
static bool s_com_initialized;
|
|
||||||
static std::unique_ptr<IXAudio2, XAudioDeleter> s_xaudio;
|
static std::unique_ptr<IXAudio2, XAudioDeleter> s_xaudio;
|
||||||
|
|
||||||
std::unique_ptr<IXAudio2, XAudioDeleter> m_xaudio;
|
std::unique_ptr<IXAudio2, XAudioDeleter> m_xaudio;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ static const GUID DEVINTERFACE_AUDIO_RENDER_GUID = { 0xe6327cad, 0xdcec, 0x4949,
|
|||||||
static_assert(IAudioAPI::kBlockCount < XAUDIO2_MAX_QUEUED_BUFFERS, "too many xaudio2 buffers");
|
static_assert(IAudioAPI::kBlockCount < XAUDIO2_MAX_QUEUED_BUFFERS, "too many xaudio2 buffers");
|
||||||
|
|
||||||
HMODULE XAudio2API::s_xaudio_dll = nullptr;
|
HMODULE XAudio2API::s_xaudio_dll = nullptr;
|
||||||
bool XAudio2API::s_com_initialized = false;
|
|
||||||
std::vector<XAudio2API::DeviceDescriptionPtr> XAudio2API::s_devices;
|
std::vector<XAudio2API::DeviceDescriptionPtr> XAudio2API::s_devices;
|
||||||
|
|
||||||
XAudio2API::XAudio2API(std::wstring device_id, uint32 samplerate, uint32 channels, uint32 samples_per_block, uint32 bits_per_sample)
|
XAudio2API::XAudio2API(std::wstring device_id, uint32 samplerate, uint32 channels, uint32 samples_per_block, uint32 bits_per_sample)
|
||||||
@@ -143,8 +142,6 @@ bool XAudio2API::InitializeStatic()
|
|||||||
{
|
{
|
||||||
if (s_xaudio_dll)
|
if (s_xaudio_dll)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
s_com_initialized = (SUCCEEDED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)));
|
|
||||||
|
|
||||||
// win 10
|
// win 10
|
||||||
s_xaudio_dll = LoadLibraryEx(XAUDIO2_DLL, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
s_xaudio_dll = LoadLibraryEx(XAUDIO2_DLL, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||||
@@ -166,9 +163,6 @@ bool XAudio2API::InitializeStatic()
|
|||||||
if (s_xaudio_dll)
|
if (s_xaudio_dll)
|
||||||
FreeLibrary(s_xaudio_dll);
|
FreeLibrary(s_xaudio_dll);
|
||||||
|
|
||||||
if (s_com_initialized)
|
|
||||||
CoUninitialize();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,20 +171,12 @@ void XAudio2API::Destroy()
|
|||||||
{
|
{
|
||||||
if (s_xaudio_dll)
|
if (s_xaudio_dll)
|
||||||
FreeLibrary(s_xaudio_dll);
|
FreeLibrary(s_xaudio_dll);
|
||||||
|
|
||||||
if (s_com_initialized)
|
|
||||||
CoUninitialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<XAudio2API::DeviceDescriptionPtr>& XAudio2API::RefreshDevices()
|
const std::vector<XAudio2API::DeviceDescriptionPtr>& XAudio2API::RefreshDevices()
|
||||||
{
|
{
|
||||||
// this function must be called from the same thread as we called CoInitializeEx
|
|
||||||
s_devices.clear();
|
s_devices.clear();
|
||||||
|
|
||||||
HRESULT r = CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
|
|
||||||
if (r != RPC_E_CHANGED_MODE && FAILED(r))
|
|
||||||
return s_devices;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
struct IWbemLocator *wbem_locator = nullptr;
|
struct IWbemLocator *wbem_locator = nullptr;
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static HMODULE s_xaudio_dll;
|
static HMODULE s_xaudio_dll;
|
||||||
static bool s_com_initialized;
|
|
||||||
static std::vector<DeviceDescriptionPtr> s_devices;
|
static std::vector<DeviceDescriptionPtr> s_devices;
|
||||||
|
|
||||||
std::unique_ptr<IXAudio2, XAudioDeleter> m_xaudio;
|
std::unique_ptr<IXAudio2, XAudioDeleter> m_xaudio;
|
||||||
|
|||||||
+7
-3
@@ -323,10 +323,10 @@ void HandlePostUpdate()
|
|||||||
fs::remove(filename, ec);
|
fs::remove(filename, ec);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
while( fs::exists(filename) )
|
while (fs::exists(filename))
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::remove(filename, ec);
|
fs::remove(filename, ec);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -338,8 +338,10 @@ void ToolShaderCacheMerger();
|
|||||||
#if BOOST_OS_WINDOWS
|
#if BOOST_OS_WINDOWS
|
||||||
|
|
||||||
// entrypoint for release builds
|
// entrypoint for release builds
|
||||||
int wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nShowCmd)
|
int wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nShowCmd)
|
||||||
{
|
{
|
||||||
|
if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE)))
|
||||||
|
cemuLog_log(LogType::Force, "CoInitializeEx() failed");
|
||||||
SDL_SetMainReady();
|
SDL_SetMainReady();
|
||||||
if (!LaunchSettings::HandleCommandline(lpCmdLine))
|
if (!LaunchSettings::HandleCommandline(lpCmdLine))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -350,6 +352,8 @@ int wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ L
|
|||||||
// entrypoint for debug builds with console
|
// entrypoint for debug builds with console
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE)))
|
||||||
|
cemuLog_log(LogType::Force, "CoInitializeEx() failed");
|
||||||
SDL_SetMainReady();
|
SDL_SetMainReady();
|
||||||
if (!LaunchSettings::HandleCommandline(argc, argv))
|
if (!LaunchSettings::HandleCommandline(argc, argv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user