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

11

24.05.2015, 21:17

Wenn ich das Programm ohne CopyResource ausführe und mit Open Broadcaster Software aufnehme ist der FPS-Verlust minimal.


Wie minimal denn? ;)

Von 13.000 runter auf 12.900, statt von 13.000 runter auf 1.300.

Ich möchte mehrere Kameras erstellen, das Bild jeweils abgreifen und im Arbeitsspeicher ablegen, da werde ich wohl um CopyResource() so oder so nicht herumkommen.

Bei 20x CopyResource() habe ich immer noch konstant 80 fps, dazu kommt dann später ja noch das Spiel selbst.
Mit diesen Werten kann ich erstmal leben.


Wenn ich z.b. 10 Kameras erstellen möchte und ihre Bilder in den Arbeitsspeicher ablegen will, ist dann der folgende Weg der richtige ?


## INIT ##
- 10x ID3D11RenderTargetView mit CreateRenderTargetView()
- OMSetRenderTargets(10, buffer)
- 30x ID3D11Texture2D mit CreateTexture2D() | 3x pro RenderTargetView für den ReadBackRing


## LOOP ##
- 10x ClearRenderTargetView()
- 10x Draw()
- 10x CopyResource()

Benötige ich 10x D3D11_VIEWPORT für die verschiedenen Blickwinkel der Kameras ?

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

12

24.05.2015, 23:22

Je nach Anwendungsfall helfen dir vielleicht die Ansätze 2 und 3 aus diesem Link: http://www.gamedev.net/page/resources/_/…irect3d10-r2735
Das ist zwar für Cubemaps beschrieben, aber wenn dein Anwendungsfall ähnlich genug ist kannst du das vielleicht adaptieren und du würdest um die 10 Draw-Calls herum kommen.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

13

25.05.2015, 11:56

Also irgendwas mache ich gewaltig falsch.

Ich habe eine Demo erstellt, in ActionScript 3, mit der AIR Runtime und der Away3D Engine.
Ich lasse einen texturierten Würfel rotieren und habe die maximale FPS auf 120 gesetzt.

- Bei einer Kamera, einer View und dem Auslesen der BitmapData aus der View habe ich 100 - 120 FPS.

- Bei vier Kameras, vier Views und auslesen der BitmapData der jeweiligen Kameras habe ich 70 - 100 FPS.
(Mehr als vier Views kann ich nicht erstellen da ich sonst zu viele Stage3D Instanzen habe)


Alternativ dazu, meine Demo in C++ und DirectX 11.
Ich habe über die WinAPI ein Fenster erstellt und DirectX 11 initialisiert.
Hier lasse ich ebenfalls ein einfaches Bild rendern und habe 13.000 FPS (keine maximale FPS festgelegt)

- Bei einer RenderTexture, einer CaptureTexture und einmal CopyResource() habe ich 1.500 FPS

- Bei 20x RenderTexture, 20x CaptureTexture und 20x CopyResource() habe ich 70 - 80 FPS
(Eine deutliche Verbesserung gegenüber ActionScript 3)




Wenn ich nun aber den Inhalt der CaptureTexture auslesen möchte dann bricht die FPS komplett ein.
Ich lese die Daten per D3DX11SaveTextureToMemory() in einen ID3D10Blob.

Bei einer RenderTexture, einer CaptureTexture und einmal CopyResource() und einmal D3DX11SaveTextureToMemory() bin ich bei 22 FPS.

14

27.05.2015, 19:11

Ich möchte das Abgreifen des Bildes beschleunigen.
Wenn sich jemand mit DirectX 11 auskennt und mir vielleicht helfen könnte.

Hier mein bisheriger Code:

## INIT ##

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ID3D11Texture2D *backBufferTexture;
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);

ID3D11RenderTargetView *backBuffer;
device->CreateRenderTargetView(backBufferTexture, NULL, &backBuffer);
deviceContext->OMSetRenderTargets(1, &backBuffer, NULL);

D3D11_TEXTURE2D_DESC captureTextureDesc;
ZeroMemory(&captureTextureDesc, sizeof(D3D11_TEXTURE2D_DESC));
backBufferTexture->GetDesc(&captureTextureDesc);
captureTextureDesc.BindFlags = 0;
captureTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
captureTextureDesc.Usage = D3D11_USAGE_STAGING;

ID3D11Texture2D *captureTexture;
device->CreateTexture2D(&captureTextureDesc, NULL, &captureTexture);

ID3D10Blob *captureData;


## LOOP ##

C-/C++-Quelltext

1
2
deviceContext->CopyResource(captureTexture, backBufferTexture);
D3DX11SaveTextureToMemory(deviceContext, captureTexture, D3DX11_IFF_DDS, &captureData, 0);


Wie bereits erwähnt habe ich normalerweise ~13.000 FPS.
Ab CopyResource() habe ich ~1.500 FPS und ab D3DX11SaveTextureToMemory() habe ich ~20 FPS.


Vorallem D3DX11SaveTextureToMemory() muss ich ersetzen, wäre memcpy schneller ?




Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

15

27.05.2015, 21:55

Wozu hat deine Capture Texture CPU_ACCESS_WRITE?

Und mit Pech synct deine CPU zur GPU wenn du D3DX11SaveTextureToMemory direkt hinter CopyResource aufrufst. D.h. die Funktion wartet bis der Kopiervorgang auch wirklich abgeschlossen ist. Das kann ich aber nicht mit Sicherheit sagen. Und in dem Fall wäre ein memcpy direkt hinterher auch nicht schneller.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

16

27.05.2015, 22:12

Wozu hat deine Capture Texture CPU_ACCESS_WRITE?

Und mit Pech synct deine CPU zur GPU wenn du D3DX11SaveTextureToMemory direkt hinter CopyResource aufrufst. D.h. die Funktion wartet bis der Kopiervorgang auch wirklich abgeschlossen ist. Das kann ich aber nicht mit Sicherheit sagen. Und in dem Fall wäre ein memcpy direkt hinterher auch nicht schneller.
CPU_ACCESS_WRITE war ein Überbleibsel aus einem Test, mit nur Read macht es auch keinen Unterschied.

Ich hatte gelesen dass sowohl CopyResource() als auch D3DX11SaveTextureToMemory() asynchron funktionieren.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

17

03.06.2015, 11:35

Ich hatte gelesen dass sowohl CopyResource() als auch D3DX11SaveTextureToMemory() asynchron funktionieren.


CopyResource wird von der GPU ausgeführt und sollte daher wirklich kein Syncpoint sein. (Siehe auch):

Zitat


The method is an asynchronous call which may be added to the command-buffer queue. This attempts to remove pipeline stalls that may occur when copying data.


Bei D3DX11SaveTextureToMemory wär ich mir da nicht so sicher. Du übergibst ja direkt deine Resource und kannst nach dem Aufruf davon ausgehen, dass die Daten im Puffer liegen. Die Funktion muss in irgendeiner Form warten bis die Daten komplett im Systemspeicher angekommen sind.
@D13_Dreinig

Werbeanzeige