D3D11: Add enough debug readback support to support savestate thumbnails

This commit is contained in:
Henrik Rydgard 2017-02-18 00:27:32 +01:00
parent 0e8aeaea3a
commit 68ba3070bc
12 changed files with 72 additions and 20 deletions

View file

@ -269,6 +269,7 @@ public:
virtual bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes) = 0;
virtual bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) = 0;
virtual bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) = 0;
virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer) = 0;
protected:
virtual void SetViewport2D(int x, int y, int w, int h) = 0;

View file

@ -120,6 +120,7 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
}
FramebufferManagerD3D11::~FramebufferManagerD3D11() {
packTexture_->Release();
// Drawing cleanup
if (quadVertexShader_)
quadVertexShader_->Release();
@ -836,8 +837,71 @@ void FramebufferManagerD3D11::Resized() {
resized_ = true;
}
// Lots of this code could be shared (like the downsampling).
bool FramebufferManagerD3D11::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes) {
return false;
VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) {
vfb = GetVFBAt(fb_address);
}
if (!vfb) {
// If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, format);
return true;
}
int w = vfb->renderWidth, h = vfb->renderHeight;
Draw::Framebuffer *fboForRead = nullptr;
if (vfb->fbo) {
if (maxRes > 0 && vfb->renderWidth > vfb->width * maxRes) {
w = vfb->width * maxRes;
h = vfb->height * maxRes;
Draw::Framebuffer *tempFBO = GetTempFBO(w, h);
VirtualFramebuffer tempVfb = *vfb;
tempVfb.fbo = tempFBO;
tempVfb.bufferWidth = vfb->width;
tempVfb.bufferHeight = vfb->height;
tempVfb.renderWidth = w;
tempVfb.renderHeight = h;
BlitFramebuffer(&tempVfb, 0, 0, vfb, 0, 0, vfb->width, vfb->height, 0);
fboForRead = tempFBO;
} else {
fboForRead = vfb->fbo;
}
}
buffer.Allocate(w, h, GE_FORMAT_8888, !useBufferedRendering_, true);
ID3D11Texture2D *packTex;
D3D11_TEXTURE2D_DESC packDesc{};
packDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
packDesc.BindFlags = 0;
packDesc.Width = w;
packDesc.Height = h;
packDesc.ArraySize = 1;
packDesc.MipLevels = 1;
packDesc.Usage = D3D11_USAGE_STAGING;
packDesc.SampleDesc.Count = 1;
packDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
device_->CreateTexture2D(&packDesc, nullptr, &packTex);
ID3D11Texture2D *nativeTex = (ID3D11Texture2D *)draw_->GetFramebufferAPITexture(fboForRead, Draw::FB_COLOR_BIT, 0);
context_->CopyResource(packTex, nativeTex);
D3D11_MAPPED_SUBRESOURCE map;
context_->Map(packTex, 0, D3D11_MAP_READ, 0, &map);
for (int y = 0; y < h; y++) {
uint8_t *dest = (uint8_t *)buffer.GetData() + y * w * 4;
const uint8_t *src = ((const uint8_t *)map.pData) + map.RowPitch * y;
memcpy(dest, src, 4 * w);
}
context_->Unmap(packTex, 0);
packTex->Release();
return true;
}
bool FramebufferManagerD3D11::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) {

View file

@ -72,7 +72,7 @@ public:
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes) override;
bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) override;
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
virtual void RebindFramebuffer() override;
@ -136,6 +136,8 @@ private:
ShaderManagerD3D11 *shaderManagerD3D11_;
DrawEngineD3D11 *drawEngine_;
// 1:1 Readback texture, 512x512 fixed
// For larger debug readbacks, we create/destroy textures on the fly.
ID3D11Texture2D *packTexture_;
// Used by post-processing shader

View file

@ -995,10 +995,6 @@ bool GPU_D3D11::GetCurrentClut(GPUDebugBuffer &buffer) {
return textureCacheD3D11_->GetCurrentClutBuffer(buffer);
}
bool GPU_D3D11::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
return framebufferManagerD3D11_->GetOutputFramebuffer(buffer);
}
bool GPU_D3D11::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
return drawEngine_.GetCurrentSimpleVertices(count, vertices, indices);
}

View file

@ -66,7 +66,6 @@ public:
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
bool GetCurrentClut(GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) override;
typedef void (GPU_D3D11::*CmdFunc)(u32 op, u32 diff);

View file

@ -74,7 +74,7 @@ public:
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes);
bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) override;
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
virtual void RebindFramebuffer() override;

View file

@ -1069,10 +1069,6 @@ bool GPU_DX9::GetCurrentClut(GPUDebugBuffer &buffer) {
return textureCacheDX9_->GetCurrentClutBuffer(buffer);
}
bool GPU_DX9::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
return framebufferManagerDX9_->GetOutputFramebuffer(buffer);
}
bool GPU_DX9::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
return drawEngine_.GetCurrentSimpleVertices(count, vertices, indices);
}

View file

@ -67,7 +67,6 @@ public:
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
bool GetCurrentClut(GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) override;
typedef void (GPU_DX9::*CmdFunc)(u32 op, u32 diff);

View file

@ -90,7 +90,7 @@ public:
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes) override;
bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) override;
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
virtual void RebindFramebuffer() override;

View file

@ -1271,10 +1271,6 @@ bool GPU_GLES::GetCurrentClut(GPUDebugBuffer &buffer) {
return textureCacheGL_->GetCurrentClutBuffer(buffer);
}
bool GPU_GLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
return framebufferManagerGL_->GetOutputFramebuffer(buffer);
}
bool GPU_GLES::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
return drawEngine_.GetCurrentSimpleVertices(count, vertices, indices);
}

View file

@ -69,7 +69,6 @@ public:
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
bool GetCurrentClut(GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) override;
bool DescribeCodePtr(const u8 *ptr, std::string &name) override;

View file

@ -103,7 +103,7 @@ public:
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes) override;
bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) override;
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
static bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
virtual void RebindFramebuffer() override;