(Debug)-[C++ & DXGI] | 4GB+ GPU Kullanımı Görüntüleme | Fix

  • Konuyu açan Konuyu açan Kaiser
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 4
  • Gösterim Gösterim 176

Kaiser

Admin
Admin
Süper Üye
Geliştirici
Yardımsever Üye
Mesaj
4.585
Çözümler
452
Beğeni
5.567
Puan
5.349
Ticaret Puanı
0
Merhabalar, dün debug mod ile testler yaparken tesadüf eseri bir şey gözüme çarptı.
Sağ üstteki değerlerde ATM(VRAM) değeri -1 olarak sabit duruyordu. Sorunun benden kaynaklı olmadığını teyit etmek için @Toranaga ya da sordum ve -51, -63 gibi saçma sayılar olduğunu belirtti. Sonra tekrar kodlara baktığımda ise bunun 32bit sınırına takıldığını gördüm. Benim kullandığım GPU 16GB ancak debug ekranına gelen bilgi 32bit üzerinden(Max. 4GB) hesaplanmaya çalışıldığı için patlıyordu ve bozuluyordu.
Pythonda ve C++ tarafında kullanılan GetAvailableTextureMemory fonksiyonu Directx'e bağımlıdır, ve maalesef directx8 ve directx9 çok eski oldukları için maksimum 4milyar değer döndürüyor.(UINT,4gb.)
Bu da 4GB'dan yüksek ekran kartlarının bu hesaplamaya doğru bir şekilde dahil edilemeyeceği anlamına geliyor.
Buradaki amaç, debug ekranında mevcut gpu'nun toplam kapasitesini göstermek değildir, uygulama içinde kullanılabilir alandan geriye kalan kısmı göstermektir.

Çözüme gelecek olursak; bu durumu mümkün olan en iyi derecede düzeltmek için dxgi kütüphanesini kullanacağız. DXGI, normal dx kütüphanelerine göre biraz daha modernlik içerir ve şu anki şartlarda en doğruyu bilgiyi görmemizi sağlar.


GrpBase.h açın ve bulun:
C++:
Genişlet Daralt Kopyala
static DWORD GetAvailableTextureMemory();
Değiştirin:
C++:
Genişlet Daralt Kopyala
static uint64_t GetAvailableTextureMemory();

GrpBase.cpp açın ve #include listesine ekleyin:
C++:
Genişlet Daralt Kopyala
#include <dxgi1_4.h>

Bulun:
C++:
Genişlet Daralt Kopyala
DWORD CGraphicBase::GetAvailableTextureMemory()
{
    assert (ms_lpd3dDevice!=NULL && "CGraphicBase::GetAvailableTextureMemory - D3DDevice is EMPTY");

    static DWORD s_dwNextUpdateTime=0;
    static DWORD s_dwTexMemSize=0;//ms_lpd3dDevice->GetAvailableTextureMem();

    DWORD dwCurTime=ELTimer_GetMSec();
    if (s_dwNextUpdateTime<dwCurTime)
    {
        s_dwNextUpdateTime=dwCurTime+5000;
        s_dwTexMemSize=ms_lpd3dDevice->GetAvailableTextureMem();
    }

    return s_dwTexMemSize;
}

Komple değiştirin:
C++:
Genişlet Daralt Kopyala
uint64_t CGraphicBase::GetAvailableTextureMemory()
{
    assert(ms_lpd3dDevice != NULL && "CGraphicBase::GetAvailableTextureMemory - D3DDevice is EMPTY");

    static DWORD    s_dwNextUpdateTime = 0;
    static uint64_t s_uRemainVRAM = 0;

    DWORD dwCurTime = ELTimer_GetMSec();
    if (s_dwNextUpdateTime < dwCurTime)
    {
        s_dwNextUpdateTime = dwCurTime + 5000;
        //Kaiser: current->used->available
        IDXGIFactory4* factory = nullptr;
        IDXGIAdapter1* adapter1 = nullptr;
        IDXGIAdapter3* adapter3 = nullptr;

        if (SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))) &&
            SUCCEEDED(factory->EnumAdapters1(0, &adapter1)) &&
            SUCCEEDED(adapter1->QueryInterface(IID_PPV_ARGS(&adapter3))))
        {
            DXGI_QUERY_VIDEO_MEMORY_INFO info = {};
            if (SUCCEEDED(adapter3->QueryVideoMemoryInfo(
                0,
                DXGI_MEMORY_SEGMENT_GROUP_LOCAL, // Kaiser: En güvenilir seçenek LOCAL'dir.
                &info)))
            {
                if (info.Budget > info.CurrentUsage)
                    s_uRemainVRAM = info.Budget - info.CurrentUsage;
                else
                    s_uRemainVRAM = 0;
            }
        }
        SAFE_RELEASE(adapter3);
        SAFE_RELEASE(adapter1);
        SAFE_RELEASE(factory);
    }
 
    return s_uRemainVRAM;
}

