- Katılım
- 23 Eki 2022
- Mesajlar
- 7,872
- Çözümler
- 12
- Tepkime puanı
- 4,565
- Puanları
- 113
- Yaş
- 28
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:
GrpBase.cpp açın ve #include listesine ekleyin:
Komple değiştirin:
PythonApplicationModule.cpp açın ve bulun:
Bu koddaki "i" kısmını "K" olarak değiştirin.

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++:
static DWORD GetAvailableTextureMemory();
Değiştirin:
C++:
static uint64_t GetAvailableTextureMemory();
GrpBase.cpp açın ve #include listesine ekleyin:
C++:
#include <dxgi1_4.h>
Bulun:
C++:
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++:
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++:
PyObject * appGetAvaiableTextureMememory(PyObject * poSelf, PyObject * poArgs)
{
return Py_BuildValue("i", CGraphicBase::GetAvailableTextureMemory());
}
Bu koddaki "i" kısmını "K" olarak değiştirin.
İçeriği görüntülemek için Giriş yapın veya Kayıt olun.
- Meta Title
- Metin2 VRAM & Texture Memory Fix – C++ Patch
- Meta Description
- Bu patch, Metin2 sunucuları ve clientleri için grafik belleği (VRAM) hesaplama sorunlarını çözer. DWORD tipindeki eski GetAvailableTextureMemory() fonksiyonunu uint64_t olarak günceller, DXGI 1.4 üzerinden doğru VRAM kullanımını raporlar ve Python modülünde dönüş tipini i yerine K yaparak büyük bellek desteği sağlar.
