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->fb_stride = params.fb_stride;
|
||||||
vfb->format = params.fmt;
|
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.
|
// Heuristic: In throughmode, a higher height could be used. Let's avoid shrinking the buffer.
|
||||||
if (params.isModeThrough && (int)vfb->width < params.fb_stride) {
|
if (params.isModeThrough && (int)vfb->width < params.fb_stride) {
|
||||||
vfb->width = std::max((int)vfb->width, drawing_width);
|
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() {
|
void FramebufferManagerDX9::EndFrame() {
|
||||||
if (resized_) {
|
if (resized_) {
|
||||||
DestroyAllFBOs();
|
DestroyAllFBOs();
|
||||||
|
|
|
@ -115,6 +115,7 @@ private:
|
||||||
void SetNumExtraFBOs(int num);
|
void SetNumExtraFBOs(int num);
|
||||||
|
|
||||||
void PackFramebufferDirectx9_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
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);
|
static bool GetRenderTargetFramebuffer(LPDIRECT3DSURFACE9 renderTarget, LPDIRECT3DSURFACE9 offscreen, int w, int h, GPUDebugBuffer &buffer);
|
||||||
|
|
||||||
// Used by DrawPixels
|
// 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
|
// 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;
|
u32 fb_address = (0x04000000) | vfb->fb_address;
|
||||||
|
|
||||||
GLubyte *packed = 0;
|
GLubyte *packed = 0;
|
||||||
|
|
||||||
bool convert = vfb->format != GE_FORMAT_8888 || UseBGRA8888();
|
bool convert = vfb->format != GE_FORMAT_8888 || UseBGRA8888();
|
||||||
const int dstBpp = vfb->format == GE_FORMAT_8888 ? 4 : 2;
|
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) {
|
if (!convert) {
|
||||||
packed = (GLubyte *)Memory::GetPointer(fb_address);
|
int byteOffset = y * vfb->fb_stride * 4;
|
||||||
} else { // End result may be 16-bit but we are reading 32-bit, so there may not be enough space at fb_address
|
packed = (GLubyte *)Memory::GetPointer(fb_address + byteOffset);
|
||||||
u32 neededSize = (u32)bufSize * sizeof(GLubyte);
|
} else {
|
||||||
if (!convBuf_ || convBufSize_ < neededSize) {
|
// 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_;
|
delete [] convBuf_;
|
||||||
convBuf_ = new u8[neededSize];
|
convBuf_ = new u8[bufSize];
|
||||||
convBufSize_ = neededSize;
|
convBufSize_ = bufSize;
|
||||||
}
|
}
|
||||||
packed = convBuf_;
|
packed = convBuf_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packed) {
|
if (packed) {
|
||||||
DEBUG_LOG(SCEGE, "Reading framebuffer to mem, bufSize = %u, packed = %p, fb_address = %08x",
|
DEBUG_LOG(SCEGE, "Reading framebuffer to mem, bufSize = %u, fb_address = %08x", bufSize, fb_address);
|
||||||
(u32)bufSize, packed, fb_address);
|
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||||
GLenum glfmt = GL_RGBA;
|
GLenum glfmt = GL_RGBA;
|
||||||
|
@ -1707,12 +1707,11 @@ void FramebufferManager::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, in
|
||||||
glfmt = GL_BGRA_EXT;
|
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);
|
||||||
SafeGLReadPixels(0, y, h == 1 ? packWidth : vfb->fb_stride, h, glfmt, GL_UNSIGNED_BYTE, packed + byteOffset);
|
|
||||||
|
|
||||||
if (convert) {
|
if (convert) {
|
||||||
int dstByteOffset = y * vfb->fb_stride * dstBpp;
|
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();
|
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
|
#ifdef _WIN32
|
||||||
void ShowScreenResolution();
|
void ShowScreenResolution();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -145,6 +145,7 @@ private:
|
||||||
|
|
||||||
void PackFramebufferAsync_(VirtualFramebuffer *vfb); // Not used under ES currently
|
void PackFramebufferAsync_(VirtualFramebuffer *vfb); // Not used under ES currently
|
||||||
void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h);
|
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
|
// Used by DrawPixels
|
||||||
unsigned int drawPixelsTex_;
|
unsigned int drawPixelsTex_;
|
||||||
|
|
Loading…
Add table
Reference in a new issue