Войти
ПрограммированиеПодсказкиГрафикаГрафика

Определение реального объема видеопамяти

Автор:

Наверняка многие из вас хотели бы получить общий локальный объем видеопамяти на видеокарте, а не свободный объем локальной (video) плюс нелокальной (AGP) памяти, который возвращается функцией IDirect3DDevice9::GetAvailableTextureMem()?

Следующий кусок кода поможет вам это сделать:

#include <ddraw.h>

IDirectDraw7* pDirectDraw;
HRESULT hr = CoCreateInstance(CLSID_DirectDraw7, NULL, CLSCTX_ALL, 
                              IID_IDirectDraw7, (void**) &pDirectDraw);
if(!FAILED(hr))
{
  hr = IDirectDraw7_Initialize(pDirectDraw, NULL);
  if (!FAILED(hr))
  {
    DDSCAPS2 QueryCaps = { 0 };
    DWORD dwTotal, dwFree;

    QueryCaps.dwCaps = DDSCAPS_LOCALVIDMEM;
    hr = pDirectDraw->GetAvailableVidMem(&QueryCaps, &dwTotal, &dwFree);
    if (!FAILED(hr))
      m_uLocalVidMemorySize = dwTotal;

    QueryCaps.dwCaps = DDSCAPS_TEXTURE;
    hr = pDirectDraw->GetAvailableVidMem(&QueryCaps, &dwTotal, &dwFree);
    if (!FAILED(hr))
      m_uTotalVidMemorySize = dwTotal;

    m_uAGPVidMemorySize = m_uTotalVidMemorySize - m_uLocalVidMemorySize;
    // либо запросить DDSCAPS_NONLOCALVIDMEM
  }

  pDirectDraw->Release();
}

Преимущество данного метода состоит в том, что вы получаете сразу и общий и свободный объем указанного вида памяти.
Я думаю, что не стоит напоминать, что необходимо выполнить CoInitialize(NULL) перед созданием объекта? :)

#видеопамять

25 марта 2006

Комментарии [26]

Страницы: 1 2 Следующая »
#1
12:19, 16 июля 2009

А для OpenGL есть вариант?

Прошло более 4 лет
#2
14:53, 7 апр 2014

полный объем
http://steps3d.narod.ru/snippets.html#gpumemory

для истории

Как узнать объем памяти на GPU

Для Nvidia -

#define GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 0x9048
#define GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX 0x9049

int  getNvTotalMemory ()
{
    GLint totalMemKb = 0;

    glGetIntegerv ( GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX, &totalMemKb );

    return totalMemKb;
}

Для ATI/AMD

int  getAtiTotalMemory ()
{
    UINT   n          = wglGetGPUIDsAMD ( 0, 0 );
    UINT * ids        = new UINT[n];
    size_t totalMemMb = 0;

    wglGetGPUIDsAMD  ( n, ids );
    wglGetGPUInfoAMD ( ids[0], WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(size_t), &totalMemMb );

    delete ids;

    return totalMemMb * 1024;
}

ещё вариант в историю, ati untested
http://www.gamedev.ru/code/forum/?id=121232&page=2#m16
barnes

#define    GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX          0x9047
#define    GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX    0x9048
#define    GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX  0x9049
#define    GPU_MEMORY_INFO_EVICTION_COUNT_NVX            0x904A
#define    GPU_MEMORY_INFO_EVICTED_MEMORY_NVX            0x904B

#define     VBO_FREE_MEMORY_ATI                     0x87FB
#define     TEXTURE_FREE_MEMORY_ATI                 0x87FC
#define     RENDERBUFFER_FREE_MEMORY_ATI            0x87FD

void R_VideoInfo_f(void){

#ifdef _WIN32
  int mem[4];
  
  if (strstr(gl_config.extensions_string, "GL_NVX_gpu_memory_info")) {
            
    Com_Printf("\nNvidia specific memory info:\n");
    Com_Printf("\n");
    qglGetIntegerv ( GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX , mem);
    Com_Printf("dedicated video memory %i MB\n", mem[0] >>10);

    qglGetIntegerv ( GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX , mem);
    Com_Printf("total available memory %i MB\n", mem[0] >>10);

    qglGetIntegerv ( GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX , mem);
    Com_Printf("currently unused GPU memory %i MB\n", mem[0] >>10);

    qglGetIntegerv ( GPU_MEMORY_INFO_EVICTION_COUNT_NVX , mem);
    Com_Printf("count of total evictions seen by system %i MB\n", mem[0] >>10);

    qglGetIntegerv ( GPU_MEMORY_INFO_EVICTED_MEMORY_NVX , mem);
    Com_Printf("total video memory evicted %i MB\n", mem[0] >>10);

  } else 
    if (strstr(gl_config.extensions_string, "GL_ATI_meminfo")) {
    
        Com_Printf("\nATI/AMD specific memory info:\n");
    Com_Printf("\n");
        qglGetIntegerv (VBO_FREE_MEMORY_ATI, mem);
        Com_Printf("VBO: total memory free in the pool %i MB\n", mem[0] >> 10);
        Com_Printf("VBO: largest available free block in the pool %i MB\n", mem[1] >> 10);
        Com_Printf("VBO: total auxiliary memory free %i MB\n", mem[2] >> 10);
        Com_Printf("VBO: largest auxiliary free block %i MB\n", mem[3] >> 10);

        qglGetIntegerv (TEXTURE_FREE_MEMORY_ATI, mem);
        Com_Printf("Texture: total memory free in the pool %i MB\n", mem[0] >> 10);
        Com_Printf("Texture: largest available free block in the pool %i MB\n", mem[1] >> 10);
        Com_Printf("Texture: total auxiliary memory free %i MB\n", mem[2] >> 10);
        Com_Printf("Texture: largest auxiliary free block %i MB\n", mem[3] >> 10);

        qglGetIntegerv (RENDERBUFFER_FREE_MEMORY_ATI, mem);
        Com_Printf("RenderBuffer: total memory free in the pool %i MB\n", mem[0] >> 10);
        Com_Printf("RenderBuffer: largest available free block in the pool %i MB\n", mem[1] >> 10);
        Com_Printf("RenderBuffer: total auxiliary memory free %i MB\n", mem[2] >> 10);
        Com_Printf("RenderBuffer: largest auxiliary free block %i MB\n", mem[3] >> 10);
    }
  else
#endif
    Com_Printf("MemInfo not availabled for your video card or driver!\n");
}
#3
19:21, 7 апр 2014

