D3D11: Implement basic framebuffer readback.
Also make debug interfaces more consistent.
This commit is contained in:
parent
522ac5c739
commit
0e8aeaea3a
21 changed files with 118 additions and 177 deletions
|
@ -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;
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue