Sign in to follow this  
Aqua Costa

DX11 Writing a D3DX11Buffer to a file

Recommended Posts

[quote name='Adam_42' timestamp='1313431778' post='4849473']
Umm, Google doesn't know what a "D3DX11Buffer" is...

Did you mean a [url=""]ID3DXBuffer[/url]?

Well I meant [url=""]ID3DX11Buffer[/url] (ID3DXBuffer -> DX9 / ID3D11Buffer -> DX11 So they should be similar :wink:)

Share this post

Link to post
Share on other sites
Do you mean the standard ID3D11Buffer resource, or are you using some framework on top of D3D11?

In general, to read the contents of a buffer in D3D11, you need to use a staging buffer. This is more or less a buffer resource of the same size that is created with the staging usage flag. Then you copy the desired buffer to the staging buffer with ID3D11DeviceContext::CopyResource (or one of the other methods for copying resource memory). This staging buffer can then be mapped and written to file.

The process for writing from file to the resource depends on when you have the data from file. If you can read the file before creating the resource, then you can provide the initial data to the resource creation method directly. Otherwise, depending on the target usage of the buffer you can use update subresource, or use the staging buffer in the reverse order.

Share this post

Link to post
Share on other sites
Well since you can't [url=""]CPU-Read[/url] from a static (default)/dynamic buffer, you have to create a second, staging-usage buffer where you map it, read the data, and then export the data to whatever format you're writing to. Then when you load said format up, you use that data as you normally would when initializing the buffer. Staging buffers can also be used the other way too, e.g. for a default-usage buffer that you may want to write data to after its been created.

Edit: Bah! Beaten to the punch :)

Share this post

Link to post
Share on other sites
1. Create a staging buffer with the same size
2. Copy to the staging buffer
3. Map the staging buffer to get a pointer to the buffer data
4. Write that data to a file using whatever file I/O classes/functions you're comfortable with

For any practical usage you'll probably want to also write some data indicating the size of the buffer, as well as other properties such as stride or format, the flags used to create it, etc. You'll probably want to do that before step 4, so that you have a little file header before the actual buffer data.

Reading it back in is just as easy. Read in your header data, use the header data to allocate enough memory to store the buffer data, read in the buffer data to that memory, then provide a pointer to that memory in the pSysMem pointer D3D11_SUBRESOURCE_DATA when creating the buffer with the size and flags specified by the header.

This is how I do it for my StructuredBuffer class:

struct StructuredBuffer
ID3D11BufferPtr Buffer;
ID3D11ShaderResourceViewPtr SRView;
ID3D11UnorderedAccessViewPtr UAView;
UINT Size;
UINT Stride;
UINT NumElements;


void Initialize(ID3D11Device* device, UINT stride, UINT numElements, BOOL useAsUAV = false,
BOOL appendConsume = false, BOOL useAsDrawIndirect = false, const void* initData = NULL);

void WriteToFile(const WCHAR* path, ID3D11Device* device, ID3D11DeviceContext* context);
void ReadFromFile(const WCHAR* path, ID3D11Device* device);

StructuredBuffer::StructuredBuffer() : Size(0), Stride(0), NumElements(0)

void StructuredBuffer::Initialize(ID3D11Device* device, UINT stride, UINT numElements, BOOL useAsUAV,
BOOL appendConsume, BOOL useAsDrawIndirect, const void* initData)
Size = stride * numElements;
Stride = stride;
NumElements = numElements;

if(appendConsume || useAsDrawIndirect)
useAsUAV = true;

D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = stride * numElements;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
bufferDesc.BindFlags |= useAsUAV ? D3D11_BIND_UNORDERED_ACCESS : 0;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags |= useAsDrawIndirect ? D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS : 0;
bufferDesc.StructureByteStride = stride;

D3D11_SUBRESOURCE_DATA subresourceData;
subresourceData.pSysMem = initData;
subresourceData.SysMemPitch = 0;
subresourceData.SysMemSlicePitch = 0;

