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
// 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.
void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLanguage language) {
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) {
// 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).

View file

@ -152,6 +152,7 @@ namespace Draw {
class DrawContext;
}
struct GPUDebugBuffer;
class TextureCacheCommon;
class ShaderManagerCommon;
@ -264,6 +265,11 @@ public:
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:
virtual void SetViewport2D(int x, int y, int w, int h) = 0;
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.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
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() {
@ -635,7 +647,7 @@ void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 wid
return;
} else {
for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGBA8888(dst32, src32, width);
memcpy(dst32, src32, width * 4);
src32 += srcStride;
dst32 += dstStride;
}
@ -646,21 +658,21 @@ void ConvertFromRGBA8888(u8 *dst, u8 *src, u32 dstStride, u32 srcStride, u32 wid
switch (format) {
case GE_FORMAT_565: // BGR 565
for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGB565(dst16, src32, width);
ConvertRGBA8888ToRGB565(dst16, src32, width);
src32 += srcStride;
dst16 += dstStride;
}
break;
case GE_FORMAT_5551: // ABGR 1555
for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGBA5551(dst16, src32, width);
ConvertRGBA8888ToRGBA5551(dst16, src32, width);
src32 += srcStride;
dst16 += dstStride;
}
break;
case GE_FORMAT_4444: // ABGR 4444
for (u32 y = 0; y < height; ++y) {
ConvertBGRA8888ToRGBA4444(dst16, src32, width);
ConvertRGBA8888ToRGBA4444(dst16, src32, width);
src32 += srcStride;
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) {
if (!vfb->fbo) {
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.
// Right now that's always 8888.
DEBUG_LOG(HLE, "Reading framebuffer to mem, fb_address = %08x", fb_address);
ID3D11Texture2D *colorTex = (ID3D11Texture2D *)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT, 0);
/*
LPDIRECT3DSURFACE9 renderTarget = (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0);
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
D3D11_BOX srcBox{ 0, 0, 0, vfb->width, vfb->height, 1 };
context_->CopySubresourceRegion(packTexture_, 0, 0, 0, 0, colorTex, 0, &srcBox);
// Ideally, we'd round robin between two packTexture_, and simply use the other one. Though if the game
// does a once-off copy, that won't work at all.
// BIG GPU STALL
D3D11_MAPPED_SUBRESOURCE map;
HRESULT result = context_->Map(packTexture_, 0, D3D11_MAP_READ, 0, &map);
if (FAILED(result)) {
return;
}
LPDIRECT3DSURFACE9 offscreen = GetOffscreenSurface(renderTarget, vfb);
if (offscreen) {
HRESULT hr = pD3Ddevice->GetRenderTargetData(renderTarget, offscreen);
if (SUCCEEDED(hr)) {
D3DLOCKED_RECT locked;
u32 widthFactor = vfb->renderWidth / vfb->bufferWidth;
u32 heightFactor = vfb->renderHeight / vfb->bufferHeight;
RECT rect = { (LONG)(x * widthFactor), (LONG)(y * heightFactor), (LONG)((x + w) * widthFactor), (LONG)((y + h) * heightFactor) };
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 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 *)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);
}
}
*/
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) {
if (!vfb->fbo) {
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0");
return;
}
// We always read the depth buffer in 24_8 format.
const u32 z_address = (0x04000000) | vfb->z_address;
/*
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);
}*/
// TODO
}
void FramebufferManagerD3D11::EndFrame() {
@ -868,18 +836,18 @@ void FramebufferManagerD3D11::Resized() {
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;
}
bool FramebufferManagerD3D11::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
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;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes);
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
bool GetCurrentStencilbuffer(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) override;
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
virtual void RebindFramebuffer() override;
@ -136,6 +136,8 @@ private:
ShaderManagerD3D11 *shaderManagerD3D11_;
DrawEngineD3D11 *drawEngine_;
ID3D11Texture2D *packTexture_;
// Used by post-processing shader
std::vector<Draw::Framebuffer *> extraFBOs_;

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) {
if (!gstate.isTextureMapEnabled()) {
return false;

View file

@ -64,9 +64,6 @@ public:
}
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 GetCurrentClut(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) {
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();
return;
}
@ -939,11 +939,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
resized_ = true;
}
bool FramebufferManagerDX9::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, 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_;
bool FramebufferManagerDX9::GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat fb_format, GPUDebugBuffer &buffer, int maxRes) {
VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) {
vfb = GetVFBAt(fb_address);
@ -1026,13 +1022,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
return success;
}
bool FramebufferManagerDX9::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();
bool FramebufferManagerDX9::GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) {
VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) {
vfb = GetVFBAt(fb_address);
@ -1070,13 +1060,7 @@ static void DXSetViewport(float x, float y, float w, float h, float minZ, float
return success;
}
bool FramebufferManagerDX9::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = gstate.getFrameBufRawAddress();
int fb_stride = gstate.FrameBufStride();
u32 z_address = gstate.getDepthBufRawAddress();
int z_stride = gstate.DepthBufStride();
bool FramebufferManagerDX9::GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) {
VirtualFramebuffer *vfb = currentRenderVfb_;
if (!vfb) {
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 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;
}

View file

@ -71,9 +71,9 @@ public:
virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override;
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes);
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
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);
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) {
if (!gstate.isTextureMapEnabled()) {
return false;

View file

@ -65,9 +65,6 @@ public:
}
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 GetCurrentClut(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 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);
bool GetStencilbuffer(u32 fb_address, int fb_stride, 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) override;
bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer) override;
bool GetOutputFramebuffer(GPUDebugBuffer &buffer);
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) {
if (!gstate.isTextureMapEnabled()) {
return false;

View file

@ -67,9 +67,6 @@ public:
}
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 GetCurrentClut(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) {
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.
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;
void ResetListPC(int listID, u32 pc) override;
void ResetListStall(int listID, u32 stall) override;

View file

@ -838,8 +838,7 @@ bool SoftGPU::FramebufferDirty() {
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 y1 = gstate.getRegionY1();
int x2 = gstate.getRegionX2() + 1;

View file

@ -1166,7 +1166,7 @@ void FramebufferManagerVulkan::Resized() {
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
// to do it callback-style?
/*

View file

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

View file

@ -328,6 +328,7 @@ enum FBChannel {
// Implementation specific
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 {

View file

@ -1060,7 +1060,7 @@ Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
descColor.Height = desc.height;
descColor.MipLevels = 1;
descColor.ArraySize = 1;
descColor.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
descColor.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
descColor.SampleDesc.Count = 1;
descColor.SampleDesc.Quality = 0;
descColor.Usage = D3D11_USAGE_DEFAULT;
@ -1213,8 +1213,15 @@ void D3D11DrawContext::BindBackbufferAsRenderTarget() {
}
uintptr_t D3D11DrawContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) {
// D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo;
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) {