D3D11: Implement basic framebuffer readback.

Also make debug interfaces more consistent.
This commit is contained in:
Henrik Rydgard 2017-02-14 12:42:35 +01:00
parent 522ac5c739
commit 0e8aeaea3a
21 changed files with 118 additions and 177 deletions

View file

@ -26,6 +26,8 @@
#define WRITE p+=sprintf #define WRITE p+=sprintf
// TODO: Add a compute shader path. Complete waste of time to set up a graphics state.
// Uses integer instructions available since OpenGL 3.0. Suitable for ES 3.0 as well. // Uses integer instructions available since OpenGL 3.0. Suitable for ES 3.0 as well.
void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLanguage language) { void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLanguage language) {
char *p = buffer; char *p = buffer;

View file

@ -1325,6 +1325,7 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst
} }
} }
// 1:1 pixel sides buffers, we resize buffers to these before we read them back.
VirtualFramebuffer *FramebufferManagerCommon::FindDownloadTempBuffer(VirtualFramebuffer *vfb) { VirtualFramebuffer *FramebufferManagerCommon::FindDownloadTempBuffer(VirtualFramebuffer *vfb) {
// For now we'll keep these on the same struct as the ones that can get displayed // For now we'll keep these on the same struct as the ones that can get displayed
// (and blatantly copy work already done above while at it). // (and blatantly copy work already done above while at it).

View file

@ -152,6 +152,7 @@ namespace Draw {
class DrawContext; class DrawContext;
} }
struct GPUDebugBuffer;
class TextureCacheCommon; class TextureCacheCommon;
class ShaderManagerCommon; class ShaderManagerCommon;
@ -264,6 +265,11 @@ public:
Draw::Framebuffer *GetTempFBO(u16 w, u16 h, Draw::FBColorDepth depth = Draw::FBO_8888); Draw::Framebuffer *GetTempFBO(u16 w, u16 h, Draw::FBColorDepth depth = Draw::FBO_8888);
// Debug features
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;
protected: protected:
virtual void SetViewport2D(int x, int y, int w, int h) = 0; virtual void SetViewport2D(int x, int y, int w, int h) = 0;
void CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, int renderWidth, int renderHeight, PostShaderUniforms *uniforms); void CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, int renderWidth, int renderHeight, PostShaderUniforms *uniforms);

View file

