c ++ - Forbruger-Producent-tråde med DirectX-desktop rammer

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg skriver en DirectX-applikation med to tråde:



  • Producentens tråd tager fat i desktop rammer med DirectX (som i DirectX-eksemplet Desktop Duplication) [18]


    IDXGIResource* DesktopResource = nullptr;
    ID3D11Texture2D *m\_AcquiredDesktopImage = nullptr;
    HRESULT hr = m\_DeskDupl->AcquireNextFrame(500, &FrameInfo, &DesktopResource);
    hr = DesktopResource->QueryInterface(\_\_uuidof(ID3D11Texture2D), reinterpret\_cast<void **>(&m\_AcquiredDesktopImage));
    DesktopResource->Release();
    // The texture pointer I'm interested is m\_AcquiredDesktopImage
    

  • Forbruger tråd udfører billedbehandling på GPU'en.



For at undgå kopier vil jeg gerne holde alt på GPU'en så meget som muligt. Fra versionFrames dokumentation kan jeg få det til at ringe ReleaseFrame på desktop duplikationsgrænsefladen, så snart jeg har behandlet rammen . [19]


Mit spørgsmål: Skal jeg kopiere m\_AcquiredDesktopImage tekstur til en anden og kalde ReleaseFrame så snart kopien er færdig og returnere den nye tekstur til producentens tråd til behandling, eller kan jeg bare komme væk med at returnere m\_AcquiredDesktopImage teksturpeger til forbrugerens tråd? Er dette en kopi af Framebuffer-tekstur eller er det Framebuffer-tekstur, og jeg kan generere et dataløb ved at returnere det?


Hvilken er den rigtige måde at håndtere en producent af greb rammer på og en forbruger af GPU-teksturer?

Bedste reference



  ... skal jeg kopiere m\_AcquiredDesktopImage tekstur til en anden og ringe ReleaseFrame så snart kopien er færdig og returnere den nye tekstur til producentens tråd til behandling eller ...



Ja, det er vejen. Du har din tekstur, du er færdig med det, og du frigiver det, fordi dataene ikke længere er gyldige efter udgivelsen.



  ... kan jeg bare komme væk med at returnere m\_AcquiredDesktopImage teksturpekeren til forbrugstråden? Er dette en kopi af Framebuffer-tekstur eller er det Framebuffer-tekstur, og jeg kan generere et dataløb ved at returnere det?



API'en opdaterer denne tekstur. Du er lovet, at mellem vellykket afkast fra AcquireNextFrame og dit ReleaseFrame opkald ikke berører API'en tekstur, og du er fri til at bruge den. Hvis du ikke kan afslutte din brug mellem de nævnte opkald (som det er tilfældet, oprettede du efter alt en forbruger tråd til at køre asynkront for at indfange) du kopierer data og ReleaseFrame. Når du har frigivet det, genoptager API'en opdateringen.


Et forsøg på at bruge tekstur efter ReleaseFrame vil resultere i samtidig adgang til tekstur, din og API'ens yderligere opdateringer.

Andre referencer 1


MSDN-dokumentationen på ReleaseFrame er lidt forvrænget. Det specificerer specifikt, at du skal frigive den aktuelle ramme, før du behandler den næste, og at overfladestatusen er 'ugyldig' efter frigivelse, hvilket ville indikere, at det ikke er en kopi eller ikke en kopi, som din proces ejer (hvilket ville give det samme effektive resultat). Det hedder også, at du bør forsinke opkaldet til ReleaseFrame indtil lige før du ringer til AcquireNextFrame af ydeevne, hvilket kan skabe nogle interessante timingproblemer, især med den trådemodel, du bruger.


Jeg tror, ​​at du er bedre til at lave en kopi (så ReleaseFrame fra den tidligere fangst, AcquireNextFrame, CopyResource. Medmindre du 'bruger hegn, har du ingen garantier for GPU vil indtage ressourcen før din producentens tråd har kaldt ReleaseFrame, hvilket kunne give dig udefinerede resultater. Og hvis du er ved hjælp af hegn, og AcquireNextFrame -opkaldet er forsinket indtil GPU'en er færdig med at forbruge den foregående frames data, vil du introducere boder og miste mange af fordelene ved, at CPU'en kan løbe foran GPU'en.


Jeg er nysgerrig, hvorfor du går med denne trådmodel, når arbejdet er færdigt på GPU'en. Jeg formoder, at det gør livet lidt mere kompliceret. Selvom at lave en kopi af tekstur ville fjerne mange af disse komplikationer.