mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-14 22:24:05 +00:00
d3d: Cache offscreen surfaces.
This commit is contained in:
parent
ff3c5075fa
commit
8c4c9e554e
@ -130,6 +130,9 @@ namespace DX9 {
|
||||
if (drawPixelsTex_) {
|
||||
drawPixelsTex_->Release();
|
||||
}
|
||||
for (auto it = offscreenSurfaces_.begin(), end = offscreenSurfaces_.end(); it != end; ++it) {
|
||||
it->second.surface->Release();
|
||||
}
|
||||
delete [] convBuf;
|
||||
}
|
||||
|
||||
@ -526,6 +529,29 @@ namespace DX9 {
|
||||
}
|
||||
}
|
||||
|
||||
LPDIRECT3DSURFACE9 FramebufferManagerDX9::GetOffscreenSurface(LPDIRECT3DSURFACE9 similarSurface) {
|
||||
D3DSURFACE_DESC desc;
|
||||
similarSurface->GetDesc(&desc);
|
||||
|
||||
u64 key = ((u64)desc.Format << 32) | (desc.Width << 16) | desc.Height;
|
||||
auto it = offscreenSurfaces_.find(key);
|
||||
if (it != offscreenSurfaces_.end()) {
|
||||
it->second.last_frame_used = gpuStats.numFlips;
|
||||
return it->second.surface;
|
||||
}
|
||||
|
||||
textureCache_->ForgetLastTexture();
|
||||
LPDIRECT3DSURFACE9 offscreen = nullptr;
|
||||
HRESULT hr = pD3Ddevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, NULL);
|
||||
if (FAILED(hr) || !offscreen) {
|
||||
ERROR_LOG_REPORT(G3D, "Unable to create offscreen surface %dx%d @%d", desc.Width, desc.Height, desc.Format);
|
||||
return nullptr;
|
||||
}
|
||||
const OffscreenSurface info = {offscreen, gpuStats.numFlips};
|
||||
offscreenSurfaces_[key] = info;
|
||||
return offscreen;
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::CopyDisplayToOutput() {
|
||||
|
||||
fbo_unbind();
|
||||
@ -934,11 +960,9 @@ namespace DX9 {
|
||||
D3DSURFACE_DESC desc;
|
||||
renderTarget->GetDesc(&desc);
|
||||
|
||||
LPDIRECT3DSURFACE9 offscreen = nullptr;
|
||||
// TODO: Cache these? Also, StretchRect to resample from 1x?
|
||||
HRESULT hr = pD3Ddevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, NULL);
|
||||
if (offscreen && SUCCEEDED(hr)) {
|
||||
hr = pD3Ddevice->GetRenderTargetData(renderTarget, offscreen);
|
||||
LPDIRECT3DSURFACE9 offscreen = GetOffscreenSurface(renderTarget);
|
||||
if (offscreen) {
|
||||
HRESULT hr = pD3Ddevice->GetRenderTargetData(renderTarget, offscreen);
|
||||
if (SUCCEEDED(hr)) {
|
||||
D3DLOCKED_RECT locked;
|
||||
u32 widthFactor = vfb->renderWidth / vfb->bufferWidth;
|
||||
@ -957,11 +981,9 @@ namespace DX9 {
|
||||
} else {
|
||||
ERROR_LOG_REPORT(G3D, "Unable to download render target data from %08x", fb_address);
|
||||
}
|
||||
offscreen->Release();
|
||||
} else {
|
||||
ERROR_LOG_REPORT(G3D, "Unable to create offscreen surface for %08x %dx%d", fb_address, desc.Width, desc.Height);
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::EndFrame() {
|
||||
if (resized_) {
|
||||
DestroyAllFBOs();
|
||||
@ -1027,6 +1049,16 @@ namespace DX9 {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = offscreenSurfaces_.begin(); it != offscreenSurfaces_.end(); ) {
|
||||
int age = frameLastFramebufUsed_ - it->second.last_frame_used;
|
||||
if (age > FBO_OLD_AGE) {
|
||||
it->second.surface->Release();
|
||||
offscreenSurfaces_.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// Do the same for ReadFramebuffersToMemory's VFBs
|
||||
for (size_t i = 0; i < bvfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *vfb = bvfbs_[i];
|
||||
@ -1052,6 +1084,18 @@ namespace DX9 {
|
||||
DestroyFramebuf(vfb);
|
||||
}
|
||||
vfbs_.clear();
|
||||
|
||||
for (size_t i = 0; i < bvfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *vfb = bvfbs_[i];
|
||||
DestroyFramebuf(vfb);
|
||||
}
|
||||
bvfbs_.clear();
|
||||
|
||||
for (auto it = offscreenSurfaces_.begin(), end = offscreenSurfaces_.end(); it != end; ++it) {
|
||||
it->second.surface->Release();
|
||||
}
|
||||
offscreenSurfaces_.clear();
|
||||
DisableState();
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::FlushBeforeCopy() {
|
||||
@ -1090,9 +1134,8 @@ namespace DX9 {
|
||||
D3DSURFACE_DESC desc;
|
||||
renderTarget->GetDesc(&desc);
|
||||
|
||||
LPDIRECT3DSURFACE9 offscreen = nullptr;
|
||||
hr = pD3Ddevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, NULL);
|
||||
if (!offscreen || !SUCCEEDED(hr)) {
|
||||
LPDIRECT3DSURFACE9 offscreen = GetOffscreenSurface(renderTarget);
|
||||
if (!offscreen) {
|
||||
renderTarget->Release();
|
||||
return false;
|
||||
}
|
||||
@ -1112,7 +1155,6 @@ namespace DX9 {
|
||||
}
|
||||
}
|
||||
|
||||
offscreen->Release();
|
||||
renderTarget->Release();
|
||||
|
||||
return success;
|
||||
|
@ -85,6 +85,8 @@ public:
|
||||
|
||||
virtual void RebindFramebuffer() override;
|
||||
|
||||
LPDIRECT3DSURFACE9 GetOffscreenSurface(LPDIRECT3DSURFACE9 similarSurface);
|
||||
|
||||
protected:
|
||||
virtual void DisableState() override;
|
||||
virtual void ClearBuffer() override;
|
||||
@ -128,7 +130,13 @@ private:
|
||||
bool resized_;
|
||||
bool gameUsesSequentialCopies_;
|
||||
|
||||
struct OffscreenSurface {
|
||||
LPDIRECT3DSURFACE9 surface;
|
||||
int last_frame_used;
|
||||
};
|
||||
|
||||
std::vector<VirtualFramebuffer *> bvfbs_; // blitting FBOs
|
||||
std::map<u64, OffscreenSurface> offscreenSurfaces_;
|
||||
|
||||
#if 0
|
||||
AsyncPBO *pixelBufObj_; //this isn't that large
|
||||
|
@ -903,7 +903,7 @@ void FramebufferManager::BlitFramebufferDepth(VirtualFramebuffer *sourceframebuf
|
||||
}
|
||||
|
||||
FBO *FramebufferManager::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) {
|
||||
u32 key = ((u64)depth << 32) | (w << 16) | h;
|
||||
u64 key = ((u64)depth << 32) | (w << 16) | h;
|
||||
auto it = tempFBOs_.find(key);
|
||||
if (it != tempFBOs_.end()) {
|
||||
it->second.last_frame_used = gpuStats.numFlips;
|
||||
|
Loading…
x
Reference in New Issue
Block a user