@ -105,6 +105,18 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
vb.Usage = D3D11_USAGE_DYNAMIC; vb.Usage = D3D11_USAGE_DYNAMIC;
vb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; vb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
device_->CreateBuffer(&vb, nullptr, &quadBuffer_); device_->CreateBuffer(&vb, nullptr, &quadBuffer_);
D3D11_TEXTURE2D_DESC packDesc{};
packDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
packDesc.BindFlags = 0;
packDesc.Width = 512; // 512x512 is the maximum size of a framebuffer on the PSP.
packDesc.Height = 512;
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, &packTexture_);
} }
FramebufferManagerD3D11::~FramebufferManagerD3D11() { FramebufferManagerD3D11::~FramebufferManagerD3D11() {
@ -635,7 +647,7 @@ void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 wid
return; return;
} else { } else {
for (u32 y = 0; y < height; ++y) { for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGBA8888(dst32, src32, width); memcpy(dst32, src32, width * 4);
src32 += srcStride; src32 += srcStride;
dst32 += dstStride; dst32 += dstStride;
} }
@ -646,21 +658,21 @@ void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 wid
switch (format) { switch (format) {
case GE_FORMAT_565: // BGR 565 case GE_FORMAT_565: // BGR 565
for (u32 y = 0; y < height; ++y) { for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGB565(dst16, src32, width); ConvertRGBA8888ToRGB565(dst16, src32, width);
src32 += srcStride; src32 += srcStride;
dst16 += dstStride; dst16 += dstStride;
} }
break; break;
case GE_FORMAT_5551: // ABGR 1555 case GE_FORMAT_5551: // ABGR 1555
for (u32 y = 0; y < height; ++y) { for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGBA5551(dst16, src32, width); ConvertRGBA8888ToRGBA5551(dst16, src32, width);
src32 += srcStride; src32 += srcStride;
dst16 += dstStride; dst16 += dstStride;
} }
break; break;
case GE_FORMAT_4444: // ABGR 4444 case GE_FORMAT_4444: // ABGR 4444
for (u32 y = 0; y < height; ++y) { for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGBA4444(dst16, src32, width); ConvertRGBA8888ToRGBA4444(dst16, src32, width);
src32 += srcStride; src32 += srcStride;
dst16 += dstStride; dst16 += dstStride;
} }
@ -673,6 +685,9 @@ void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 wid
} }
} }
// This function takes an already correctly-sized framebuffer and packs it into RAM.
// Does not need to account for scaling.
// Color conversion is currently done on CPU but should be done on GPU.
void FramebufferManagerD3D11::PackFramebufferD3D11_(VirtualFramebuffer *vfb, int x, int y, int w, int h) { void FramebufferManagerD3D11::PackFramebufferD3D11_(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
if (!vfb->fbo) { if (!vfb->fbo) {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferD3D11_: vfb->fbo == 0"); ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferD3D11_: vfb->fbo == 0");
@ -686,85 +701,38 @@ void FramebufferManagerD3D11::PackFramebufferD3D11_(VirtualFramebuffer *vfb, int
// We always need to convert from the framebuffer native format. // We always need to convert from the framebuffer native format.
// Right now that's always 8888. // Right now that's always 8888.
DEBUG_LOG(HLE, "Reading framebuffer to mem, fb_address = %08x", fb_address); DEBUG_LOG(HLE, "Reading framebuffer to mem, fb_address = %08x", fb_address);
ID3D11Texture2D *colorTex = (ID3D11Texture2D *)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT, 0);
/* D3D11_BOX srcBox{ 0, 0, 0, vfb->width, vfb->height, 1 };
LPDIRECT3DSURFACE9 renderTarget = (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0); context_->CopySubresourceRegion(packTexture_, 0, 0, 0, 0, colorTex, 0, &srcBox);
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
LPDIRECT3DSURFACE9 offscreen = GetOffscreenSurface(renderTarget, vfb); // Ideally, we'd round robin between two packTexture_, and simply use the other one. Though if the game
if (offscreen) { // does a once-off copy, that won't work at all.
HRESULT hr = pD3Ddevice->GetRenderTargetData(renderTarget, offscreen);
if (SUCCEEDED(hr)) { // BIG GPU STALL
D3DLOCKED_RECT locked; D3D11_MAPPED_SUBRESOURCE map;
u32 widthFactor = vfb->renderWidth / vfb->bufferWidth; HRESULT result = context_->Map(packTexture_, 0, D3D11_MAP_READ, 0, &map);
u32 heightFactor = vfb->renderHeight / vfb->bufferHeight; if (FAILED(result)) {
RECT rect = { (LONG)(x * widthFactor), (LONG)(y * heightFactor), (LONG)((x + w) * widthFactor), (LONG)((y + h) * heightFactor) }; return;
hr = offscreen->LockRect(&locked, &rect, D3DLOCK_READONLY);
if (SUCCEEDED(hr)) {
// TODO: Handle the other formats? We don't currently create them, I think.
const int dstByteOffset = (y * vfb->fb_stride + x) * dstBpp;
// Pixel size always 4 here because we always request BGRA8888.
ConvertFromRGBA8888(Memory::GetPointer(fb_address + dstByteOffset), (u8 *)locked.pBits, vfb->fb_stride, locked.Pitch / 4, w, h, vfb->format);
offscreen->UnlockRect();
} else {
ERROR_LOG_REPORT(G3D, "Unable to lock rect from %08x: %d,%d %dx%d of %dx%d", fb_address, rect.left, rect.top, rect.right, rect.bottom, vfb->renderWidth, vfb->renderHeight);
}
} else {
ERROR_LOG_REPORT(G3D, "Unable to download render target data from %08x", fb_address);
}
} }
*/
// TODO: Handle the other formats? We don't currently create them, I think.
const int srcByteOffset = y * map.RowPitch + x * 4;
const int dstByteOffset = (y * vfb->fb_stride + x) * dstBpp;
// Pixel size always 4 here because we always request BGRA8888.
ConvertFromRGBA8888(Memory::GetPointer(fb_address + dstByteOffset), (u8 *)map.pData, vfb->fb_stride, map.RowPitch/4, w, h, vfb->format);
context_->Unmap(packTexture_, 0);
} }
// Nobody calls this yet.
void FramebufferManagerD3D11::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) { void FramebufferManagerD3D11::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
if (!vfb->fbo) { if (!vfb->fbo) {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0"); ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0");
return; return;
} }
// We always read the depth buffer in 24_8 format.
const u32 z_address = (0x04000000) | vfb->z_address; const u32 z_address = (0x04000000) | vfb->z_address;
// TODO
/*
DEBUG_LOG(SCEGE, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address);
LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_DEPTH_BIT, 0);
if (tex) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
tex->GetLevelDesc(0, &desc);
RECT rect = { 0, 0, (LONG)desc.Width, (LONG)desc.Height };
HRESULT hr = tex->LockRect(0, &locked, &rect, D3DLOCK_READONLY);
if (SUCCEEDED(hr)) {
const int dstByteOffset = y * vfb->fb_stride * sizeof(s16);
const u32 *packed = (const u32 *)locked.pBits;
u16 *depth = (u16 *)Memory::GetPointer(z_address);
// TODO: Optimize.
for (int yp = 0; yp < h; ++yp) {
for (int xp = 0; xp < w; ++xp) {
const int offset = (yp + y) & vfb->z_stride + x + xp;
float scaled = FromScaledDepth((packed[offset] & 0x00FFFFFF) * (1.0f / 16777215.0f));
if (scaled <= 0.0f) {
depth[offset] = 0;
} else if (scaled >= 65535.0f) {
depth[offset] = 65535;
} else {
depth[offset] = (int)scaled;
}
}
}
tex->UnlockRect(0);
} else {
ERROR_LOG_REPORT(G3D, "Unable to lock rect from depth %08x: %d,%d %dx%d of %dx%d", vfb->fb_address, rect.left, rect.top, rect.right, rect.bottom, vfb->renderWidth, vfb->renderHeight);
}
} else {
ERROR_LOG_REPORT(G3D, "Unable to download render target depth from %08x", vfb->fb_address);
}*/
} }
void FramebufferManagerD3D11::EndFrame() { void FramebufferManagerD3D11::EndFrame() {
@ -868,18 +836,18 @@ void FramebufferManagerD3D11::Resized() {
resized_ = true; resized_ = true;
} }
bool FramebufferManagerD3D11::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) { bool FramebufferManagerD3D11::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes) {
return false;
}
bool FramebufferManagerD3D11::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) {
return false;
}
bool FramebufferManagerD3D11::GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) {
return false; return false;
} }
bool FramebufferManagerD3D11::GetOutputFramebuffer(GPUDebugBuffer &buffer) { bool FramebufferManagerD3D11::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
return false; return false;
} }
bool FramebufferManagerD3D11::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
return false;
}
bool FramebufferManagerD3D11::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
return false;
}

