Hi,

I have been having performance problems with Direct3D when it comes to having rendering performed in a window created in a secondary monitor. It looks like I cannot get full hardware acceleration on that window.

From my research on the net, people seem to be saying that all that is needed is to create the Direct3Device9 interface on that secondary display. I think that is what I am doing but hopefully someone here will pinpoint my mistake.

I first create a window on the primary monitor to show some options. Once the user validates by pressing on the OK button I go through a routine to create a new window on the secondary monitor in which there will be some rendering using Direct3D.

To do so, I call ::EnumDisplayDevices to obtain a pointer to a DISPLAY_DEVICE struct for the secondary monitor that will then be used in a call to ::EnumDisplaySettings to obtain a pointer to a DEVMODE struct. I then change the secondary display's resolution using ::ChangeDisplaySettingsEx. Once that's done, I hide the curent options window (which is a parent window created with WS_EX_CONTROLPARENT) and then proceed to create a new window on the secondary monitor. Now I am constrained in that I cannot create a fullscreen Direct3D device so I have to stick to windowed mode. So what I have to do instead is create a fake fullscreen by making a borderless window that has the same size as the secondary display which I have just resized. To create it in the proper place, I used the DEVMODE struct I obtained earlier. Now all that's left is to create a Direct3Device9 object and I pass it handles to that newly created window. Everything is created and seems to work except that the performance just isn't there when compared to using the same code to create the device on the primary monitor.

Well that was maybe a little hard to follow with just text so here's some code + pseudocode. I removed error checking and some declarations to keep it short and concise.

Code:
m_hWindow = ::CreateWindowEx( WS_EX_CONTROLPARENT,
      "WindowClass",
      TITLE,
      WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
      | WS_MINIMIZEBOX | WS_VISIBLE,
      (DesktopSize.right - m_dwWindowWidth)/2,
      (DesktopSize.bottom - m_dwWindowHeight)/2,
      m_dwWindowWidth,
      m_dwWindowHeight,
      NULL,
      NULL,
      ::GetModuleHandle( NULL ),
      NULL );
   //
   // Do some UI processing and get option choices from the user
   //
   ...

      //
      // Get the information for the secondary display
      //
      DISPLAY_DEVICE sDisplayDevice = {sizeof(sDisplayDevice)};
   DEVMODE sDevMode;
   BOOL bReturn = ::EnumDisplayDevices(	NULL,                              // device name
      m_dwMonitorIndex,                  // Selected Monitor
      (PDISPLAY_DEVICE) &sDisplayDevice, // device information
      NULL);                             // reserved

   bReturn = ::EnumDisplaySettings(	sDisplayDevice.DeviceName,  // display device
      ENUM_CURRENT_SETTINGS,      // graphics mode
      (LPDEVMODE) &sDevMode       // graphics mode settings
      );

   sDevMode.dmFields = 0;
   sDevMode.dmFields   |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; 
   sDevMode.dmPelsWidth = m_dwWidth;
   sDevMode.dmPelsHeight = m_dwHeight;

   LONG lReturn = ::ChangeDisplaySettingsEx( sDisplayDevice.DeviceName,  // display device
      (LPDEVMODE) &sDevMode,
      NULL,
      (CDS_UPDATEREGISTRY),
      NULL );
   // Get back settings !
   bReturn = ::EnumDisplaySettings(	sDisplayDevice.DeviceName,  // display device
      ENUM_CURRENT_SETTINGS,      // graphics mode
      (LPDEVMODE) &sDevMode );    // graphics mode settings

   // Hide the options window
   ::SetWindowPos(   m_hWindow,
      NULL,
      m_dwWindowWidth/2,
      m_dwWindowHeight/2,
      m_dwWindowWidth,
      m_dwWindowHeight,
      SWP_HIDEWINDOW );

   // Create the window on which we will do 3D rendering
   m_hDXWindow = ::CreateWindowEx( WS_EX_CONTROLPARENT,
      "WindowClass",
      TITLE,
      WS_POPUP & ~WS_THICKFRAME & ~WS_BORDER | WS_VISIBLE | WS_EX_TOPMOST,
      sDevMode.dmPosition.x,
      sDevMode.dmPosition.y,
      m_dwWidth,
      m_dwHeight,
      NULL,
      NULL,
      ::GetModuleHandle( NULL ),
      NULL );

   // Fill the present parameters
   ::ZeroMemory( &m_PresentParameters, sizeof( m_PresentParameters ) );
   m_PresentParameters.Windowed = m_bWindowed;
   // Discard last displayed frame - Faster and supports multisampling
   m_PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;

   // Depth/Stencil Format
   m_PresentParameters.EnableAutoDepthStencil = true;
   m_PresentParameters.AutoDepthStencilFormat = m_DepthStencilFormat;
   m_PresentParameters.hDeviceWindow = m_hDXWindow;			// Window handle

   //Disable vsync
   m_PresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_ONE;//D3DPRESENT_INTERVAL_DEFAULT;//D3DPRESENT_INTERVAL_IMMEDIATE;
   m_PresentParameters.BackBufferCount = 2;              // Triple buffering
   m_PresentParameters.BackBufferWidth = m_dwWidth;		// Screen Width
   m_PresentParameters.BackBufferHeight = m_dwHeight;		// Screen Height
   m_PresentParameters.BackBufferFormat = m_ColorFormat;	// Color Depth
   m_PresentParameters.MultiSampleType = m_MultiSampling;	// Multi-Sampling

   // Create the Device
   m_pDirect3DObject->CreateDevice(	D3DADAPTER_DEFAULT,
      D3DDEVTYPE_HAL,
      m_hDXWindow,
      m_dwVertexProcessing,
      &m_PresentParameters,
      &m_pDirect3DDevice );
Thanks in advance