ARtnaMed
> UINT * ids = new UINT[n];
>delete ids;
Сразу видно, что код Борескова.

#4
18:15, 8 апр 2014

gammaker
Он использует паттерн KISS ). Но база знаний у него хорошая, зачастую поиски приводят меня именно к нему в финале.

#5
22:18, 8 апр 2014

ARtnaMed
> Он использует паттерн KISS ).
Я не про неиспользование контейнеров, если ты это имел в виду. Я про то, что он неправильно удаляет массив: выделяет через new[], а удаляет через delete, а не delete[]. Я это ещё в его книге "Расширения OpenGL" заметил.

#6
12:42, 9 апр 2014

gammaker
ну так чо - если в приложении тока

main()
и
getAtiTotalMemory ()

то в релизе может и не упадет
тем более POD типы в массиве

#7
12:52, 9 апр 2014

gammaker
Это хитрая политика - выделиться из толпы быдлокодеров и намекнуть
крестостандартизаторам что кресты убогое говно, перегруженное лишними ненужными операторами.

#8
12:15, 10 апр 2014

gammaker
> Я не про неиспользование контейнеров, если ты это имел в виду
паттерн KISS - "Keep it simple, stupid" (c)
он показывает функции в приближенном окружении, а не правила с++, он мог и не писать delete вовсе, т.к. это snippet.
Главное показать принцип, usecase
n = wglGetGPUIDsAMD( 0, 0 ); подразумевает количество гпушек
если есть количество, следом есть какой-то массив этого количества
new UINT[n]; тут он показал что массив этот UINT типа
далее показывает зачем ваще этот массив нужен
wglGetGPUIDsAMD  ( n, ids );
ура! далее
wglGetGPUInfoAMD ( ids[0], WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(size_t), &totalMemMb );
много каких-то трудно для понимания констант которые нужны просто потому что нужны
но суть в том, что мы берем количество гпу памяти из  ids[0] в totalMemMb.
всё остальное не важно, снипет на столько прост, что понимание функционала осознаётся в течении нескольких секунд.

Это вам не boost.asio ))

#9
12:32, 10 апр 2014

ARtnaMed
> всё остальное не важно, снипет на столько прост, что понимание функционала
> осознаётся в течении нескольких секунд.
Но если взять не пытаться понимать, а просто взять и скопировать в свой проект, то память будет течь и портиться, о чем gammaker и говорит.

#10
13:06, 10 апр 2014

kipar
> Но если взять не пытаться понимать, а просто взять и скопировать в свой проект
1. Не нужно копипастить код, который не понимаешь как работает (к полностью законченным функциям не относится).
2. Копипаст - ЗЛО!!!

#11
13:22, 10 апр 2014

asvp
А что в #2, как не полностью законченные функции? Ну т.е. насчет нвидиевской я согласен, glGetIntegerv можно и самому написать, нет смысла копипастить. Но в атишной я бы точно не стал разбираться а просто скопировал (если бы на С++ писал).

#12
13:47, 10 апр 2014

kipar
> А что в #2, как не полностью законченные функции? Ну т.е. насчет нвидиевской я
> согласен, glGetIntegerv можно и самому написать, нет смысла копипастить. Но в
> атишной я бы точно не стал разбираться а просто скопировал (если бы на С++
> писал).
Законченные, но...
Скопипастил ты функцию getAtiTotalMemory(), не разобравшись как работает.
Ок. Разрешается.

В процессе тестирования, понимаешь что функция getAtiTotalMemory()- глючит, не работает, дает утечку памяти ну и т.п. не важно.
Есть 2 варианта:
1. Написать самому функцию (но ты не знаешь как её писать)
2. Разобраться как она работает и найти причину ошибки.

И вот ты уже в преклонном возрасте, матеря автора функции, разобравшись как она работает - переписываешь функцию.

Поэтому, если уж и копипаститься код, то нужно минимально пробежаться по коду хотя бы 2-3 раза. Нужно хотя бы в общих чертах понять, как она работает.

#13
13:51, 10 апр 2014

asvp
> Поэтому, если уж и копипаститься код, то нужно минимально пробежаться по коду
> хотя бы 2-3 раза. Нужно хотя бы в общих чертах понять, как она работает.
Согласен.

А еще лучше не писать на С++ - волей-неволей придется пробежаться по коду и понять как он работает, чтобы переписать на свой язык.

#14
14:05, 10 апр 2014

kipar

> А еще лучше не писать на крестах - волей-неволей придется пробежаться по коду и понять как он работает, чтобы переписать на свой язык.
О-у-о-у-о-у!!! Тише, тише!!! А то ща быстро запинают за кресты. "Голова -- прочь! Правая нога -- хрусть, пополам! Левая -- хрусть, пополам!"

А ваще это относятся к любому языку.

Страницы: 1 2 Следующая »
ПрограммированиеПодсказкиГрафикаГрафика

Тема в архиве.

Монтажмедстрой чистые помещения ПромКонВент.рф.