View file

@ -69,9 +69,9 @@ public:
virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes); bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer); bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer); bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer); bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
virtual void RebindFramebuffer() override; virtual void RebindFramebuffer() override;
@ -136,6 +136,8 @@ private:
ShaderManagerD3D11 *shaderManagerD3D11_; ShaderManagerD3D11 *shaderManagerD3D11_;
DrawEngineD3D11 *drawEngine_; DrawEngineD3D11 *drawEngine_;
ID3D11Texture2D *packTexture_;
// Used by post-processing shader // Used by post-processing shader
std::vector<Draw::Framebuffer *> extraFBOs_; std::vector<Draw::Framebuffer *> extraFBOs_;
@ -145,4 +147,4 @@ private:
AsyncPBO *pixelBufObj_; //this isn't that large AsyncPBO *pixelBufObj_; //this isn't that large
u8 currentPBO_; u8 currentPBO_;
#endif #endif
}; };

View file

@ -981,18 +981,6 @@ void GPU_D3D11::DoState(PointerWrap &p) {
} }
} }
bool GPU_D3D11::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
return framebufferManagerD3D11_->GetCurrentFramebuffer(buffer, type, maxRes);
}
bool GPU_D3D11::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
return framebufferManagerD3D11_->GetCurrentDepthbuffer(buffer);
}
bool GPU_D3D11::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
return framebufferManagerD3D11_->GetCurrentStencilbuffer(buffer);
}
bool GPU_D3D11::GetCurrentTexture(GPUDebugBuffer &buffer, int level) { bool GPU_D3D11::GetCurrentTexture(GPUDebugBuffer &buffer, int level) {
if (!gstate.isTextureMapEnabled()) { if (!gstate.isTextureMapEnabled()) {
return false; return false;

View file

@ -64,9 +64,6 @@ public:
} }
std::vector<FramebufferInfo> GetFramebufferList() override; std::vector<FramebufferInfo> GetFramebufferList() override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override; bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
bool GetCurrentClut(GPUDebugBuffer &buffer) override; bool GetCurrentClut(GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override; bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;

View file

@ -632,7 +632,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
void FramebufferManagerDX9::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) { void FramebufferManagerDX9::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) {
if (!dst->fbo || !src->fbo || !useBufferedRendering_) { if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
// This can happen if they recently switched from non-buffered. // This can happen if we recently switched from non-buffered.
draw_->BindBackbufferAsRenderTarget(); draw_->BindBackbufferAsRenderTarget();
return; return;
} }
@ -939,11 +939,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
resized_ = true; resized_ = true;
} }
bool FramebufferManagerDX9::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) { bool FramebufferManagerDX9::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat fb_format, GPUDebugBuffer &buffer, int maxRes) {
u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.getFrameBufRawAddress() : displayFramebufPtr_;
int fb_stride = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufStride() : displayStride_;
GEBufferFormat fb_format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufFormat() : displayFormat_;
VirtualFramebuffer *vfb = currentRenderVfb_; VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) { if (!vfb) {
vfb = GetVFBAt(fb_address); vfb = GetVFBAt(fb_address);
@ -1026,13 +1022,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
return success; return success;
} }
bool FramebufferManagerDX9::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) { bool FramebufferManagerDX9::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();
VirtualFramebuffer *vfb = currentRenderVfb_; VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) { if (!vfb) {
vfb = GetVFBAt(fb_address); vfb = GetVFBAt(fb_address);
@ -1070,13 +1060,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
return success; return success;
} }
bool FramebufferManagerDX9::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) { bool FramebufferManagerDX9::GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();
VirtualFramebuffer *vfb = currentRenderVfb_; VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) { if (!vfb) {
vfb = GetVFBAt(fb_address); vfb = GetVFBAt(fb_address);
@ -1084,7 +1068,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
if (!vfb) { if (!vfb) {
// If there's no vfb and we're drawing there, must be memory? // If there's no vfb and we're drawing there, must be memory?
buffer = GPUDebugBuffer(Memory::GetPointer(z_address | 0x04000000), z_stride, 512, GPU_DBG_FORMAT_16BIT); buffer = GPUDebugBuffer(Memory::GetPointer(vfb->z_address | 0x04000000), vfb->z_stride, 512, GPU_DBG_FORMAT_16BIT);
return true; return true;
} }

View file

@ -71,9 +71,9 @@ public:
virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes); bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes);
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer); bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer); bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer); bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
virtual void RebindFramebuffer() override; virtual void RebindFramebuffer() override;

