2017-10-19 208 views
0

我执行Direct3D后台缓冲区的捕获。当我下载像素时,图像帧沿着其垂直轴翻转。当复制资源时,或者在创建目标时,可以“告诉”D3D翻转该帧。Direct3D11:翻转ID3D11Texture2D

这是我如何做到这一点:

到我复制帧缓存纹理创建这样的:

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); 

然后每帧我做的:

 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:我没有渲染管道的控制权。我用这段代码挂钩了一个外部应用程序。 此外,我不想弄乱CPU上的像素缓冲区,就像循环中的反向复制等。副本的低延迟是高优先级。

UPDATE:

我也试过这样:

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); 

这将导致框架是从它的内容为空。

+0

不要忘记检查那些返回非''void''的函数的''HRESULT''值。您目前假设它始终有效。使用''SUCCEEDED'',''FAILED''或类似[ThrowIfFiled](https://github.com/Microsoft/DirectXTK/wiki/ThrowIfFailed)。 –

+0

@ChuckWalbourn实际上一直这样做..为简单起见,在这里删除。 –

+0

基于多钩子一个旧项目的例子:https://github.com/headmax/Cplus/blob/master/Projet4/Main.cpp不知道如果真的帮助你... – 2017-10-19 07:20:54

回答

0

所有的Direct3D映射的资源应该被处理的扫描线逐个扫描线,所以才扭转副本:

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; 
} 

对于大量使用的Direct3D资源工作的例子,见DirectXTex

+0

没有选项。我需要的副本速度非常快。我试图在驱动程序或GPU方面做翻转的方式。我会在我的问题中强调这一点。 –

+0

只需将Vs翻转即可将四边形渲染到纹理... –

0

用D3D11_USAGE_DEAFULT创建一个纹理,CPUAccessFlags = 0,BindFlags = D3D11_BIND_SHADER_RESOURCE。将资源交换链的后台缓冲区复制到它。用D3D11_BIND_RENDER_TARGET创建另一个纹理。将其设置为渲染目标,设置像素着色器并使用第一个纹理绘制翻转的四边形。现在,您应该可以将第二个纹理的CopyResource更改为您现在使用的临时纹理。这应该比使用CPU复制翻转的图像数据更快。但是,这种解决方案会占用GPU上的更多资源,并且可能很难在钩子中进行设置。