locked
DirectX find video ram RRS feed

  • Question

  • How do I find the available video ram using DirectX like dxdiag does?

     

    The following code doesn't work:

     

    LPDIRECT3D8 pD3D;

    LPDIRECT3DDEVICE8 pDevice;

    if((pD3D = Direct3DCreate8(D3D_SDK_VERSION))==NULL)

    return;

    D3DDISPLAYMODE d3ddm;

    pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));

    d3dpp.BackBufferFormat = d3ddm.Format;

    d3dpp.Windowed = true;

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,

    m_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice)))

    return;

    UINT nTotalMemory = pDevice->GetAvailableTextureMem();

     

    Both DirectDraw and Direct3D need to be enabled and GetAvailableTextureMem() DOESN'T return the correct value, anyway.

    Tuesday, May 29, 2007 3:35 PM

Answers

  • Both D3D8 and D3D9’s GetAvailableTextureMemory return a combination of local and non-local (AGP) memory.   That’s probably why it doesn’t work.   Some system memory is included in the totals.

    Historically we’ve discouraged applications from trying to obtain this info since it’s too easy to make bad assumptions about how many resources you can actually create.    

    However, this information can still be obtained through DirectDraw’s GetAvailableVidMem() function.   I believe this is what DXDIAG uses.

     

    http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/ddraw7/directdraw7/ddref_3jg7.asp 

    // For this example, the lpDD variable is a valid

    // pointer to an IDirectDraw interface.

    LPDIRECTDRAW7 lpDD;

    DDSCAPS2      ddsCaps2;

    DWORD         dwTotal;

    DWORD         dwFree;

    HRESULT       hr;

     

    hr = lpDD->QueryInterface(IID_IDirectDraw7, &lpDD);

    if (FAILED(hr))

        return hr;

     

    // Initialize the structure.

    ZeroMemory(&ddsCaps2, sizeof(ddsCaps2));

     

    ddsCaps2.dwCaps = DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM;

    hr = lpDD->GetAvailableVidMem(&ddsCaps2, &dwTotal, &dwFree);

    if (FAILED(hr))

        return hr;

     

    Olan Hanley

    DirectX

    Monday, June 4, 2007 7:03 PM

All replies

  • Both D3D8 and D3D9’s GetAvailableTextureMemory return a combination of local and non-local (AGP) memory.   That’s probably why it doesn’t work.   Some system memory is included in the totals.

    Historically we’ve discouraged applications from trying to obtain this info since it’s too easy to make bad assumptions about how many resources you can actually create.    

    However, this information can still be obtained through DirectDraw’s GetAvailableVidMem() function.   I believe this is what DXDIAG uses.

     

    http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/ddraw7/directdraw7/ddref_3jg7.asp 

    // For this example, the lpDD variable is a valid

    // pointer to an IDirectDraw interface.

    LPDIRECTDRAW7 lpDD;

    DDSCAPS2      ddsCaps2;

    DWORD         dwTotal;

    DWORD         dwFree;

    HRESULT       hr;

     

    hr = lpDD->QueryInterface(IID_IDirectDraw7, &lpDD);

    if (FAILED(hr))

        return hr;

     

    // Initialize the structure.

    ZeroMemory(&ddsCaps2, sizeof(ddsCaps2));

     

    ddsCaps2.dwCaps = DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM;

    hr = lpDD->GetAvailableVidMem(&ddsCaps2, &dwTotal, &dwFree);

    if (FAILED(hr))

        return hr;

     

    Olan Hanley

    DirectX

    Monday, June 4, 2007 7:03 PM
  • GetAvailableVidMem() function returns between 495k and 502k for a 512k card.

    This is good.  Thanks.

     

    I would like to get the full 512.0k like DXDIAG does.

    Monday, June 4, 2007 10:20 PM
  • Edit: Oops, just realized I posted C# code, and the solution does not involve DirectX at all. Sorry for that, but I'm going to leave the post anyway.


    This method is easier and seems to be more accurate. There are tons of system variables you can query using these classes -- I actually wrote a little reflection app so I could look at all the available WMI classes and the values that were set, which is how I stumbled across this one. Don't forget you'll have to add the System.Management library as a reference in your project.

    Code Snippet
    using System.Management;


    Code Snippet
    object propertyValue = null;
    UInt32 videoCardRAMBytes = 0;
    UInt32 videoCardRAMMegaBytes = 0;

    ManagementClass managementClass = new ManagementClass("Win32_VideoController");

    foreach (ManagementObject mo in managementClass.GetInstances())
    {
    propertyValue = mo.Properties["AdapterRAM"].Value;
    break; // only interested in the first ManagementObject
    }

    // This value is reported in bytes
    videoCardRAMBytes = ((UInt32)propertyValue);

    // To get the number of megabytes, just divide by 1024 twice
    videoCardRAMMegaBytes = videoCardRAMBytes / 1024 / 1024;

    Thursday, June 21, 2007 4:09 PM
  • Is there a solution in C++?
    Tuesday, June 26, 2007 4:12 PM