View file

@ -976,18 +976,6 @@ void GPU_DX9::DoState(PointerWrap &p) {
} }
} }
bool GPU_DX9::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
return framebufferManagerDX9_->GetCurrentFramebuffer(buffer, type, maxRes);
}
bool GPU_DX9::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
return framebufferManagerDX9_->GetCurrentDepthbuffer(buffer);
}
bool GPU_DX9::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
return framebufferManagerDX9_->GetCurrentStencilbuffer(buffer);
}
bool GPU_DX9::GetCurrentTexture(GPUDebugBuffer &buffer, int level) { bool GPU_DX9::GetCurrentTexture(GPUDebugBuffer &buffer, int level) {
if (!gstate.isTextureMapEnabled()) { if (!gstate.isTextureMapEnabled()) {
return false; return false;

View file

@ -65,9 +65,6 @@ public:
} }
std::vector<FramebufferInfo> GetFramebufferList() override; std::vector<FramebufferInfo> GetFramebufferList() override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes = -1) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override; bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
bool GetCurrentClut(GPUDebugBuffer &buffer) override; bool GetCurrentClut(GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override; bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;

View file

@ -87,9 +87,9 @@ public:
bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override;
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes); 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); 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); bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer); bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
virtual void RebindFramebuffer() override; virtual void RebindFramebuffer() override;

View file

@ -1230,30 +1230,6 @@ void GPU_GLES::DoState(PointerWrap &p) {
} }
} }
bool GPU_GLES::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.getFrameBufRawAddress() : framebufferManagerGL_->DisplayFramebufAddr();
int fb_stride = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufStride() : framebufferManagerGL_->DisplayFramebufStride();
GEBufferFormat format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufFormat() : framebufferManagerGL_->DisplayFramebufFormat();
return framebufferManagerGL_->GetFramebuffer(fb_address, fb_stride, format, buffer, maxRes);
}
bool GPU_GLES::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();
return framebufferManagerGL_->GetDepthbuffer(fb_address, fb_stride, z_address, z_stride, buffer);
}
bool GPU_GLES::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
return framebufferManagerGL_->GetStencilbuffer(fb_address, fb_stride, buffer);
}
bool GPU_GLES::GetCurrentTexture(GPUDebugBuffer &buffer, int level) { bool GPU_GLES::GetCurrentTexture(GPUDebugBuffer &buffer, int level) {
if (!gstate.isTextureMapEnabled()) { if (!gstate.isTextureMapEnabled()) {
return false; return false;

View file

@ -67,9 +67,6 @@ public:
} }
std::vector<FramebufferInfo> GetFramebufferList() override; std::vector<FramebufferInfo> GetFramebufferList() override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override; bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) override;
bool GetCurrentClut(GPUDebugBuffer &buffer) override; bool GetCurrentClut(GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override; bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;

View file

@ -2116,3 +2116,27 @@ bool GPUCommon::PerformStencilUpload(u32 dest, int size) {
void GPUCommon::PerformStencilUploadInternal(u32 dest, int size) { void GPUCommon::PerformStencilUploadInternal(u32 dest, int size) {
framebufferManager_->NotifyStencilUpload(dest, size); framebufferManager_->NotifyStencilUpload(dest, size);
} }
bool GPUCommon::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.getFrameBufRawAddress() : framebufferManager_->DisplayFramebufAddr();
int fb_stride = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufStride() : framebufferManager_->DisplayFramebufStride();
GEBufferFormat format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufFormat() : framebufferManager_->DisplayFramebufFormat();
return framebufferManager_->GetFramebuffer(fb_address, fb_stride, format, buffer, maxRes);
}
bool GPUCommon::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();
return framebufferManager_->GetDepthbuffer(fb_address, fb_stride, z_address, z_stride, buffer);
}
bool GPUCommon::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
return framebufferManager_->GetStencilbuffer(fb_address, fb_stride, buffer);
}

