Add an interface to grab the depth/stencil buffers.

Not sure yet how to show in UI, not well tested...
This commit is contained in:
Unknown W. Brackets 2013-09-28 02:14:27 -07:00
parent 086294b495
commit 14efcbcc9b
6 changed files with 114 additions and 5 deletions

View file

@ -30,11 +30,28 @@ struct GPUDebugOp {
std::string desc;
};
enum GPUDebugBufferFormat {
// These match GEBufferFormat.
GPU_DBG_FORMAT_565 = 0,
GPU_DBG_FORMAT_5551 = 1,
GPU_DBG_FORMAT_4444 = 2,
GPU_DBG_FORMAT_8888 = 3,
GPU_DBG_FORMAT_INVALID = 0xFF,
// These don't, they're for depth buffers.
GPU_DBG_FORMAT_FLOAT = 0x10,
GPU_DBG_FORMAT_16BIT = 0x11,
};
struct GPUDebugBuffer {
GPUDebugBuffer() : alloc_(false), data_(NULL) {
}
GPUDebugBuffer(void *data, u32 stride, u32 height, GEBufferFormat fmt)
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(GPUDebugBufferFormat(fmt)), flipped_(false) {
}
GPUDebugBuffer(void *data, u32 stride, u32 height, GPUDebugBufferFormat fmt)
: alloc_(false), data_((u8 *)data), stride_(stride), height_(height), fmt_(fmt), flipped_(false) {
}
@ -70,6 +87,10 @@ struct GPUDebugBuffer {
}
void Allocate(u32 stride, u32 height, GEBufferFormat fmt, bool flipped = false) {
Allocate(stride, height, GPUDebugBufferFormat(fmt), flipped);
}
void Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt, bool flipped = false) {
if (alloc_ && stride_ == stride && height_ == height && fmt_ == fmt) {
// Already allocated the right size.
flipped_ = flipped;
@ -84,7 +105,7 @@ struct GPUDebugBuffer {
flipped_ = flipped;
u32 pixelSize = 2;
if (fmt == GE_FORMAT_8888) {
if (fmt == GPU_DBG_FORMAT_8888 || fmt == GPU_DBG_FORMAT_FLOAT) {
pixelSize = 4;
};
@ -114,7 +135,7 @@ struct GPUDebugBuffer {
return flipped_;
}
GEBufferFormat GetFormat() const {
GPUDebugBufferFormat GetFormat() const {
return fmt_;
}
@ -124,7 +145,7 @@ private:
u32 height_;
u32 stride_;
bool flipped_;
GEBufferFormat fmt_;
GPUDebugBufferFormat fmt_;
};
class GPUDebugInterface {
@ -153,6 +174,16 @@ public:
return false;
}
// Similar to GetCurrentFramebuffer().
virtual bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
return false;
}
// Similar to GetCurrentFramebuffer().
virtual bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
return false;
}
// Similar to GetCurrentFramebuffer().
virtual bool GetCurrentTexture(GPUDebugBuffer &buffer) {
return false;

View file

@ -1342,8 +1342,7 @@ void FramebufferManager::Resized() {
resized_ = true;
}
bool FramebufferManager::GetCurrentFramebuffer(GPUDebugBuffer &buffer)
{
bool FramebufferManager::GetCurrentFramebuffer(GPUDebugBuffer &buffer) {
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
int fb_stride = gstate.fbwidth & 0x3C0;
@ -1366,3 +1365,62 @@ bool FramebufferManager::GetCurrentFramebuffer(GPUDebugBuffer &buffer)
return true;
}
bool FramebufferManager::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
int fb_stride = gstate.fbwidth & 0x3C0;
u32 z_address = (gstate.zbptr & 0xFFFFFF) | ((gstate.zbwidth & 0xFF0000) << 8);
int z_stride = gstate.zbwidth & 0x3C0;
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(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT);
return true;
}
#ifndef USING_GLES2
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_FLOAT, true);
fbo_bind_for_read(vfb->fbo);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(0, 0, vfb->renderWidth, vfb->renderHeight, GL_DEPTH_COMPONENT, GL_FLOAT, buffer.GetData());
return true;
#else
return false;
#endif
}
bool FramebufferManager::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
int fb_stride = gstate.fbwidth & 0x3C0;
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), fb_stride, 512, GPU_DBG_FORMAT_8888);
return true;
}
#ifndef USING_GLES2
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_16BIT, true);
fbo_bind_for_read(vfb->fbo);
glPixelStorei(GL_PACK_ALIGNMENT, 2);
glReadPixels(0, 0, vfb->renderWidth, vfb->renderHeight, GL_STENCIL_INDEX, GL_UNSIGNED_SHORT, buffer.GetData());
return true;
#else
return false;
#endif
}

View file

@ -171,6 +171,8 @@ public:
void DestroyFramebuf(VirtualFramebuffer *vfb);
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer);
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
private:
void CompileDraw2DProgram();

View file

@ -1519,6 +1519,14 @@ bool GLES_GPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer) {
return framebufferManager_.GetCurrentFramebuffer(buffer);
}
bool GLES_GPU::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
return framebufferManager_.GetCurrentDepthbuffer(buffer);
}
bool GLES_GPU::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
return framebufferManager_.GetCurrentStencilbuffer(buffer);
}
bool GLES_GPU::GetCurrentTexture(GPUDebugBuffer &buffer) {
if (!gstate.isTextureMapEnabled()) {
return false;

View file

@ -67,6 +67,8 @@ public:
std::vector<FramebufferInfo> GetFramebufferList();
bool GetCurrentFramebuffer(GPUDebugBuffer &buffer);
bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer);
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
bool GetCurrentTexture(GPUDebugBuffer &buffer);
protected:

View file

@ -78,6 +78,14 @@ public:
// TODO
return false;
}
virtual bool GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
// TODO
return false;
}
virtual bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
// TODO
return false;
}
protected:
virtual void FastRunLoop(DisplayList &list);