Example #1
0
/*
 * D3DAppTotalVideoMemory
 * Returns the amount of total video memory supported (not free)
 */
DWORD
D3DAppTotalVideoMemory(void)
{
#if 0
    DDCAPS DriverCaps, HELCaps;
    memset (&DriverCaps, 0, sizeof(DDCAPS));
    DriverCaps.dwSize = sizeof(DDCAPS);
    memset (&HELCaps, 0, sizeof(DDCAPS));
    HELCaps.dwSize = sizeof(DDCAPS);
    LastError = d3dappi.lpDD->lpVtbl->GetCaps(d3dappi.lpDD, &DriverCaps,
                                              &HELCaps);
    if (LastError != DD_OK) {
        D3DAppISetErrorString("Getting DD capabilities failed while checking total video memory.\n%s",
                              D3DAppErrorToString(LastError));
        return 0L;
    }
    if (DriverCaps.dwVidMemTotal)
        return DriverCaps.dwVidMemTotal;
    else
        return HELCaps.dwVidMemTotal;
#endif

    LPDIRECTDRAW4 lpdd4;
    DDSCAPS2      ddsCaps2;
    DWORD         dwTotal, dwFree;
    DDSURFACEDESC2 dds2;
    
    // get dd4 ptr...
    IDirectDraw4_QueryInterface( d3dappi.lpDD, &IID_IDirectDraw4, (LPVOID *)&lpdd4 );  

    memset( &ddsCaps2, 0, sizeof( DDSCAPS2 ) );
    ddsCaps2.dwCaps = DDSCAPS_LOCALVIDMEM;

    if ( IDirectDraw4_GetAvailableVidMem( lpdd4, &ddsCaps2, &dwTotal, &dwFree ) != DD_OK )
        dwTotal = 0;

    if ( dwTotal )
    {
        memset( &dds2, 0, sizeof( DDSURFACEDESC2 ) );
        dds2.dwSize = sizeof( DDSURFACEDESC2 );
        if ( IDirectDraw4_GetDisplayMode( lpdd4, &dds2  ) == DD_OK )
        {
            dwTotal += ( dds2.dwHeight * dds2.lPitch  );
        }
    }

    IDirectDraw4_Release( lpdd4 );

    return dwTotal;
}
Bool
winAllocateFBShadowDDNL (ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;  
  HRESULT		ddrval = DD_OK;
  DDSURFACEDESC2	ddsdShadow;
  char			*lpSurface = NULL;
  DDPIXELFORMAT		ddpfPrimary;

#if CYGDEBUG
  winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n",
	  pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth);
#endif

  /* Set the padded screen width */
  pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
					      pScreenInfo->dwBPP);

  /* Allocate memory for our shadow surface */
  lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
  if (lpSurface == NULL)
    {
      ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n");
      return FALSE;
    }

  /*
   * Initialize the framebuffer memory so we don't get a 
   * strange display at startup
   */
  ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
  
  /* Create a clipper */
  ddrval = (*g_fpDirectDrawCreateClipper) (0,
					   &pScreenPriv->pddcPrimary,
					   NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n",
	      (unsigned int) ddrval);
      return FALSE;
    }

#if CYGDEBUG
  winDebug ("winAllocateFBShadowDDNL - Created a clipper\n");
#endif

  /* Attach the clipper to our display window */
  ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
				       0,
				       pScreenPriv->hwndScreen);
  if (FAILED (ddrval))
    {
      ErrorF ("winAllocateFBShadowDDNL - Clipper not attached "
	      "to window: %08x\n",
	      (unsigned int) ddrval);
      return FALSE;
    }

#if CYGDEBUG
  winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n");
#endif

  /* Create a DirectDraw object, store the address at lpdd */
  ddrval = (*g_fpDirectDrawCreate) (NULL,
				    (LPDIRECTDRAW*) &pScreenPriv->pdd,
				    NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winAllocateFBShadowDDNL - Could not start "
	      "DirectDraw: %08x\n",
	      (unsigned int) ddrval);
      return FALSE;
    }

#if CYGDEBUG
  winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n");
