Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Lexington

Frischling

  • »Lexington« ist der Autor dieses Themas

Beiträge: 17

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

1

08.10.2014, 00:39

[Direct3D 11] CreateShaderResourceView Memory Leak?!

Hi,

in einem meiner Projekte benutze ich Compute Shader und greife dort auf eine Textureressource
pro Frame einmal mit einer UnorderedAccessView und einmal mit einer ShaderResourceView zu.
Da eine Resource nicht gleichzeitig durch eine UAV und eine SRV gebunden sein kann, erzeuge ich alternierend die Views auf die Ressource.

Nun beobachtete ich merkwürdiges Verhalten in der Speichernutzung meines Programms.
Es wurden innerhalb von Sekunden über 300MB an RAM reserviert, danach ging es in kleineren Schritten bis 399MB.
Der Übeltäter ist einzig und allein die folgende Stelle im Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
while(m_pMainWindow->isVisible()) {
ComPtr<ID3D11ShaderResourceView> pOutputTextureView;
HRESULT result = m_pD3DController->getDevice()->CreateShaderResourceView(
                m_pOutputTexture.Get(),
                nullptr,
                pOutputTextureView.GetAddressOf());
}


Der Anstieg der RAM-Nutzung bleibt unverändert, auch wenn man statt des ComPtr's einen raw pointer benutzt und manuell Release() aufruft.
Die ref-Counts habe ich gecheckt. Der von m_pOutputTexture bleibt unverändert auf 1.
Result ist S_OK so lange, bis ein Out-of-Memory Fehler kommt.

Ich sehe nicht, wo hier das Problem ist. Weiß jemand, was im Hintergrund passieren könnte/wieso es dazu kommt? Bug oder Feature?

Liebe Grüße,
Lexington

EDIT:
Das Lustige ist, dass dieser Fehler nur auftritt, wenn ich den obigen Code alleine laufen lasse. Aktiviere ich das Rendering und die Compute Shader Ausführung, dann tritt das besagte Leaking
nur auf, wenn das Anwendungsfenster minimiert ist. Es scheint fast so, als würde es auftreten, wenn man nichts auf die Swap Chain rendert bzw. wenn kein Present der Swap Chain aufgerufen wird.
Ich bin definitiv kein Anfänger in Direct3D 11 aber das ist mir echt noch nie passiert.

EDIT2:
Beim Starten des Programmes ist der RAM-Verbrauch bei etwa 10MB, wenn man das Fenster minimiert steigt er sofort auf 20MB an und erhöht sich etwa um 200KB jede Sekunde. Wenn man das Fenster jetzt wieder maximiert,
sinkt der Verbrauch auf etwa 20MB ab und bleibt auch dort.
Ich verwende keinerlei raw pointer in meinem Projekt (außer schwache Referenzen, wenn ein Objekt nicht der Besitzer ist). Lediglich ComPtr, UniquePtr und nur statische Arrays.

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »Lexington« (08.10.2014, 01:13)


2

08.10.2014, 02:12

Hmm, keine Ahnung, was da schief läuft, aber erstell doch mal Textur und ResourceView einmalig, du musst weder Textur noch ResourceView in jedem Frame neu erstellen, solange sich die Eigenschaften der Textur nicht ändern.
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

Lexington

Frischling

  • »Lexington« ist der Autor dieses Themas

Beiträge: 17

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

3

08.10.2014, 07:31

Die Textur erstelle ich natürlich nicht in jedem Frame neu.
Der/die/das View muss ich aber in jedem Frame neu erstellen da die Texturressource nicht gleichzeitig an ein UAV und an ein SRV gebunden sein kann.
Es geht ja auch darum dieses Verhalten zu ergründen. Ich möchte einfach wissen wieso diese Leaks auftreten, wenn es keine Draw und Present Aufrufe gibt.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

4

08.10.2014, 08:24

Du musst doch nur jeweils einen View davon einmal erzeugen und jeweils abwechselnd binden? Daher gibt es ja die Trennung zwischen View und Ressource, so dass du mehrere Views für eine Ressource hast. Jeweils abwechselnd einen View pro Frame zu erstellen ist ja prinzipiell nicht so toll. oder verstehe ich da was falsch?

Lexington

Frischling

  • »Lexington« ist der Autor dieses Themas

Beiträge: 17

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

5

08.10.2014, 08:47

