Original Post
Hi, I am working on an MFC app that has multiple windows in them kinda like a 3d modeling program. I first started with just one window to see if i could do it. I used the MFCFog example in the SDK as a guide. I got it, it worked fine and i was getting about 1500 fps. So i added another window, I did this by creating an aditional swapchain (Actually i created 2 swap chains one for each render target, I dont know if this is right or not because when i created the device i passed it the HWND to my first render target m_hwndRendTarg1 for example, then i created an additional swap chain and passed the m_hwndRendTarg1 again, and created an additional swap chain and passed it the next render target to it m_hwndRendTarg2 for example).
Now when i did this it worked the way it was supposed to each window was rendering the right stuff but my framerate dropped to 50 fps. 50 fps isn''t bad but if there was that much performance drop by just adding one extra render target thats a problem. The scene is not very complex at all its just drawing a grid of about 200 vertices.
I tracked down the slow down using the profiler to the SwapChains->Present() method. I am using DX9. Below is the code if anyone knows what the problem is or if there is a better way to do this please comment, Thank you.
I tried remarking out the second render window and still only got 50 fps. I moved the one call to m_pSwapChain->Present() to a seperate function and ran the profiler on it and found Function Time takes 9395.278.
Anyone have any ideas? Sorry this post was so long.
void CGraphView::OnInitialUpdate()
{
// this is my MFC View class OnInitialUpdate()
// Get the handle to the 1st render target.
m_hwndRenderWindow = GetDlgItem(IDC_RENDER_FRAME)->GetSafeHwnd();
// Get the handle to the 2nd render target.
m_hwndRenderWindow2 = GetDlgItem(IDC_RENDER_FRAME2)->GetSafeHwnd();
// Create the device using the Example Framework class
// CD3DApplication
CD3DApplication::m_hWnd = m_hwndRenderWindow;
// Create the device passing it the HINSTANCE handle
// of our main app.
CD3DApplication::Create( AfxGetInstanceHandle() );
// The seperate D3DPRESENT_PARAMETERS for each swap chain.
ZeroMemory(&m_d3dppSwapChain, sizeof(D3DPRESENT_PARAMETERS) );
ZeroMemory(&m_d3dppSwapChain2, sizeof(D3DPRESENT_PARAMETERS) );
// Get the current display mode for the desktop.
D3DDISPLAYMODE mode;
m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
// Setup the presentation paramaters for the first swapchain.
m_d3dppSwapChain.Windowed = TRUE;
m_d3dppSwapChain.SwapEffect = D3DSWAPEFFECT_COPY;
m_d3dppSwapChain.BackBufferFormat = mode.Format;
m_d3dppSwapChain.hDeviceWindow = m_hwndRenderWindow;
// Create the first swapchain
m_pd3dDevice->CreateAdditionalSwapChain(&m_d3dppSwapChain, &m_pSwapChain);
// Setup the presentation parameters for second swapchain.
m_d3dppSwapChain2.Windowed = TRUE;
m_d3dppSwapChain2.SwapEffect = D3DSWAPEFFECT_COPY;
m_d3dppSwapChain2.BackBufferFormat = mode.Format;
m_d3dppSwapChain.hDeviceWindow = m_hwndRenderWindow2;
// Create the 2nd swap chain
m_pd3dDevice->CreateAdditionalSwapChain(&m_d3dppSwapChain2, &m_pSwapChain2);
}
// The main render function called from the main apps
// OnIdle() function.
HRESULT CGraphView::Render()
{
// Create a temporary surface to hold the returned
// suface from GetBackBuffer()
LPDIRECT3DSURFACE9 pSurface = NULL;
if( SUCCEEDED( m_pd3dDevice->BeginScene() ))
{
// Render the 1st viewport
m_pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
m_pd3dDevice->SetRenderTarget(0, pSurface);
m_pd3dDevice->Clear( 0, NULL,D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, D3DCOLOR(0x000000), 1.0f, 0L);
// Reset the world matrix
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
// Draw the grid
m_pd3dDevice->SetFVF( D3DFVF_GRIDVERTEX );
m_pd3dDevice->SetStreamSource( 0, m_pGridVB, 0, sizeof(GRIDVERTEX) );
m_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, m_dwNumGridVerts/2 );
pSurface->Release();
// Render the 2nd viewport, For the purposes of this
// example i am rendering the same scene as the other
m_pSwapChain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
m_pd3dDevice->SetRenderTarget(0, pSurface);
m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR(0x000000), 1.0f, 0L);
// Reset the world matrix
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
// Draw the grid
m_pd3dDevice->SetFVF( D3DFVF_GRIDVERTEX );
m_pd3dDevice->SetStreamSource( 0, m_pGridVB, 0, sizeof(GRIDVERTEX) );
m_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, m_dwNumGridVerts/2 );
pSurface->Release();
m_pd3dDevice->EndScene();
}
m_pSwapChain->Present(NULL,NULL,NULL,NULL,NULL);
m_pSwapChain2->Present(NULL,NULL,NULL,NULL,NULL);
return S_OK;
}