ADDED option to disable multi-threaded pixel filtering
REDUCED maximum number of cores to use to 8 git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@473 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
parent
c6f5298e6a
commit
c3641f314d
|
@ -173,7 +173,7 @@ Direct3DDisplay::Direct3DDisplay()
|
||||||
pfthread_data = NULL;
|
pfthread_data = NULL;
|
||||||
hThreads = NULL;
|
hThreads = NULL;
|
||||||
nThreads = theApp.maxCpuCores;
|
nThreads = theApp.maxCpuCores;
|
||||||
if( nThreads > 16 ) nThreads = 16;
|
if( nThreads > 8 ) nThreads = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -444,75 +444,75 @@ void Direct3DDisplay::render()
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
u32 pitch = theApp.sizeX * ( systemColorDepth >> 3 ) + 4;
|
u32 pitch = theApp.sizeX * ( systemColorDepth >> 3 ) + 4;
|
||||||
|
|
||||||
if( theApp.filterFunction ) {
|
if( theApp.filterFunction ) {
|
||||||
u8 *start = pix + pitch;
|
if( theApp.filterMT ) {
|
||||||
int src_height_per_thread = theApp.sizeY / nThreads;
|
u8 *start = pix + pitch;
|
||||||
int src_height_remaining = theApp.sizeY - ( ( theApp.sizeY / nThreads ) * nThreads );
|
int src_height_per_thread = theApp.sizeY / nThreads;
|
||||||
u32 src_bytes_per_thread = pitch * src_height_per_thread;
|
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;
|
int dst_height_per_thread = src_height_per_thread * theApp.filterMagnification;
|
||||||
u32 dst_bytes_per_thread = lr.Pitch * dst_height_per_thread;
|
u32 dst_bytes_per_thread = lr.Pitch * dst_height_per_thread;
|
||||||
|
|
||||||
unsigned int i = nThreads - 1;
|
unsigned int i = nThreads - 1;
|
||||||
|
|
||||||
// Use Multi Threading
|
// Use Multi Threading
|
||||||
do {
|
do {
|
||||||
// create last thread first because it could have more work than the others (for eg. if nThreads = 3)
|
// 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)
|
// (last thread has to process the remaining lines if (height / nThreads) is not an integer)
|
||||||
|
|
||||||
// configure thread
|
// configure thread
|
||||||
pfthread_data[i].filterFunction = theApp.filterFunction;
|
pfthread_data[i].filterFunction = theApp.filterFunction;
|
||||||
pfthread_data[i].sourcePointer = start + ( i * src_bytes_per_thread );
|
pfthread_data[i].sourcePointer = start + ( i * src_bytes_per_thread );
|
||||||
pfthread_data[i].sourcePitch = pitch;
|
pfthread_data[i].sourcePitch = pitch;
|
||||||
pfthread_data[i].deltaPointer = (u8*)theApp.delta; // TODO: check if thread-safe
|
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].destPointer = ( (u8*)lr.pBits ) + ( i * dst_bytes_per_thread );
|
||||||
pfthread_data[i].destPitch = lr.Pitch;
|
pfthread_data[i].destPitch = lr.Pitch;
|
||||||
pfthread_data[i].width = theApp.sizeX;
|
pfthread_data[i].width = theApp.sizeX;
|
||||||
|
|
||||||
if( i == ( nThreads - 1 ) ) {
|
if( i == ( nThreads - 1 ) ) {
|
||||||
// last thread
|
// last thread
|
||||||
pfthread_data[i].height = src_height_per_thread + src_height_remaining;
|
pfthread_data[i].height = src_height_per_thread + src_height_remaining;
|
||||||
} else {
|
} else {
|
||||||
// other thread
|
// other thread
|
||||||
pfthread_data[i].height = src_height_per_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] );
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// create thread
|
// multi-threading disabled
|
||||||
hThreads[i] = CreateThread(
|
theApp.filterFunction(
|
||||||
NULL,
|
pix + pitch,
|
||||||
0,
|
pitch,
|
||||||
pfthread_func,
|
(u8*)theApp.delta,
|
||||||
&pfthread_data[i],
|
(u8*)lr.pBits,
|
||||||
0,
|
lr.Pitch,
|
||||||
NULL );
|
theApp.sizeX,
|
||||||
assert( hThreads[i] != NULL );
|
theApp.sizeY
|
||||||
} 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] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* without threads
|
|
||||||
// pixel filter enabled
|
|
||||||
theApp.filterFunction(
|
|
||||||
pix + pitch,
|
|
||||||
pitch,
|
|
||||||
(u8*)theApp.delta,
|
|
||||||
(u8*)lr.pBits,
|
|
||||||
lr.Pitch,
|
|
||||||
theApp.sizeX,
|
|
||||||
theApp.sizeY
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
// pixel filter disabled
|
// pixel filter disabled
|
||||||
switch( systemColorDepth )
|
switch( systemColorDepth )
|
||||||
|
|
|
@ -437,6 +437,8 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
|
||||||
ON_WM_NCRBUTTONDOWN()
|
ON_WM_NCRBUTTONDOWN()
|
||||||
ON_COMMAND(ID_OUTPUTAPI_XAUDIO2, &MainWnd::OnOutputapiXaudio2)
|
ON_COMMAND(ID_OUTPUTAPI_XAUDIO2, &MainWnd::OnOutputapiXaudio2)
|
||||||
ON_UPDATE_COMMAND_UI(ID_OUTPUTAPI_XAUDIO2, &MainWnd::OnUpdateOutputapiXaudio2)
|
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()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,8 @@ public:
|
||||||
afx_msg void OnNcRButtonDown(UINT nHitTest, CPoint point);
|
afx_msg void OnNcRButtonDown(UINT nHitTest, CPoint point);
|
||||||
afx_msg void OnOutputapiXaudio2();
|
afx_msg void OnOutputapiXaudio2();
|
||||||
afx_msg void OnUpdateOutputapiXaudio2(CCmdUI *pCmdUI);
|
afx_msg void OnUpdateOutputapiXaudio2(CCmdUI *pCmdUI);
|
||||||
|
afx_msg void OnPixelfilterMultiThreading();
|
||||||
|
afx_msg void OnUpdatePixelfilterMultiThreading(CCmdUI *pCmdUI);
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1854,3 +1854,13 @@ void MainWnd::OnEmulatorBiosfiles()
|
||||||
theApp.biosFileNameGB = dlg.m_pathGB;
|
theApp.biosFileNameGB = dlg.m_pathGB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWnd::OnPixelfilterMultiThreading()
|
||||||
|
{
|
||||||
|
theApp.filterMT = !theApp.filterMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWnd::OnUpdatePixelfilterMultiThreading(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
pCmdUI->SetCheck( theApp.filterMT ? 1 : 0 );
|
||||||
|
}
|
||||||
|
|
|
@ -215,6 +215,8 @@ VBA::VBA()
|
||||||
if( S_OK != CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ) ) {
|
if( S_OK != CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ) ) {
|
||||||
systemMessage( IDS_COM_FAILURE, NULL );
|
systemMessage( IDS_COM_FAILURE, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ! keep in mind that many of the following values will be really initialized in loadSettings()
|
||||||
mode320Available = false;
|
mode320Available = false;
|
||||||
mode640Available = false;
|
mode640Available = false;
|
||||||
mode800Available = false;
|
mode800Available = false;
|
||||||
|
@ -229,6 +231,7 @@ VBA::VBA()
|
||||||
filterType = FILTER_NONE;
|
filterType = FILTER_NONE;
|
||||||
filterWidth = 0;
|
filterWidth = 0;
|
||||||
filterHeight = 0;
|
filterHeight = 0;
|
||||||
|
filterMT = false;
|
||||||
fsAdapter = 0;
|
fsAdapter = 0;
|
||||||
fsWidth = 0;
|
fsWidth = 0;
|
||||||
fsHeight = 0;
|
fsHeight = 0;
|
||||||
|
@ -1543,6 +1546,8 @@ void VBA::loadSettings()
|
||||||
if(filterType < 0 || filterType > 17)
|
if(filterType < 0 || filterType > 17)
|
||||||
filterType = 0;
|
filterType = 0;
|
||||||
|
|
||||||
|
filterMT = ( 1 == regQueryDwordValue("filterEnableMultiThreading", 0) );
|
||||||
|
|
||||||
disableMMX = regQueryDwordValue("disableMMX", false) ? true: false;
|
disableMMX = regQueryDwordValue("disableMMX", false) ? true: false;
|
||||||
|
|
||||||
disableStatusMessage = regQueryDwordValue("disableStatus", 0) ? true : false;
|
disableStatusMessage = regQueryDwordValue("disableStatus", 0) ? true : false;
|
||||||
|
@ -1681,7 +1686,7 @@ void VBA::loadSettings()
|
||||||
|
|
||||||
updateThrottle( (unsigned short)regQueryDwordValue( "throttle", 0 ) );
|
updateThrottle( (unsigned short)regQueryDwordValue( "throttle", 0 ) );
|
||||||
|
|
||||||
linktimeout = regQueryDwordValue("LinkTimeout", 1000);
|
linktimeout = regQueryDwordValue("LinkTimeout", 1000);
|
||||||
|
|
||||||
linklog = regQueryDwordValue("Linklog", false) ? true : false;
|
linklog = regQueryDwordValue("Linklog", false) ? true : false;
|
||||||
if(linklog)
|
if(linklog)
|
||||||
|
@ -1704,6 +1709,11 @@ void VBA::loadSettings()
|
||||||
|
|
||||||
oalBufferCount = regQueryDwordValue( "oalBufferCount", 5 );
|
oalBufferCount = regQueryDwordValue( "oalBufferCount", 5 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if( ( maxCpuCores == 1 ) && filterMT ) {
|
||||||
|
// multi-threading use useless for just one core
|
||||||
|
filterMT = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VBA::updateFrameSkip()
|
void VBA::updateFrameSkip()
|
||||||
|
@ -2511,6 +2521,8 @@ void VBA::saveSettings()
|
||||||
|
|
||||||
regSetDwordValue("filter", filterType);
|
regSetDwordValue("filter", filterType);
|
||||||
|
|
||||||
|
regSetDwordValue("filterEnableMultiThreading", filterMT ? 1 : 0);
|
||||||
|
|
||||||
regSetDwordValue("LCDFilter", filterLCD);
|
regSetDwordValue("LCDFilter", filterLCD);
|
||||||
|
|
||||||
regSetDwordValue("disableMMX", disableMMX);
|
regSetDwordValue("disableMMX", disableMMX);
|
||||||
|
|
|
@ -91,6 +91,7 @@ class VBA : public CWinApp
|
||||||
int filterHeight;
|
int filterHeight;
|
||||||
int filterMagnification;
|
int filterMagnification;
|
||||||
int filterLCD;
|
int filterLCD;
|
||||||
|
bool filterMT; // enable multi-threading for pixel filters
|
||||||
int fsWidth;
|
int fsWidth;
|
||||||
int fsHeight;
|
int fsHeight;
|
||||||
int fsColorDepth;
|
int fsColorDepth;
|
||||||
|
|
|
@ -1661,6 +1661,7 @@ BEGIN
|
||||||
MENUITEM "&Smart", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_SMART
|
MENUITEM "&Smart", ID_OPTIONS_FILTER_INTERFRAMEBLENDING_SMART
|
||||||
END
|
END
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
|
MENUITEM "Multi-Threading (D3D)", ID_PIXELFILTER_MULTI
|
||||||
MENUITEM "Disable &MMX", ID_OPTIONS_FILTER_DISABLEMMX
|
MENUITEM "Disable &MMX", ID_OPTIONS_FILTER_DISABLEMMX
|
||||||
END
|
END
|
||||||
POPUP "&Audio"
|
POPUP "&Audio"
|
||||||
|
|
|
@ -850,13 +850,14 @@
|
||||||
#define ID_FILE_OPENGBC 40357
|
#define ID_FILE_OPENGBC 40357
|
||||||
#define ID_FILE_OPEN_GBC 40358
|
#define ID_FILE_OPEN_GBC 40358
|
||||||
#define ID_OUTPUTAPI_XAUDIO2 40359
|
#define ID_OUTPUTAPI_XAUDIO2 40359
|
||||||
|
#define ID_PIXELFILTER_MULTI 40360
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 163
|
#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_CONTROL_VALUE 1284
|
||||||
#define _APS_NEXT_SYMED_VALUE 103
|
#define _APS_NEXT_SYMED_VALUE 103
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue