mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
D3D11: Add enough debug readback support to support savestate thumbnails
This commit is contained in:
parent
0e8aeaea3a
commit
68ba3070bc
12 changed files with 72 additions and 20 deletions
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue