Direct3D11: Flipping ID3D11Texture2D

匿名 (未验证) 提交于 2019-12-03 09:14:57

问题:

I perform a capture of Direct3D back buffer. When I download the pixels the image frame is flipped along its vertical axis.Is it possible to "tell" D3D to flip the frame when copying resource,or when creating target ID3D11Texture2D ?

Here is how I do it:

The texture into which I copy the frame buffer is created like this:

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

Then on each frame I do:

     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: I don't have a control of the rendering pipeline. I hook an external app with this code. Also,I don't want to mess with the pixel buffer on the CPU, like reverse copy in a loop etc.. The low latency of the copy is high priority.

UPDATE:

I also tried this:

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

Which causes the frame to be empty from its content.

回答1:

Create a texture with D3D11_USAGE_DEAFULT, with CPUAccessFlags=0 and BindFlags=D3D11_BIND_SHADER_RESOURCE. CopyResource the swapchain's backbuffer to it. Create another texture with D3D11_BIND_RENDER_TARGET. Set it as a render target, set a pixel shader and draw a flipped quad using the first texture. Now you should be able to CopyResource the second texture to the staging texture that you use now. This should be faster than copying a flipped image data using the CPU. However, this solution would take more resources on the GPU and might be hard to setup in a hook.



回答2:

All Direct3D mapped resources should be processed scanline-by-scanline, so just reverse the copy:

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

For lots of examples of working with Direct3D resources, see DirectXTex.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!