DXCall(device->CreateBuffer(&bufferDesc, initData != NULL ? &subresourceData : NULL, &Buffer));

srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvDesc.Buffer.ElementOffset = 0;
srvDesc.Buffer.ElementWidth = numElements;
DXCall(device->CreateShaderResourceView(Buffer, &srvDesc, &SRView));

uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = appendConsume ? D3D11_BUFFER_UAV_FLAG_APPEND : 0;
uavDesc.Buffer.NumElements = numElements;
DXCall(device->CreateUnorderedAccessView(Buffer, &uavDesc, &UAView));

void StructuredBuffer::WriteToFile(const WCHAR* path, ID3D11Device* device, ID3D11DeviceContext* context)
_ASSERT(Buffer != NULL);

// Get the buffer info

UINT32 useAsUAV = (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) ? 1 : 0;
UINT32 useAsDrawIndirect = (desc.MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) ? 1 : 0;

UINT32 appendConsume = 0;
appendConsume = (uavDesc.Format & D3D11_BUFFER_UAV_FLAG_APPEND) ? 1 : 0;

// If the exists, delete it

// Create the file
if(fileHandle == INVALID_HANDLE_VALUE)

// Write the buffer info
DWORD bytesWritten = 0;
Win32Call(WriteFile(fileHandle, &Size, 4, &bytesWritten, NULL));
Win32Call(WriteFile(fileHandle, &Stride, 4, &bytesWritten, NULL));
Win32Call(WriteFile(fileHandle, &NumElements, 4, &bytesWritten, NULL));
Win32Call(WriteFile(fileHandle, &useAsUAV, 4, &bytesWritten, NULL));
Win32Call(WriteFile(fileHandle, &useAsDrawIndirect, 4, &bytesWritten, NULL));
Win32Call(WriteFile(fileHandle, &appendConsume, 4, &bytesWritten, NULL));

// Get the buffer data
StagingBuffer stagingBuffer;
stagingBuffer.Initialize(device, Size);
context->CopyResource(stagingBuffer.Buffer, Buffer);
const void* bufferData= stagingBuffer.Map(context);

// Write the data to the file
Win32Call(WriteFile(fileHandle, bufferData, Size, &bytesWritten, NULL));

// Un-map the staging buffer

// Close the file

void StructuredBuffer::ReadFromFile(const WCHAR* path, ID3D11Device* device)
// Open the file
if(fileHandle == INVALID_HANDLE_VALUE)

// Read the buffer info
UINT32 useAsUAV, useAsDrawIndirect, appendConsume;
DWORD bytesRead = 0;
Win32Call(ReadFile(fileHandle, &Size, 4, &bytesRead, NULL));
Win32Call(ReadFile(fileHandle, &Stride, 4, &bytesRead, NULL));
Win32Call(ReadFile(fileHandle, &NumElements, 4, &bytesRead, NULL));
Win32Call(ReadFile(fileHandle, &useAsUAV, 4, &bytesRead, NULL));
Win32Call(ReadFile(fileHandle, &useAsDrawIndirect, 4, &bytesRead, NULL));
Win32Call(ReadFile(fileHandle, &appendConsume, 4, &bytesRead, NULL));

// Read the buffer data
UINT8* bufferData = new UINT8[Size];
Win32Call(ReadFile(fileHandle, bufferData, Size, &bytesRead, NULL));

// Close the file

// Init
Initialize(device, Stride, NumElements, useAsUAV, appendConsume, useAsDrawIndirect, bufferData);

// Clean up
delete [] bufferData;

And this is the StagingBuffer class:
struct StagingBuffer
ID3D11BufferPtr Buffer;
UINT Size;


void Initialize(ID3D11Device* device, UINT size);
void* Map(ID3D11DeviceContext* context);
void Unmap(ID3D11DeviceContext* context);

StagingBuffer::StagingBuffer() : Size(0)

void StagingBuffer::Initialize(ID3D11Device* device, UINT size)
Size = size;