PythonApplicationModule.cpp açın ve bulun:
C++:
Genişlet Daralt Kopyala
PyObject * appGetAvaiableTextureMememory(PyObject * poSelf, PyObject * poArgs)
{      
    return Py_BuildValue("i", CGraphicBase::GetAvailableTextureMemory());
}

Bu koddaki "i" kısmını "K" olarak değiştirin.

Sonuç(VRAM = game.py içindeki varsayılan olarak bulunan ATM yazısıdır. Değiştirebilirsiniz.):
Ekran görüntüsü 2026-01-26 124540.webp


BİLMENİZ GEREKENLER:
Bu düzenleme sonucu göreceğiniz değerler, GPU'nun maksimum kapasitesi üzerinden değil Windows'un GPU'da uygulamaya ayırdığı alan üzerinden; DXGI’nin bildirdiği “kullanılabilir bütçeden” motorun henüz dokunmadığı kısmı gösterir. Yani 16GB bir ekran kartının bu hesaplamadaki maksimum kapasitesi ~14.8–15.2 GB civarı olabilmektedir. FPS ile doğrudan bir bağlantısı yoktur.

Örneğin; sahnede 50 tane tamamen aynı görünen savaşçı karakteri varsa, bunlardan 1 tanesi bu hesaplamaya dahil edilir. Geriye kalan 49 tanesi zaten birebir aynı olduğundan FPS'i etkilese bile bellek hareketinde büyük bir oynama yapmayacaktır ya da hiç yapmayacaktır. Çünkü birebir aynı dokulara, yüzeylere vb. sahipler.
Yani burada amaç, oluşturulan yüzeyler, dokular, tampon bellek hareketleri, yeni arazi parçalarının sahneye girişi vb. gibi şeylere bağlı olarak GPU belleğinde oluşan değişimleri gözlemlemektir.


Derleme sırasında çözümlenmemiş dış sembol hatası alırsanız verdiğim .lib dosyasını projenize ekleyin.( )
 

Dosya Eklentileri

abim efsane konu olmuş wpde bahsettiğin kadar var. p2p çalışıyor mu peki bu? quiye ekleme yapamaz mıyız?
 
eline sağlık , ufak bir bilgi düzeltmesi ekleyeyim ;

bu sorun aslında 32bit 4gb sınırı değil GetAvailableTextureMem() fonksiyonu dx8 veya dx9 da hiç bir zaman gerçek vram veya doğru bellek bilgisini vermek üzere yapılmamış, yani sürücüden gelen tahmini bir değeri döndürüyor yani doğal bir sonuç bu ama dxgi fikri muhteşem ve çok modern durmuş.
 
eline sağlık , ufak bir bilgi düzeltmesi ekleyeyim ;

bu sorun aslında 32bit 4gb sınırı değil GetAvailableTextureMem() fonksiyonu dx8 veya dx9 da hiç bir zaman gerçek vram veya doğru bellek bilgisini vermek üzere yapılmamış, yani sürücüden gelen tahmini bir değeri döndürüyor yani doğal bir sonuç bu ama dxgi fikri muhteşem ve çok modern durmuş.
Evet o da ayrı bir olay. Fakat 4GB sınırı da mevcuttur. GetAvailableTextureMem() directx8/9un kendi içerisinde UINT döndürüyor, bu da doğal olarak 4GB dan fazlasını işleme alamıyor.
 
Geri
Üst