An sich ergibt es schon Sinn wie du es schreibst aber bei meiner Argumentation beziehe ich mich auf folgende Passage aus dem MSDN über RWTexture2D:


"Note: The runtime enforces certain usage patterns when you create multiple view types to the same resource. For example, the runtime does not allow you to have both a UAV mapping for a resource and SRV mapping for the same resource active at the same time."

So wie ich diesen Passus verstehe, kann man nicht gleichzeitig UAV und SRV auf eine Ressource haben.

Trotzdem angenommen es würde gehen, dann gibt es immer noch kein Grund, warum der Speicherverbrauch so extrem und mit komischem Verhalten in die Höhe schnellt. Nach jedem Frame werden die Views wieder released und dann sollte es doch egal sein ob ich so ein Ding einmal erzeuge oder einhunderttausendmal.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

08.10.2014, 09:08

"Note: The runtime enforces certain usage patterns when you create multiple view types to the same resource. For example, the runtime does not allow you to have both a UAV mapping for a resource and SRV mapping for the same resource active at the same time."

Doch, kannst du (beachte das "active" in deinem Zitat ;)). Und wenn möglich solltest du es natürlich unbedingt vermeiden, ständig neue Views zu erzeugen nur um sie gleich wieder zu löschen. Was du nicht kannst, ist lediglich, gleichzeitig ein UAV und ein SRV in die selbe Resource gebunden haben (also verwenden). Und der Grund dafür sollte klar sein, denn das würde bedeuten, dass deine Shader aus einer Resource, in die gerade geschrieben wird, auch lesen könnten, was keine sinnvolle Konstruktion ist...

Trotzdem angenommen es würde gehen, dann gibt es immer noch kein Grund, warum der Speicherverbrauch so extrem und mit komischem Verhalten in die Höhe schnellt. Nach jedem Frame werden die Views wieder released und dann sollte es doch egal sein ob ich so ein Ding einmal erzeuge oder einhunderttausendmal.

Das ist in der Tat richtig; ich würde mal vermuten, dass du irgendwo eben etwas nicht wieder freigibst, z.B. weil du irgendwo mit den Smartpointern was falsch machst oder du irgendeine Operation hast, die intern eine Referenz auf die Ressource hält. Es könnte sich natürlich z.B. auch um einen Driverbug handeln...

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »dot« (08.10.2014, 09:17)


TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

7

08.10.2014, 09:11

Wenn dot das sagt, dann kannst du tatsächlich jeweils deine zwei Views einmal erzeugen und dann jeweils den einen deaktivieren und den anderen aktivieren. Dann sollte alles klappen!

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

08.10.2014, 10:00

Hab das mal in einem minimalen Beispiel ausprobiert, der Speicher scheint wirklich zu leaken, wenn die View nicht mindestens einmal an den Rendercontext gebunden wurde (plus Present der SwapChain). Sieht auf den ersten Blick tatsächlich so aus als würde da intern was schief laufen, ich könnte mir vorstellen das Microsoft irgendeine Form von "lazy initialization" vornimmt und deshalb das Objekt nicht richtig freigegeben wird.
@D13_Dreinig

Lexington

Frischling

  • »Lexington« ist der Autor dieses Themas

Beiträge: 17

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

9

08.10.2014, 10:41

Danke erstmal für eure Antworten.

@dot: Ich habe das "active" dann wohl falsch interpretiert. Die View wurde nur in jedem Frame neu erzeugt, weil ich davon ausgegangen bin, dass jeweils nur eine View-Art auf die Ressource existieren darf (was mir so schon spanisch vorkam).
An meiner eigenen Speicherverwaltung kann es definitiv nicht liegen. Der Speicher leakt nicht mehr, wenn ich das Erzeugen der View auskommentiere. Und die View selbst wird durch den ComPtr verwaltet, der Ref-Count ist höchstens 1 (ich hole mir keine weitere Referenz auf die View).

@David_pb: Danke für deine Mühe, es beruhigt mich, dass der Fehler nicht nur bei mir aufzutreten scheint. Es ist zwar nicht der Alltagsfall aber ich finde es schon ein bisschen nachlässig, dass Microsoft das nicht in der Dokumentation erwähnt.

Ich werde das ganze mal wie empfohlen umbasteln und schauen, inwieweit der Fehler dann noch besteht.

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

10

08.10.2014, 11:27

Du wirst dadurch bestimmt auch einen kleinen Performanceschub bekommen. ;)
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Werbeanzeige