D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = Size;
bufferDesc.Usage = D3D11_USAGE_STAGING;
bufferDesc.BindFlags = 0;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
DXCall(device->CreateBuffer(&bufferDesc, NULL, &Buffer));

void* StagingBuffer::Map(ID3D11DeviceContext* context)
DXCall(context->Map(Buffer, 0, D3D11_MAP_READ, 0, &mapped));

return mapped.pData;

void StagingBuffer::Unmap(ID3D11DeviceContext* context)
context->Unmap(Buffer, 0);

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Forum Statistics

    • Total Topics
    • Total Posts
  • Similar Content

    • By noodleBowl
      I was wondering if anyone could explain the depth buffer and the depth stencil state comparison function to me as I'm a little confused
      So I have set up a depth stencil state where the DepthFunc is set to D3D11_COMPARISON_LESS, but what am I actually comparing here? What is actually written to the buffer, the pixel that should show up in the front?
      I have these 2 quad faces, a Red Face and a Blue Face. The Blue Face is further away from the Viewer with a Z index value of -100.0f. Where the Red Face is close to the Viewer with a Z index value of 0.0f.
      When DepthFunc is set to D3D11_COMPARISON_LESS the Red Face shows up in front of the Blue Face like it should based on the Z index values. BUT if I change the DepthFunc to D3D11_COMPARISON_LESS_EQUAL the Blue Face shows in front of the Red Face. Which does not make sense to me, I would think that when the function is set to D3D11_COMPARISON_LESS_EQUAL the Red Face would still show up in front of the Blue Face as the Z index for the Red Face is still closer to the viewer
      Am I thinking of this comparison function all wrong?
      Vertex data just in case
      //Vertex date that make up the 2 faces Vertex verts[] = { //Red face Vertex(Vector4(0.0f, 0.0f, 0.0f), Color(1.0f, 0.0f, 0.0f)), Vertex(Vector4(100.0f, 100.0f, 0.0f), Color(1.0f, 0.0f, 0.0f)), Vertex(Vector4(100.0f, 0.0f, 0.0f), Color(1.0f, 0.0f, 0.0f)), Vertex(Vector4(0.0f, 0.0f, 0.0f), Color(1.0f, 0.0f, 0.0f)), Vertex(Vector4(0.0f, 100.0f, 0.0f), Color(1.0f, 0.0f, 0.0f)), Vertex(Vector4(100.0f, 100.0f, 0.0f), Color(1.0f, 0.0f, 0.0f)), //Blue face Vertex(Vector4(0.0f, 0.0f, -100.0f), Color(0.0f, 0.0f, 1.0f)), Vertex(Vector4(100.0f, 100.0f, -100.0f), Color(0.0f, 0.0f, 1.0f)), Vertex(Vector4(100.0f, 0.0f, -100.0f), Color(0.0f, 0.0f, 1.0f)), Vertex(Vector4(0.0f, 0.0f, -100.0f), Color(0.0f, 0.0f, 1.0f)), Vertex(Vector4(0.0f, 100.0f, -100.0f), Color(0.0f, 0.0f, 1.0f)), Vertex(Vector4(100.0f, 100.0f, -100.0f), Color(0.0f, 0.0f, 1.0f)), };  
    • By mellinoe
      Hi all,
      First time poster here, although I've been reading posts here for quite a while. This place has been invaluable for learning graphics programming -- thanks for a great resource!
      Right now, I'm working on a graphics abstraction layer for .NET which supports D3D11, Vulkan, and OpenGL at the moment. I have implemented most of my planned features already, and things are working well. Some remaining features that I am planning are Compute Shaders, and some flavor of read-write shader resources. At the moment, my shaders can just get simple read-only access to a uniform (or constant) buffer, a texture, or a sampler. Unfortunately, I'm having a tough time grasping the distinctions between all of the different kinds of read-write resources that are available. In D3D alone, there seem to be 5 or 6 different kinds of resources with similar but different characteristics. On top of that, I get the impression that some of them are more or less "obsoleted" by the newer kinds, and don't have much of a place in modern code. There seem to be a few pivots:
      The data source/destination (buffer or texture) Read-write or read-only Structured or unstructured (?) Ordered vs unordered (?) These are just my observations based on a lot of MSDN and OpenGL doc reading. For my library, I'm not interested in exposing every possibility to the user -- just trying to find a good "middle-ground" that can be represented cleanly across API's which is good enough for common scenarios.
      Can anyone give a sort of "overview" of the different options, and perhaps compare/contrast the concepts between Direct3D, OpenGL, and Vulkan? I'd also be very interested in hearing how other folks have abstracted these concepts in their libraries.
    • By turanszkij
      If I do a buffer update with MAP_NO_OVERWRITE or MAP_DISCARD, can I just write to the buffer after I called Unmap() on the buffer? It seems to work fine for me (Nvidia driver), but is it actually legal to do so? I have a graphics device wrapper and I don't want to expose Map/Unmap, but just have a function like void* AllocateFromRingBuffer(GPUBuffer* buffer, uint size, uint& offset); This function would just call Map on the buffer, then Unmap immediately and then return the address of the buffer. It usually does a MAP_NO_OVERWRITE, but sometimes it is a WRITE_DISCARD (when the buffer wraps around). Previously I have been using it so that the function expected the data upfront and would copy to the buffer between Map/Unmap, but now I want to extend functionality of it so that it would just return an address to write to.
    • By mister345
      Trying to write a multitexturing shader in DirectX11 - 3 textures work fine, but adding 4th gets sampled as black!
      Could you please look at the textureClass.cpp line 79? - I'm guess its D3D11_TEXTURE2D_DESC settings are wrong, 
      but no idea how to set it up right. I tried changing ArraySize from 1 to 4, but does nothing. If thats not the issue, please look
      at the LightShader_ps - maybe doing something wrong there? Otherwise, no idea.
          // Setup the description of the texture.
          textureDesc.Height = height;
          textureDesc.Width = width;
          textureDesc.MipLevels = 0;
          textureDesc.ArraySize = 1;
          textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
          textureDesc.SampleDesc.Count = 1;
          textureDesc.SampleDesc.Quality = 0;
          textureDesc.Usage = D3D11_USAGE_DEFAULT;
          textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
          textureDesc.CPUAccessFlags = 0;
          textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
      Please help, thanks.
    • By GameDevCoder
      I have to learn DirectX for a course I am studying. This book I felt would be great for me to learn from.
      The trouble is the examples which are all offered here . They do not work for me. This is a known issue as there is a link on the examples page saying how to fix it. I'm having difficulty with doing this though. This is the page with the solution
      The reason why this problem is happening, the book was released before Windows 10 was released. Now when the examples are run they need slight fixes in order for them to even work. I just can't get these examples working at all.
      Would anyone be able to help me get the examples working please. I am running Windows 10 also just to make this clear, so this is why the examples are experiencing the not so desired behaviour. I just wish they would work straight away but there seems to be issues with the examples from this book mainly because of it trying to run from a Windows 10 OS.
      On top of this, if anyone has any suggestions with how I can learn DirectX 11 i would be most grateful. Thanks very much. I really would like to get them examples working to though from the book I mentioned.
      Look forward to reading any replies this thread receives.

      PS - If anyone has noticed. I asked this about 1 year ago also but this was when I was dabbling in it. Now I am actually needing to produce some stuff with DirectX so I have to get my head round this now. I felt at the time that I sort of understood what was being written to me in response to my thread back then. I had always been a little unsure though of being absolutely sure of what was happening with these troublesome examples. So I am really just trying to get to the bottom of this now. If anyone can help me work these examples out so I can see them working then hopefully I can learn DirectX 11 from them.
      *SOLUTION* - I was able to get the examples running thanks to the community. Great work guys. I'm so please now that I can learn from this book now I have the examples running.
  • Popular Now