#endif

  /* Get a DirectDraw4 interface pointer */
  ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd,
				       &IID_IDirectDraw4,
				       (LPVOID*) &pScreenPriv->pdd4);
  if (FAILED (ddrval))
    {
      ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n",
	      (unsigned int) ddrval);
      return FALSE;
    }

  /* Are we full screen? */
  if (pScreenInfo->fFullScreen)
    {
      DDSURFACEDESC2	ddsdCurrent;
      DWORD		dwRefreshRateCurrent = 0;
      HDC		hdc = NULL;

      /* Set the cooperative level to full screen */
      ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4,
						 pScreenPriv->hwndScreen,
						 DDSCL_EXCLUSIVE
						 | DDSCL_FULLSCREEN);
      if (FAILED (ddrval))
	{
	  ErrorF ("winAllocateFBShadowDDNL - Could not set "
		  "cooperative level: %08x\n",
		  (unsigned int) ddrval);
	  return FALSE;
	}

      /*
       * We only need to get the current refresh rate for comparison
       * if a refresh rate has been passed on the command line.
       */
      if (pScreenInfo->dwRefreshRate != 0)
	{
	  ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent));
	  ddsdCurrent.dwSize = sizeof (ddsdCurrent);

	  /* Get information about current display settings */
	  ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4,
						&ddsdCurrent);
	  if (FAILED (ddrval))
	    {
	      ErrorF ("winAllocateFBShadowDDNL - Could not get current "
		      "refresh rate: %08x.  Continuing.\n",
		      (unsigned int) ddrval);
	      dwRefreshRateCurrent = 0;
	    }
	  else
	    {
	      /* Grab the current refresh rate */
	      dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
	    }
	}

      /* Clean up the refresh rate */
      if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate)
	{
	  /*
	   * Refresh rate is non-specified or equal to current.
	   */
	  pScreenInfo->dwRefreshRate = 0;
	}

      /* Grab a device context for the screen */
      hdc = GetDC (NULL);
      if (hdc == NULL)
	{
	  ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n");
	  return FALSE;
	}

      /* Only change the video mode when different than current mode */
      if (!pScreenInfo->fMultipleMonitors
	  && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
	      || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
	      || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
	      || pScreenInfo->dwRefreshRate != 0))
	{
	  winDebug ("winAllocateFBShadowDDNL - Changing video mode\n");

	  /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
	  ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4,
						pScreenInfo->dwWidth,
						pScreenInfo->dwHeight,
						pScreenInfo->dwBPP,
						pScreenInfo->dwRefreshRate,
						0);	       
	  if (FAILED (ddrval))
	    {
	      ErrorF ("winAllocateFBShadowDDNL - Could not set "
		      "full screen display mode: %08x\n",
		      (unsigned int) ddrval);
	      ErrorF ("winAllocateFBShadowDDNL - Using default driver refresh rate\n");
	      ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4,
						    pScreenInfo->dwWidth,
						    pScreenInfo->dwHeight,
						    pScreenInfo->dwBPP,
						    0,
						    0);
	      if (FAILED(ddrval))
		{
			ErrorF ("winAllocateFBShadowDDNL - Could not set default refresh rate "
				"full screen display mode: %08x\n",
				(unsigned int) ddrval);
			return FALSE;
		}
	    }
	}
      else
	{
	  winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n");
	}

      /* Release our DC */
      ReleaseDC (NULL, hdc);
      hdc = NULL;
    }
  else
    {
      /* Set the cooperative level for windowed mode */
      ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4,
						 pScreenPriv->hwndScreen,
						 DDSCL_NORMAL);
      if (FAILED (ddrval))
	{
	  ErrorF ("winAllocateFBShadowDDNL - Could not set "
		  "cooperative level: %08x\n",
		  (unsigned int) ddrval);
	  return FALSE;
	}
    }

  /* Create the primary surface */
  if (!winCreatePrimarySurfaceShadowDDNL (pScreen))
    {
      ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL "
	      "failed\n");
      return FALSE;
    }

  /* Get primary surface's pixel format */
  ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary));
  ddpfPrimary.dwSize = sizeof (ddpfPrimary);
  ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4,
					       &ddpfPrimary);
  if (FAILED (ddrval))
    {
      ErrorF ("winAllocateFBShadowDDNL - Could not get primary "
	      "pixformat: %08x\n",
	      (unsigned int) ddrval);
      return FALSE;
    }

#if CYGDEBUG
  winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x "
	  "dwRGBBitCount: %d\n",
	  ddpfPrimary.u2.dwRBitMask,
	  ddpfPrimary.u3.dwGBitMask,
	  ddpfPrimary.u4.dwBBitMask,
	  ddpfPrimary.u1.dwRGBBitCount);
#endif

  /* Describe the shadow surface to be created */
  /*
   * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
   * as drawing, locking, and unlocking take forever
   * with video memory surfaces.  In addition,
   * video memory is a somewhat scarce resource,
   * so you shouldn't be allocating video memory when
   * you have the option of using system memory instead.
   */
  ZeroMemory (&ddsdShadow, sizeof (ddsdShadow));
  ddsdShadow.dwSize = sizeof (ddsdShadow);
  ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH
    | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT;
  ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
  ddsdShadow.dwHeight = pScreenInfo->dwHeight;
  ddsdShadow.dwWidth = pScreenInfo->dwWidth;
  ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth;
  ddsdShadow.lpSurface = lpSurface;
  ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary;
  
  winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n",
	  (int) pScreenInfo->dwPaddedWidth);

  /* Create the shadow surface */
  ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4,
				       &ddsdShadow,
				       &pScreenPriv->pddsShadow4,
				       NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winAllocateFBShadowDDNL - Could not create shadow "
	      "surface: %08x\n", (unsigned int) ddrval);
      return FALSE;
    }
  
#if CYGDEBUG || YES
  winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n",
	  (int) ddsdShadow.u1.lPitch);
#endif

  /* Grab the pitch from the surface desc */
  pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8)
    / pScreenInfo->dwBPP;

#if CYGDEBUG || YES
  winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n",
	  (int) pScreenInfo->dwStride);
#endif

  /* Save the pointer to our surface memory */
  pScreenInfo->pfb = lpSurface;
  
  /* Grab the masks from the surface description */
  pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask;
  pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask;
  pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask;

#if CYGDEBUG
  winDebug ("winAllocateFBShadowDDNL - Returning\n");
#endif

  return TRUE;
}