From e3d4c0f2b5b35881fe7dd9fcaed2b165dba7d4a1 Mon Sep 17 00:00:00 2001 From: spacy51 Date: Sat, 5 Apr 2008 00:13:31 +0000 Subject: [PATCH] ADDED option to disable multi-threaded pixel filtering REDUCED maximum number of cores to use to 8 --- src/win32/Direct3D.cpp | 126 +++++++++++++++++------------------ src/win32/MainWnd.cpp | 2 + src/win32/MainWnd.h | 2 + src/win32/MainWndOptions.cpp | 10 +++ src/win32/VBA.cpp | 14 +++- src/win32/VBA.h | 1 + src/win32/VBA.rc | 1 + src/win32/resource.h | 3 +- 8 files changed, 94 insertions(+), 65 deletions(-) diff --git a/src/win32/Direct3D.cpp b/src/win32/Direct3D.cpp index 945215b3..7f0e69c7 100644 --- a/src/win32/Direct3D.cpp +++ b/src/win32/Direct3D.cpp @@ -173,7 +173,7 @@ Direct3DDisplay::Direct3DDisplay() pfthread_data = NULL; hThreads = NULL; nThreads = theApp.maxCpuCores; - if( nThreads > 16 ) nThreads = 16; + if( nThreads > 8 ) nThreads = 8; } @@ -444,75 +444,75 @@ void Direct3DDisplay::render() return; } else { u32 pitch = theApp.sizeX * ( systemColorDepth >> 3 ) + 4; + if( theApp.filterFunction ) { - u8 *start = pix + pitch; - int src_height_per_thread = theApp.sizeY / nThreads; - int src_height_remaining = theApp.sizeY - ( ( theApp.sizeY / nThreads ) * nThreads ); - u32 src_bytes_per_thread = pitch * src_height_per_thread; + if( theApp.filterMT ) { + u8 *start = pix + pitch; + int src_height_per_thread = theApp.sizeY / nThreads; + int src_height_remaining = theApp.sizeY - ( ( theApp.sizeY / nThreads ) * nThreads ); + u32 src_bytes_per_thread = pitch * src_height_per_thread; - int dst_height_per_thread = src_height_per_thread * theApp.filterMagnification; - u32 dst_bytes_per_thread = lr.Pitch * dst_height_per_thread; + int dst_height_per_thread = src_height_per_thread * theApp.filterMagnification; + u32 dst_bytes_per_thread = lr.Pitch * dst_height_per_thread; - unsigned int i = nThreads - 1; + unsigned int i = nThreads - 1; - // Use Multi Threading - do { - // create last thread first because it could have more work than the others (for eg. if nThreads = 3) - // (last thread has to process the remaining lines if (height / nThreads) is not an integer) + // Use Multi Threading + do { + // create last thread first because it could have more work than the others (for eg. if nThreads = 3) + // (last thread has to process the remaining lines if (height / nThreads) is not an integer) - // configure thread - pfthread_data[i].filterFunction = theApp.filterFunction; - pfthread_data[i].sourcePointer = start + ( i * src_bytes_per_thread ); - pfthread_data[i].sourcePitch = pitch; - pfthread_data[i].deltaPointer = (u8*)theApp.delta; // TODO: check if thread-safe - pfthread_data[i].destPointer = ( (u8*)lr.pBits ) + ( i * dst_bytes_per_thread ); - pfthread_data[i].destPitch = lr.Pitch; - pfthread_data[i].width = theApp.sizeX; - - if( i == ( nThreads - 1 ) ) { - // last thread - pfthread_data[i].height = src_height_per_thread + src_height_remaining; - } else { - // other thread - pfthread_data[i].height = src_height_per_thread; + // configure thread + pfthread_data[i].filterFunction = theApp.filterFunction; + pfthread_data[i].sourcePointer = start + ( i * src_bytes_per_thread ); + pfthread_data[i].sourcePitch = pitch; + pfthread_data[i].deltaPointer = (u8*)theApp.delta; // TODO: check if thread-safe + pfthread_data[i].destPointer = ( (u8*)lr.pBits ) + ( i * dst_bytes_per_thread ); + pfthread_data[i].destPitch = lr.Pitch; + pfthread_data[i].width = theApp.sizeX; + + if( i == ( nThreads - 1 ) ) { + // last thread + pfthread_data[i].height = src_height_per_thread + src_height_remaining; + } else { + // other thread + pfthread_data[i].height = src_height_per_thread; + } + + // create thread + hThreads[i] = CreateThread( + NULL, + 0, + pfthread_func, + &pfthread_data[i], + 0, + NULL ); + assert( hThreads[i] != NULL ); + } while ( i-- ); + + // Wait until every thread has finished. + WaitForMultipleObjects( + nThreads, + hThreads, + TRUE, + INFINITE ); + + // Close all thread handles. + for( i = 0 ; i < nThreads ; i++ ) { + CloseHandle( hThreads[i] ); } - - // create thread - hThreads[i] = CreateThread( - NULL, - 0, - pfthread_func, - &pfthread_data[i], - 0, - NULL ); - assert( hThreads[i] != NULL ); - } while ( i-- ); - - // Wait until every thread has finished. - WaitForMultipleObjects( - nThreads, - hThreads, - TRUE, - INFINITE ); - - // Close all thread handles. - for( i = 0 ; i < nThreads ; i++ ) { - CloseHandle( hThreads[i] ); + } else { + // multi-threading disabled + theApp.filterFunction( + pix + pitch, + pitch, + (u8*)theApp.delta, + (u8*)lr.pBits, + lr.Pitch, + theApp.sizeX, + theApp.sizeY + ); } - - - /* without threads - // pixel filter enabled - theApp.filterFunction( - pix + pitch, - pitch, - (u8*)theApp.delta, - (u8*)lr.pBits, - lr.Pitch, - theApp.sizeX, - theApp.sizeY - ); - */ } else { // pixel filter disabled switch( systemColorDepth ) diff --git a/src/win32/MainWnd.cpp b/src/win32/MainWnd.cpp index 20fdc80f..6cadc8fc 100644 --- a/src/win32/MainWnd.cpp +++ b/src/win32/MainWnd.cpp @@ -437,6 +437,8 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd) ON_WM_NCRBUTTONDOWN() ON_COMMAND(ID_OUTPUTAPI_XAUDIO2, &MainWnd::OnOutputapiXaudio2) ON_UPDATE_COMMAND_UI(ID_OUTPUTAPI_XAUDIO2, &MainWnd::OnUpdateOutputapiXaudio2) + ON_COMMAND(ID_PIXELFILTER_MULTI, &MainWnd::OnPixelfilterMultiThreading) + ON_UPDATE_COMMAND_UI(ID_PIXELFILTER_MULTI, &MainWnd::OnUpdatePixelfilterMultiThreading) END_MESSAGE_MAP() diff --git a/src/win32/MainWnd.h b/src/win32/MainWnd.h index 4c56e68c..1524a133 100644 --- a/src/win32/MainWnd.h +++ b/src/win32/MainWnd.h @@ -425,6 +425,8 @@ public: afx_msg void OnNcRButtonDown(UINT nHitTest, CPoint point); afx_msg void OnOutputapiXaudio2(); afx_msg void OnUpdateOutputapiXaudio2(CCmdUI *pCmdUI); + afx_msg void OnPixelfilterMultiThreading(); + afx_msg void OnUpdatePixelfilterMultiThreading(CCmdUI *pCmdUI); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/src/win32/MainWndOptions.cpp b/src/win32/MainWndOptions.cpp index ef8842f0..6a0e2e9a 100644 --- a/src/win32/MainWndOptions.cpp +++ b/src/win32/MainWndOptions.cpp @@ -1854,3 +1854,13 @@ void MainWnd::OnEmulatorBiosfiles() theApp.biosFileNameGB = dlg.m_pathGB; } } + +void MainWnd::OnPixelfilterMultiThreading() +{ + theApp.filterMT = !theApp.filterMT; +} + +void MainWnd::OnUpdatePixelfilterMultiThreading(CCmdUI *pCmdUI) +{ + pCmdUI->SetCheck( theApp.filterMT ? 1 : 0 ); +} diff --git a/src/win32/VBA.cpp b/src/win32/VBA.cpp index 7583c8ec..e99e71a8 100644 --- a/src/win32/VBA.cpp +++ b/src/win32/VBA.cpp @@ -215,6 +215,8 @@ VBA::VBA() if( S_OK != CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ) ) { systemMessage( IDS_COM_FAILURE, NULL ); } + + // ! keep in mind that many of the following values will be really initialized in loadSettings() mode320Available = false; mode640Available = false; mode800Available = false; @@ -229,6 +231,7 @@ VBA::VBA() filterType = FILTER_NONE; filterWidth = 0; filterHeight = 0; + filterMT = false; fsAdapter = 0; fsWidth = 0; fsHeight = 0; @@ -1543,6 +1546,8 @@ void VBA::loadSettings() if(filterType < 0 || filterType > 17) filterType = 0; + filterMT = ( 1 == regQueryDwordValue("filterEnableMultiThreading", 0) ); + disableMMX = regQueryDwordValue("disableMMX", false) ? true: false; disableStatusMessage = regQueryDwordValue("disableStatus", 0) ? true : false; @@ -1681,7 +1686,7 @@ void VBA::loadSettings() updateThrottle( (unsigned short)regQueryDwordValue( "throttle", 0 ) ); - linktimeout = regQueryDwordValue("LinkTimeout", 1000); + linktimeout = regQueryDwordValue("LinkTimeout", 1000); linklog = regQueryDwordValue("Linklog", false) ? true : false; if(linklog) @@ -1704,6 +1709,11 @@ void VBA::loadSettings() oalBufferCount = regQueryDwordValue( "oalBufferCount", 5 ); #endif + + if( ( maxCpuCores == 1 ) && filterMT ) { + // multi-threading use useless for just one core + filterMT = false; + } } void VBA::updateFrameSkip() @@ -2511,6 +2521,8 @@ void VBA::saveSettings() regSetDwordValue("filter", filterType); + regSetDwordValue("filterEnableMultiThreading", filterMT ? 1 : 0); + regSetDwordValue("LCDFilter", filterLCD); regSetDwordValue("disableMMX", disableMMX); diff --git a/src/win32/VBA.h b/src/win32/VBA.h index d581e3e0..fa5ac482 100644 --- a/src/win32/VBA.h +++ b/src/win32/VBA.h @@ -91,6 +91,7 @@ class VBA : public CWinApp int filterHeight; int filterMagnification; int filterLCD; + bool filterMT; // enable multi-threading for pixel filters int fsWidth; int fsHeight; int fsColorDepth; diff --git a/src/win32/VBA.rc b/src/win32/VBA.rc index 5c69ac08..2e222a34 100644 --- a/src/win32/VBA.rc +++ b/src/win32/VBA.rc @@ -1661,6 +1661,7 @@ BEGIN MENUITEM "&Smart", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_SMART END MENUITEM SEPARATOR + MENUITEM "Multi-Threading (D3D)", ID_PIXELFILTER_MULTI MENUITEM "Disable &MMX", ID_OPTIONS_FILTER_DISABLEMMX END POPUP "&Audio" diff --git a/src/win32/resource.h b/src/win32/resource.h index a9b4a259..5e940d4d 100644 --- a/src/win32/resource.h +++ b/src/win32/resource.h @@ -850,13 +850,14 @@ #define ID_FILE_OPENGBC 40357 #define ID_FILE_OPEN_GBC 40358 #define ID_OUTPUTAPI_XAUDIO2 40359 +#define ID_PIXELFILTER_MULTI 40360 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 163 -#define _APS_NEXT_COMMAND_VALUE 40360 +#define _APS_NEXT_COMMAND_VALUE 40361 #define _APS_NEXT_CONTROL_VALUE 1284 #define _APS_NEXT_SYMED_VALUE 103 #endif