mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-18 18:26:27 +01:00
Merge pull request #3861 from stenzek/d3d11-mip-dumping
D3D11: Support texture dumping of non-zero mipmap levels
This commit is contained in:
commit
c6a0e543a5
@ -2,6 +2,7 @@
|
|||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "VideoBackends/D3D/D3DBase.h"
|
#include "VideoBackends/D3D/D3DBase.h"
|
||||||
@ -38,43 +39,41 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
|||||||
|
|
||||||
bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
|
bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
|
||||||
{
|
{
|
||||||
// TODO: Somehow implement this (D3DX11 doesn't support dumping individual LODs)
|
// Create a staging/readback texture with the dimensions of the specified mip level.
|
||||||
static bool warn_once = true;
|
u32 mip_width = std::max(config.width >> level, 1u);
|
||||||
if (level && warn_once)
|
u32 mip_height = std::max(config.height >> level, 1u);
|
||||||
|
CD3D11_TEXTURE2D_DESC staging_texture_desc(DXGI_FORMAT_R8G8B8A8_UNORM, mip_width, mip_height, 1,
|
||||||
|
1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ);
|
||||||
|
|
||||||
|
ID3D11Texture2D* staging_texture;
|
||||||
|
HRESULT hr = D3D::device->CreateTexture2D(&staging_texture_desc, nullptr, &staging_texture);
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Dumping individual LOD not supported by D3D11 backend!");
|
WARN_LOG(VIDEO, "Failed to create texture dumping readback texture: %X", static_cast<u32>(hr));
|
||||||
warn_once = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11Texture2D* pNewTexture = nullptr;
|
// Copy the selected mip level to the staging texture.
|
||||||
ID3D11Texture2D* pSurface = texture->GetTex();
|
CD3D11_BOX src_box(0, 0, 0, mip_width, mip_height, 1);
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D::context->CopySubresourceRegion(staging_texture, 0, 0, 0, 0, texture->GetTex(),
|
||||||
pSurface->GetDesc(&desc);
|
D3D11CalcSubresource(level, 0, config.levels), &src_box);
|
||||||
|
|
||||||
desc.BindFlags = 0;
|
// Map the staging texture to client memory, and encode it as a .png image.
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
desc.Usage = D3D11_USAGE_STAGING;
|
hr = D3D::context->Map(staging_texture, 0, D3D11_MAP_READ, 0, &map);
|
||||||
|
if (FAILED(hr))
|
||||||
HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &pNewTexture);
|
|
||||||
|
|
||||||
bool saved_png = false;
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr) && pNewTexture)
|
|
||||||
{
|
{
|
||||||
D3D::context->CopyResource(pNewTexture, pSurface);
|
WARN_LOG(VIDEO, "Failed to map texture dumping readback texture: %X", static_cast<u32>(hr));
|
||||||
|
staging_texture->Release();
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
return false;
|
||||||
hr = D3D::context->Map(pNewTexture, 0, D3D11_MAP_READ_WRITE, 0, &map);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
saved_png = TextureToPng((u8*)map.pData, map.RowPitch, filename, desc.Width, desc.Height);
|
|
||||||
D3D::context->Unmap(pNewTexture, 0);
|
|
||||||
}
|
|
||||||
SAFE_RELEASE(pNewTexture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return saved_png;
|
bool encode_result =
|
||||||
|
TextureToPng(reinterpret_cast<u8*>(map.pData), map.RowPitch, filename, mip_width, mip_height);
|
||||||
|
D3D::context->Unmap(staging_texture, 0);
|
||||||
|
staging_texture->Release();
|
||||||
|
|
||||||
|
return encode_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase* source,
|
void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase* source,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user