I am trying to send video data from Dolphin Emulator to another process. To do so, I first get a reference to the back buffer from the swap chain.
// in file: D3DGfx.cpp
// in function: void Gfx::PresentBackBuffer()
HRESULT hr = m_swap_chain->GetDXGISwapChain()->GetBuffer(
0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(back_buffer.GetAddressOf()));
I then create a shared texture and do a GPU -> GPU copy so I can modify the texture later.
D3D11_TEXTURE2D_DESC desc;
ComPtr<ID3D11Texture2D> shared_texture;
back_buffer->GetDesc(&desc);
desc.BindFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
hr = D3D::device->CreateTexture2D(&desc, nullptr, shared_texture.GetAddressOf());
D3D::context->CopyResource(shared_texture.Get(), back_buffer.Get());
Then, I create a shared handle, and map it to shared memory with my other process for reading.
hr = shared_texture.As(&dxgi_resource);
hr = dxgi_resource->GetSharedHandle(&shared_handle);
void* pMappedMem = MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0,
32); // map 32 bytes into the virtual address space
struct SharedTextureData sd;
sd.handle = shared_handle;
sd.width = width;
sd.height = height;
if (pMappedMem)
{
std::memcpy(pMappedMem, &sd, sizeof(SharedTextureData));
UnmapViewOfFile(pMappedMem);
}
However, before sharing the texture, I wanted to debug the texture to make sure I was sending the proper data. So I created a staging texture, mapped the resource, and saved to png to view the texture.
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; // Allow CPU read access
desc.Usage = D3D11_USAGE_STAGING;
ComPtr<ID3D11Texture2D> staging_texture;
hr = D3D::device->CreateTexture2D(&desc, nullptr, staging_texture.GetAddressOf());
D3D::context->CopyResource(staging_texture.Get(), shared_texture.Get());
D3D11_MAPPED_SUBRESOURCE mappedResource;
hr = D3D::context->Map(stagingTexture.Get(), 0, D3D11_MAP_READ, 0, &mappedResource);
BYTE* data = reinterpret_cast<BYTE*>(mappedResource.pData);
UINT rowPitch = mappedResource.RowPitch;
//save to png
stbi_write_png("output.png", width, height, 4, data, rowPitch);
This is the texture that was saved.

For reference, this is what the texture looks like after being drawn to the screen by Dolphin Emulator.

Things I have tried to resolve this issue but did not change anything or made it worse:
Ensure that the format is correct (DXGI_FORMAT_R10G10B10A2_UNORM)
Adjust the format to be PNG-compatible:
for (UINT i = 0; i < desc.Height; ++i) { for (UINT j = 0; j < mappedResource.RowPitch; j += 4) { UINT offset = (i * desc.Width + j); data[offset] = (data[offset] >> 2) & 0x3F; data[offset + 1] = (data[offset] >> 2) & 0x3F; data[offset + 2] = (data[offset] >> 2) & 0x3F; data[offset + 3] = (data[offset] >> 2) & 0x3F; } }Resolve the texture to a single sample (if it was multi-sampled) before copying to the staging texture
desc.Usage = D3D11_USAGE_DEFAULT; desc.SampleDesc.Count = 1; // Resolve to a single sample desc.SampleDesc.Quality = 0; ComPtr<ID3D11Texture2D> resolvedTexture; hr = D3D::device->CreateTexture2D(&desc, nullptr, resolvedTexture.GetAddressOf()); D3D::context->CopyResource(resolvedTexture.Get(), backBuffer.Get()); D3D::context->ResolveSubresource(resolvedTexture.Get(), 0, backBuffer.Get(), 0, desc.Format);
If anyone could identify what the cause of the distortion might be, or suggest a better technique or a different approach entirely, I would greatly appreciate it.
