Skip to content

Instantly share code, notes, and snippets.

@iondune
Created June 24, 2018 19:57
Show Gist options
  • Save iondune/1c8197083408f377d9f2494d3dcd6523 to your computer and use it in GitHub Desktop.
Save iondune/1c8197083408f377d9f2494d3dcd6523 to your computer and use it in GitHub Desktop.
Copy texture data from gpu to cpu with Direct3D 11
int const Width = 16;
int const Height = 16;
/////////////////////
// Create Textures //
/////////////////////
ID3D11Texture2D * Texture = nullptr;
ID3D11Texture2D * Staging = nullptr;
D3D11_TEXTURE2D_DESC TexDesc;
TexDesc.Width = Width;
TexDesc.Height = Height;
TexDesc.MipLevels = 0;
TexDesc.ArraySize = 1;
TexDesc.Format = DXGI_FORMAT_R32_FLOAT;
TexDesc.SampleDesc.Count = 1;
TexDesc.SampleDesc.Quality = 0;
TexDesc.BindFlags = 0;
TexDesc.MiscFlags = 0;
TexDesc.Usage = D3D11_USAGE_DEFAULT;
TexDesc.CPUAccessFlags = 0;
Device->CreateTexture2D(& TexDesc, NULL, & Texture);
TexDesc.Usage = D3D11_USAGE_STAGING;
TexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
Device->CreateTexture2D(& TexDesc, NULL, & Staging);
/////////////////
// Upload Data //
/////////////////
FLOAT * Data = new FLOAT[Width * Height]();
for (int i = 0; i < Width; ++ i)
{
for (int j = 0; j < Height; ++ j)
{
Data[i + j * Width] = (float) i + (float) j / 1000.f;
}
}
UINT const DataSize = sizeof(FLOAT);
UINT const RowPitch = DataSize * Width;
UINT const DepthPitch = DataSize * Width * Height;
D3D11_BOX Box;
Box.left = 0;
Box.right = Width;
Box.top = 0;
Box.bottom = Height;
Box.front = 0;
Box.back = 1;
ImmediateContext->UpdateSubresource(Texture, 0, & Box, Data, RowPitch, DepthPitch);
delete[] Data;
///////////////////
// Download Data //
///////////////////
ImmediateContext->CopyResource(Staging, Texture);
FLOAT * Read = new FLOAT[Width * Height]();
for (int i = 0; i < Width; ++ i)
{
for (int j = 0; j < Height; ++ j)
{
Read[i + j * Width] = -1.f;
}
}
D3D11_MAPPED_SUBRESOURCE ResourceDesc = {};
ImmediateContext->Map(Staging, 0, D3D11_MAP_READ, 0, & ResourceDesc);
if (ResourceDesc.pData)
{
int const BytesPerPixel = sizeof(FLOAT);
for (int i = 0; i < Height; ++ i)
{
std::memcpy(
(byte *) Read + Width * BytesPerPixel * i,
(byte *) ResourceDesc.pData + ResourceDesc.RowPitch * i,
Width * BytesPerPixel);
}
}
ImmediateContext->Unmap(Staging, 0);
for (int i = 0; i < Width; ++ i)
{
for (int j = 0; j < Height; ++ j)
{
printf("[%d, %d] = { %.6f }\n", i, j, Read[i + j * Width]);
}
}
delete[] Read;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment