Dreu Zmeu scrie: ↑*Problemă/Întrebare:Salut, ma confrunt cu un freeze total al clientului in momentul in care incerc sa rulez doua instante simultan. Primul client ingheata (Not Responding) imediat ce al doilea client este pornit. Daca nu ingheata, crapa cu erori de memorie video sau erori de tip Granny.
Detalii despre sistemul de Cache/Preload din sursa:
-Sursa foloseste un
sistem de pre-incarcare care incearca sa ridice toate resursele (animatii,
efecte, modele
NPC) in memoria video la startul jocului.
-Animatii: Foloseste LoadStaticCache in PythonPlayerSettingsModule.cpp pentru a bloca fisierele .msa in VRAM.
-Efecte: Inregistreaza mii de efecte cu parametrul bCache = true.
-Threaded Loading: Foloseste FileLoaderThread pentru a procesa aceste cereri in fundal.
Modificari efectuate deja in sursa:
-Optimizare Memorie: Am dezactivat incarcarea statica (LoadStaticCache) in ResourceManager.cpp pentru a evita umplerea VRAM-ului la start.
-Lazy Loading: Am setat
efectele si emotiile pe false in PythonPlayerSettingsModule.cpp.
-Device Restore: In CheckDeviceState, am implementat eliberarea resurselor inainte de Reset() si re-initializarea bufferelor Granny (GrannyCreateSharedDeformBuffer) dupa restaurare.
-Logic Fix: Am incercat sa folosesc un goto catre sectiunea de restaurare a device-ului in Process() pentru a opri orice calcul 3D cat timp placa video este pierduta.
Comportament observat:
Desi ambele cliente pornesc cu un consum mic de memorie, exista un conflict in momentul schimburii de focus. Se pare ca thread-ul principal intra intr-o stare de asteptare infinita (Deadlock) asteptand ca driverul video sa redevina disponibil, dar acest lucru nu se mai intampla.
Intrebari:
Ar putea fi o problema legata de sincronizarea thread-ului de incarcare (FileLoaderThread) cu thread-ul de randare in momentul unui "Device Lost"?
Exista vreo setare in CGraphicDevice care sa previna blocajul ferestrei cand DirectX pierde contextul?
Este necesara o gestionare speciala a bufferelor Granny la nivel de CGrannyModelInstance pentru a permite multi-client pe configuratii mai slabe?
*Resursă folosită (sistem/funcție/modificare): Serverfiles M2PROJECT
*Syserr:0126 21:08:04142 :: CreateDDSTexture: Cannot create texture
0126 23:58:40839 :: GRANNY DEFORM DYNAMIC BUFFER LOCK ERROR
*Fișier(e) cu problema (link pastebin / code): N/A
*Poze / Video: N/A
Salut! Problema descrisă indică un conflict clasic de gestionare a resurselor DirectX și sincronizare a thread-urilor în timpul unui "Device Lost" (pierdere de context DirectX), frecvent întâlnit la rularea multi-client. Erorile din syserr confirmă acest lucru.
Iată răspunsurile la întrebările tale și o direcție de rezolvare:
1. **Ar putea fi o problema legata de sincronizarea thread-ului de incarcare (FileLoaderThread) cu thread-ul de randare in momentul unui "Device Lost"?**
*
Da, absolut. Acesta este un scenariu foarte probabil. Când DirectX pierde contextul, toate resursele
devin invalide. Dacă
FileLoaderThread încearcă să creeze sau să acceseze resurse DirectX în timp ce device-ul este pierdut sau în curs de resetare, poate duce la blocaje (deadlock) sau erori. Thread-ul principal de randare trebuie să semnaleze
FileLoaderThread să-și suspende operațiunile legate de DirectX până la restaurarea completă a device-ului.
2. **Exista vreo setare in CGraphicDevice care sa previna blocajul ferestrei cand DirectX pierde contextul?**
* Nu există o "setare" directă. Soluția constă într-o implementare robustă a gestionării stării device-ului. Funcția
IDirect3DDevice9::TestCooperativeLevel()
trebuie apelată regulat.
* Dacă returnează
, clientul trebuie să
oprească orice încercare de randare sau creare de resurse și să aștepte (ex:
) până când device-ul devine disponibil pentru resetare.
* Dacă returnează
, atunci trebuie apelată funcția de restaurare a device-ului (ex:
CGraphicDevice::RestoreDevice()).
* Blocajul ferestrei apare când aplicația încearcă să folosească un device DirectX invalid sau intră într-o buclă de așteptare fără a elibera resursele corect.
3. **Este necesara o gestionare speciala a bufferelor Granny la nivel de CGrannyModelInstance pentru a permite multi-client pe configuratii mai slabe?**
*
Da, este esențială. Eroarea
GRANNY DEFORM DYNAMIC BUFFER LOCK ERROR
indică direct o problemă cu bufferele de deformare Granny. Acestea sunt adesea partajate și trebuie eliberate (
GrannyFreeSharedDeformBuffer()
) înainte de
IDirect3DDevice9::Reset()
și re-create (
GrannyCreateSharedDeformBuffer()
) după resetare, în cadrul funcției de restaurare a device-ului. Asigură-te că aceste apeluri sunt sincronizate și se întâmplă la momentul potrivit.
**Recomandări de verificare și implementare:**
1. **Sincronizare
FileLoaderThread:**
* În
CGraphicDevice.cpp sau unde gestionezi starea device-ului, adaugă un mecanism (ex: un flag global sau un mutex/event) care să semnaleze
FileLoaderThread când device-ul este pierdut.
* În
FileLoaderThread, înainte de orice operațiune care implică resurse DirectX (ex: încărcarea texturilor), verifică acest flag și așteaptă dacă device-ul este pierdut/resetat.
2. **Verifică logica de restaurare a device-ului:**
* Unde exact se află implementarea ta pentru
RestoreDevice() (sau funcția echivalentă)?
* Asigură-te că în această funcție,
toate resursele
(texturi, vertex/index buffere, buffere Granny) sunt eliberate
înainte de apelul
IDirect3DDevice9::Reset()
și re-create
după un reset de succes.
* Verifică apelurile
GrannyFreeSharedDeformBuffer()
și
GrannyCreateSharedDeformBuffer()
în
CGraphicDevice.cpp sau
GrannyManager.cpp pentru a te asigura că sunt în ordinea corectă în timpul restaurării.
3. **Gestionarea erorilor de textură:**
* Eroarea
CreateDDSTexture: Cannot create texture
sugerează că
CTextureManager sau o funcție similară încearcă să creeze o textură pe un device invalid. Asigură-te că
CTextureManager este notificat să elibereze resursele la pierderea device-ului și să le reîncarce după restaurare.
Te rog să specifici unde ai implementat exact logica de restaurare a device-ului (numele funcției și fișierul) pentru a putea oferi o verificare mai precisă.