0

I have a ID3D11Texture2D and want to write it to disk using literally any picture format (png, bmp, jpeg, ...). I have already tried to read the docs https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nn-d3d11-id3d11texture2d, which are less than helpful, and i have found an NVIDIA tutorial of how to take individual ID3D11Texture2D and convert them into a video: https://github.com/NVIDIA/video-sdk-samples/tree/master/nvEncDXGIOutputDuplicationSample

However, I dont find anything how to simply write it to disk in any format. I'm sure I'm missing something obvious, any hint would be appreciated.

To experiment, I used https://github.com/NVIDIA/video-sdk-samples/tree/master/nvEncDXGIOutputDuplicationSample, set the frames to capture to 1, and try to write the ID3D11Texture2D to file before encoding to video.

Markus Weninger
  • 11,931
  • 7
  • 64
  • 137
loonytune
  • 1,775
  • 11
  • 22
  • You must map the texture to get access to its pixels buffer (this is only possible with textures with CPU read access obviously, if it's not the case then you must create a new one with CPU read access and copy pixels to it) and then use for example Wic to save the bits using a similar code to SavePixelsToFile32bppPBGRA function in this SO answer https://stackoverflow.com/a/30138664/403671 – Simon Mourier Apr 01 '22 at 12:48
  • I have read about WIC before, and I think I also found that answer already. But it doesnt really help because it uses different types and formats and I have no idea on how and what to change to make it work with a different input. – loonytune Apr 01 '22 at 13:11
  • Can you point me into the right direction on where i find instructions on how to do this? – loonytune Apr 01 '22 at 13:37
  • This https://stackoverflow.com/a/43631781/403671 answer the first part, and my other answer has enough information. If you have problem with these, post your code. – Simon Mourier Apr 01 '22 at 15:00

1 Answers1

4

I have a solution for exactly this in the ScreenGrab module which captures a texture (if not already in Map-supporting memory), and then writes it out as a picture using WIC. It handles some edge-cases like "typeless" resources and MSAA as well.

The 'standalone' version is on GitHub here as part of the DirectXTex package:

https://github.com/microsoft/DirectXTex/blob/main/ScreenGrab/ScreenGrab11.h

https://github.com/microsoft/DirectXTex/blob/main/ScreenGrab/ScreenGrab11.cpp

Documentation is here.

ScreenGrab is also included in the DirectX Tool Kit for DX11 and DX12. There's also a basic DX9 version in the DirectXTex package as well.

ScreenGrab can write to any file container supported by WIC. It also has buit-in support for writing DDS files directly without using WIC.

In addition to using ScreenGrab (which is intended as a light-weight screenshot solution), you can also use the DirectTex library to capture a texture and then save it to DDS, HDR, TGA, or any WIC-supported file format.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • 1
    Thanks for this @ChuckWalbourn. Just a note that without the standalone version (i.e. just using DXTK), it's necessary to include `` to get the **GUID_ContainerFormat** definitions. – Maico De Blasio Apr 03 '22 at 03:34
  • 2
    Fair enough. Added a note to the wiki page. – Chuck Walbourn Apr 04 '22 at 02:48
  • it's solved perfectly. only followup problem that i have is that the function takes up to a minute to complete if i have a game running (in my case rdr2), only milliseconds if my system is (almost) idle. but thats worth a separate question i guess. ill mark it as accepted, since it solves my problem. thanks for the help! – loonytune Apr 12 '22 at 14:45
  • @ChuckWalbourn see my followup question here in case u have any ideas: https://stackoverflow.com/questions/71706795/how-to-transform-a-id3d11texture2d-into-any-picture-format – loonytune Apr 19 '22 at 13:39