mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add methods to download depth to PSP RAM.
This commit is contained in:
parent
2916298695
commit
0443fbebd0
5 changed files with 108 additions and 13 deletions
|
@ -310,6 +310,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
|||
vfb->fb_stride = params.fb_stride;
|
||||
vfb->format = params.fmt;
|
||||
}
|
||||
// Keep track, but this isn't really used.
|
||||
vfb->z_stride = params.z_stride;
|
||||
// Heuristic: In throughmode, a higher height could be used. Let's avoid shrinking the buffer.
|
||||
if (params.isModeThrough && (int)vfb->width < params.fb_stride) {
|
||||
vfb->width = std::max((int)vfb->width, drawing_width);
|
||||
|
|
|
@ -1055,6 +1055,55 @@ namespace DX9 {
|
|||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::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 = fbo_get_depth_texture(vfb->fbo_dx9);
|
||||
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 FramebufferManagerDX9::EndFrame() {
|
||||
if (resized_) {
|
||||
DestroyAllFBOs();
|
||||
|
|
|
@ -115,6 +115,7 @@ private:
|
|||
void SetNumExtraFBOs(int num);
|
||||
|
||||
void PackFramebufferDirectx9_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
static bool GetRenderTargetFramebuffer(LPDIRECT3DSURFACE9 renderTarget, LPDIRECT3DSURFACE9 offscreen, int w, int h, GPUDebugBuffer &buffer);
|
||||
|
||||
// Used by DrawPixels
|
||||
|
|
|
@ -1676,30 +1676,30 @@ void FramebufferManager::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, in
|
|||
}
|
||||
|
||||
// Pixel size always 4 here because we always request RGBA8888
|
||||
size_t bufSize = vfb->fb_stride * std::max(vfb->height, (u16)h) * 4;
|
||||
u32 bufSize = vfb->fb_stride * (h - y) * 4;
|
||||
u32 fb_address = (0x04000000) | vfb->fb_address;
|
||||
|
||||
GLubyte *packed = 0;
|
||||
|
||||
bool convert = vfb->format != GE_FORMAT_8888 || UseBGRA8888();
|
||||
const int dstBpp = vfb->format == GE_FORMAT_8888 ? 4 : 2;
|
||||
const int packWidth = x + w < vfb->width ? x + w : vfb->width;
|
||||
const int packWidth = std::min(vfb->fb_stride, std::min(x + w, (int)vfb->width));
|
||||
|
||||
if (!convert) {
|
||||
packed = (GLubyte *)Memory::GetPointer(fb_address);
|
||||
} else { // End result may be 16-bit but we are reading 32-bit, so there may not be enough space at fb_address
|
||||
u32 neededSize = (u32)bufSize * sizeof(GLubyte);
|
||||
if (!convBuf_ || convBufSize_ < neededSize) {
|
||||
int byteOffset = y * vfb->fb_stride * 4;
|
||||
packed = (GLubyte *)Memory::GetPointer(fb_address + byteOffset);
|
||||
} else {
|
||||
// End result may be 16-bit but we are reading 32-bit, so there may not be enough space at fb_address
|
||||
if (!convBuf_ || convBufSize_ < bufSize) {
|
||||
delete [] convBuf_;
|
||||
convBuf_ = new u8[neededSize];
|
||||
convBufSize_ = neededSize;
|
||||
convBuf_ = new u8[bufSize];
|
||||
convBufSize_ = bufSize;
|
||||
}
|
||||
packed = convBuf_;
|
||||
}
|
||||
|
||||
if (packed) {
|
||||
DEBUG_LOG(SCEGE, "Reading framebuffer to mem, bufSize = %u, packed = %p, fb_address = %08x",
|
||||
(u32)bufSize, packed, fb_address);
|
||||
DEBUG_LOG(SCEGE, "Reading framebuffer to mem, bufSize = %u, fb_address = %08x", bufSize, fb_address);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
GLenum glfmt = GL_RGBA;
|
||||
|
@ -1707,12 +1707,11 @@ void FramebufferManager::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, in
|
|||
glfmt = GL_BGRA_EXT;
|
||||
}
|
||||
|
||||
int byteOffset = y * vfb->fb_stride * 4;
|
||||
SafeGLReadPixels(0, y, h == 1 ? packWidth : vfb->fb_stride, h, glfmt, GL_UNSIGNED_BYTE, packed + byteOffset);
|
||||
SafeGLReadPixels(0, y, h == 1 ? packWidth : vfb->fb_stride, h, glfmt, GL_UNSIGNED_BYTE, packed);
|
||||
|
||||
if (convert) {
|
||||
int dstByteOffset = y * vfb->fb_stride * dstBpp;
|
||||
ConvertFromRGBA8888(Memory::GetPointer(fb_address + dstByteOffset), packed + byteOffset, vfb->fb_stride, vfb->fb_stride, packWidth, h, vfb->format);
|
||||
ConvertFromRGBA8888(Memory::GetPointer(fb_address + dstByteOffset), packed, vfb->fb_stride, vfb->fb_stride, packWidth, h, vfb->format);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1731,6 +1730,49 @@ void FramebufferManager::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, in
|
|||
fbo_unbind_read();
|
||||
}
|
||||
|
||||
void FramebufferManager::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) {
|
||||
if (vfb->fbo) {
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
} else {
|
||||
ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0");
|
||||
return;
|
||||
}
|
||||
|
||||
// Pixel size always 4 here because we always request float
|
||||
const u32 bufSize = vfb->z_stride * (h - y) * 4;
|
||||
const u32 z_address = (0x04000000) | vfb->z_address;
|
||||
const int packWidth = std::min(vfb->z_stride, std::min(x + w, (int)vfb->width));
|
||||
|
||||
if (!convBuf_ || convBufSize_ < bufSize) {
|
||||
delete [] convBuf_;
|
||||
convBuf_ = new u8[bufSize];
|
||||
convBufSize_ = bufSize;
|
||||
}
|
||||
|
||||
DEBUG_LOG(SCEGE, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
SafeGLReadPixels(0, y, h == 1 ? packWidth : vfb->z_stride, h, GL_DEPTH_COMPONENT, GL_FLOAT, convBuf_);
|
||||
|
||||
int dstByteOffset = y * vfb->fb_stride * sizeof(u16);
|
||||
u16 *depth = (u16 *)Memory::GetPointer(z_address + dstByteOffset);
|
||||
GLfloat *packed = (GLfloat *)convBuf_;
|
||||
|
||||
int totalPixels = h == 1 ? packWidth : vfb->z_stride * h;
|
||||
for (int i = 0; i < totalPixels; ++i) {
|
||||
float scaled = FromScaledDepth(packed[i]);
|
||||
if (scaled <= 0.0f) {
|
||||
depth[i] = 0;
|
||||
} else if (scaled >= 65535.0f) {
|
||||
depth[i] = 65535;
|
||||
} else {
|
||||
depth[i] = (int)scaled;
|
||||
}
|
||||
}
|
||||
|
||||
fbo_unbind_read();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void ShowScreenResolution();
|
||||
#endif
|
||||
|
|
|
@ -145,6 +145,7 @@ private:
|
|||
|
||||
void PackFramebufferAsync_(VirtualFramebuffer *vfb); // Not used under ES currently
|
||||
void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
||||
|
||||
// Used by DrawPixels
|
||||
unsigned int drawPixelsTex_;
|
||||
|
|
Loading…
Add table
Reference in a new issue