View file

@ -162,6 +162,10 @@ public:
// From GPUDebugInterface. // From GPUDebugInterface.
bool GetCurrentDisplayList(DisplayList &list) override; bool GetCurrentDisplayList(DisplayList &list) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) override;
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) override;
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) override;
std::vector<DisplayList> ActiveDisplayLists() override; std::vector<DisplayList> ActiveDisplayLists() override;
void ResetListPC(int listID, u32 pc) override; void ResetListPC(int listID, u32 pc) override;
void ResetListStall(int listID, u32 stall) override; void ResetListStall(int listID, u32 stall) override;

View file

@ -838,8 +838,7 @@ bool SoftGPU::FramebufferDirty() {
return true; return true;
} }
bool SoftGPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) bool SoftGPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
{
int x1 = gstate.getRegionX1(); int x1 = gstate.getRegionX1();
int y1 = gstate.getRegionY1(); int y1 = gstate.getRegionY1();
int x2 = gstate.getRegionX2() + 1; int x2 = gstate.getRegionX2() + 1;

View file

@ -1166,7 +1166,7 @@ void FramebufferManagerVulkan::Resized() {
resized_ = true; resized_ = true;
} }
bool FramebufferManagerVulkan::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer) { bool FramebufferManagerVulkan::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxStride) {
// TODO: Doing this synchronously will require stalling the pipeline. Maybe better // TODO: Doing this synchronously will require stalling the pipeline. Maybe better
// to do it callback-style? // to do it callback-style?
/* /*

View file

@ -100,9 +100,9 @@ public:
bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override;
bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer); 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); 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); bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
static bool GetOutputFramebuffer(GPUDebugBuffer &buffer); static bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
virtual void RebindFramebuffer() override; virtual void RebindFramebuffer() override;

View file

@ -328,6 +328,7 @@ enum FBChannel {
// Implementation specific // Implementation specific
FB_SURFACE_BIT = 32, // Used in conjunction with the others in D3D9 to get surfaces through get_api_texture FB_SURFACE_BIT = 32, // Used in conjunction with the others in D3D9 to get surfaces through get_api_texture
FB_VIEW_BIT = 64, // Used in conjunction with the others in D3D11 to get shader resource views through get_api_texture
}; };
enum FBBlitFilter { enum FBBlitFilter {

View file

@ -1060,7 +1060,7 @@ Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
descColor.Height = desc.height; descColor.Height = desc.height;
descColor.MipLevels = 1; descColor.MipLevels = 1;
descColor.ArraySize = 1; descColor.ArraySize = 1;
descColor.Format = DXGI_FORMAT_B8G8R8A8_UNORM; descColor.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
descColor.SampleDesc.Count = 1; descColor.SampleDesc.Count = 1;
descColor.SampleDesc.Quality = 0; descColor.SampleDesc.Quality = 0;
descColor.Usage = D3D11_USAGE_DEFAULT; descColor.Usage = D3D11_USAGE_DEFAULT;
@ -1213,8 +1213,15 @@ void D3D11DrawContext::BindBackbufferAsRenderTarget() {
} }
uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) { uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) {
// D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo; D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
return 0; switch (channelBit) {
case FB_COLOR_BIT: return (uintptr_t)fb->colorTex;
case FB_DEPTH_BIT: return (uintptr_t)fb->depthStencilTex;
case FB_COLOR_BIT | FB_VIEW_BIT: return (uintptr_t)fb->colorRTView;
case FB_DEPTH_BIT | FB_VIEW_BIT: return (uintptr_t)fb->depthStencilRTView;
default:
return 0;
}
} }
void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) { void D3D11DrawContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {