2017-10-19 11 views
0

Je réalise une capture du tampon arrière Direct3D. Lorsque je télécharge les pixels, le cadre de l'image est retourné le long de son axe vertical. Est-il possible de "dire" à D3D de retourner le cadre lors de la copie de la ressource, ou lors de la création de la cible ID3D11Texture2D?Direct3D11: basculement ID3D11Texture2D

Voici comment je le fais:

La texture dans laquelle je copie la mémoire tampon de trame est créé comme ceci:

D3D11_TEXTURE2D_DESC description = 
    { 
     desc.BufferDesc.Width, desc.BufferDesc.Height, 1, 1, 
     DXGI_FORMAT_R8G8B8A8_UNORM, 
     { 1, 0 }, // DXGI_SAMPLE_DESC 
     D3D11_USAGE_STAGING,//transder from GPU to CPU 
     0, D3D11_CPU_ACCESS_READ, 0 
    }; 
    D3D11_SUBRESOURCE_DATA data = { buffer, desc.BufferDesc.Width * PIXEL_SIZE, 0 }; 
    device->CreateTexture2D(&description, &data, &pNewTexture); 

Puis sur chaque image que je fais:

 pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pSurface)); 
    pContext->CopyResource(pNewTexture, pSurface); 
    D3D11_MAPPED_SUBRESOURCE resource; 
    pContext->Map(pNewTexture, 0, D3D11_MAP_READ , 0, &resource); 
    //reading from resource.pData 
    //... 

PS: Je n'ai pas de contrôle sur le pipeline de rendu. Je raccorde une application externe avec ce code. En outre, je ne veux pas jouer avec le tampon de pixels sur la CPU, comme la copie inverse dans une boucle, etc .. La faible latence de la copie est de haute priorité.

MISE À JOUR:

J'ai aussi essayé ceci:

D3D11_BOX box; 
    box.left = 0; 
    box.right = desc.BufferDesc.Width; 
    box.top = desc.BufferDesc.Height; 
    box.bottom = 0; 
    box.front = 0; 
    box.back = 1; 
    pContext->CopySubresourceRegion(pNewTexture, 0, 0, 0, 0, pSurface, 0, &box); 

Ce qui fait que le cadre soit vide de son contenu.

+0

N'oubliez pas de vérifier les valeurs '' HRESULT'' sur les fonctions qui retournent non-''void''. Vous êtes en train de supposer que cela fonctionne toujours. Utilisez '' SUCCEEDED'', '' FAILED'', ou quelque chose comme [ThrowIfFailed] (https://github.com/Microsoft/DirectXTK/wiki/ThrowIfFailed). –

+0

@ChuckWalbourn Fait en fait tout le chemin .. Retiré ici pour des raisons de simplicité. –

+0

Un exemple basé sur multi crochets un ancien projet: https://github.com/headmax/Cplus/blob/master/Projet4/Main.cpp dunno si vraiment vous aider ... –

Répondre

0

Toutes les ressources Direct3D mappées devraient être traitées par ligne de balayage ligne de balayage, donc juste inverser la copie:

auto ptr = reinterpret_cast<const uint8_t>(resource.pData) 
      + (desc.BufferDesc.Height - 1) * resource.RowPitch; 

for(unsigned int y = 0; y < desc.BufferDesc.Height; ++y) 
{ 
    // do something with the data in ptr 
    // which is desc.BufferDesc.Width * BytesPerPixel(desc.Format) bytes 
    // i.e. DXGI_FORMAT_R8G8B8A8_UNORM would be desc.BufferDesc.Width * 4 
    ptr -= resource.RowPitch; 
} 

Pour beaucoup d'exemples de travail avec les ressources Direct3D, voir DirectXTex.

+0

Pas une option. J'ai besoin de la copie pour être extrêmement rapide. Je cherche un moyen de faire le flip sur le côté du pilote ou du GPU. Je vais le souligner dans ma question. –

+0

Vous pouvez simplement rendre un quad à une texture avec le Vs retourné ... –

0

Créer une texture avec D3D11_USAGE_DEAFULT, avec CPUAccessFlags = 0 et BindFlags = D3D11_BIND_SHADER_RESOURCE. CopyResource le backbuffer de la swapchain à lui. Créez une autre texture avec D3D11_BIND_RENDER_TARGET. Définissez-le comme une cible de rendu, définissez un pixel shader et dessinez un quad retourné en utilisant la première texture. Vous devriez maintenant être en mesure de CopyResource la deuxième texture à la texture de mise en scène que vous utilisez maintenant. Cela devrait être plus rapide que de copier une image retournée avec le CPU. Cependant, cette solution nécessiterait plus de ressources sur le GPU et pourrait être difficile à installer dans un hook.