mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Fix image leak bug when pausing and we're just displaying a framebuffer in memory
This commit is contained in:
parent
364c205d95
commit
49ecc01556
7 changed files with 45 additions and 7 deletions
|
@ -131,7 +131,6 @@ public:
|
|||
stencilDirty_ = true;
|
||||
}
|
||||
|
||||
void EndFrame() override;
|
||||
|
||||
void Draw(int vertexCount, int offset) override;
|
||||
void DrawIndexed(int vertexCount, int offset) override;
|
||||
|
@ -139,6 +138,9 @@ public:
|
|||
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
|
||||
|
||||
void BeginFrame() override;
|
||||
void EndFrame() override;
|
||||
|
||||
int GetFrameCount() override { return frameCount_; }
|
||||
|
||||
std::string GetInfoString(InfoField info) const override {
|
||||
switch (info) {
|
||||
|
@ -221,6 +223,7 @@ private:
|
|||
int nextIndexBufferOffset_ = 0;
|
||||
|
||||
InvalidationCallback invalidationCallback_;
|
||||
int frameCount_ = 0;
|
||||
|
||||
// Dynamic state
|
||||
float blendFactor_[4]{};
|
||||
|
@ -423,6 +426,7 @@ void D3D11DrawContext::HandleEvent(Event ev, int width, int height, void *param1
|
|||
|
||||
void D3D11DrawContext::EndFrame() {
|
||||
curPipeline_ = nullptr;
|
||||
frameCount_++;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::SetViewport(const Viewport &viewport) {
|
||||
|
|
|
@ -580,6 +580,7 @@ public:
|
|||
}
|
||||
|
||||
void EndFrame() override;
|
||||
int GetFrameCount() override { return frameCount_; }
|
||||
|
||||
void UpdateDynamicUniformBuffer(const void *ub, size_t size) override;
|
||||
|
||||
|
@ -640,6 +641,7 @@ private:
|
|||
D3DCAPS9 d3dCaps_;
|
||||
char shadeLangVersion_[64]{};
|
||||
DeviceCaps caps_{};
|
||||
int frameCount_ = 0;
|
||||
|
||||
// Bound state
|
||||
AutoRef<D3D9Pipeline> curPipeline_;
|
||||
|
@ -964,6 +966,7 @@ void D3D9Context::BindNativeTexture(int index, void *nativeTexture) {
|
|||
|
||||
void D3D9Context::EndFrame() {
|
||||
curPipeline_ = nullptr;
|
||||
frameCount_++;
|
||||
}
|
||||
|
||||
static void SemanticToD3D9UsageAndIndex(int semantic, BYTE *usage, BYTE *index) {
|
||||
|
|
|
@ -370,6 +370,10 @@ public:
|
|||
void BeginFrame() override;
|
||||
void EndFrame() override;
|
||||
|
||||
int GetFrameCount() override {
|
||||
return frameCount_;
|
||||
}
|
||||
|
||||
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
|
||||
void UpdateTextureLevels(Texture *texture, const uint8_t **data, TextureCallback initDataCallback, int numLevels) override;
|
||||
|
||||
|
@ -492,6 +496,7 @@ private:
|
|||
void ApplySamplers();
|
||||
|
||||
GLRenderManager renderManager_;
|
||||
int frameCount_ = 0;
|
||||
|
||||
DeviceCaps caps_{};
|
||||
|
||||
|
@ -795,6 +800,7 @@ void OpenGLContext::EndFrame() {
|
|||
renderManager_.Finish();
|
||||
|
||||
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
|
||||
frameCount_++;
|
||||
}
|
||||
|
||||
void OpenGLContext::Invalidate(InvalidationFlags flags) {
|
||||
|
|
|
@ -53,8 +53,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(
|
|||
return false;
|
||||
case 1303270965:
|
||||
// Benign perf warning, image blit using GENERAL layout.
|
||||
// UNASSIGNED
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
|
||||
// TODO: Oops, turns out we filtered out a bit too much here!
|
||||
// We really need that performance flag check to sort out the stuff that matters.
|
||||
// Will enable it soon, but it'll take some fixing.
|
||||
//
|
||||
//if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
@ -79,6 +82,14 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(
|
|||
// Extended validation (ARM best practices)
|
||||
// Non-fifo validation not recommended
|
||||
return false;
|
||||
case -564812795:
|
||||
case 369680064:
|
||||
case 307231540:
|
||||
case 618171435: // SHADER_ACCESS_READ
|
||||
case 1774732925: // same but different
|
||||
case -1539028524: // image layout in draw
|
||||
// wip
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -484,6 +484,10 @@ public:
|
|||
void EndFrame() override;
|
||||
void WipeQueue() override;
|
||||
|
||||
int GetFrameCount() override {
|
||||
return frameCount_;
|
||||
}
|
||||
|
||||
void FlushState() override {}
|
||||
|
||||
void ResetStats() override {
|
||||
|
@ -528,6 +532,7 @@ private:
|
|||
VulkanTexture *GetNullTexture();
|
||||
VulkanContext *vulkan_ = nullptr;
|
||||
|
||||
int frameCount_ = 0;
|
||||
VulkanRenderManager renderManager_;
|
||||
|
||||
VulkanTexture *nullTexture_ = nullptr;
|
||||
|
@ -1105,6 +1110,8 @@ void VKContext::EndFrame() {
|
|||
|
||||
// Unbind stuff, to avoid accidentally relying on it across frames (and provide some protection against forgotten unbinds of deleted things).
|
||||
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
|
||||
|
||||
frameCount_++;
|
||||
}
|
||||
|
||||
void VKContext::Invalidate(InvalidationFlags flags) {
|
||||
|
|
|
@ -841,6 +841,10 @@ public:
|
|||
// Not very elegant, but more elegant than the old passId hack.
|
||||
virtual void SetInvalidationCallback(InvalidationCallback callback) = 0;
|
||||
|
||||
// Total amount of frames rendered. Unaffected by game pause, so more robust than gpuStats.numFlips
|
||||
virtual int GetFrameCount() = 0;
|
||||
virtual int GetFramesInFlight() { return 3; }
|
||||
|
||||
protected:
|
||||
ShaderModule *vsPresets_[VS_MAX_PRESET];
|
||||
ShaderModule *fsPresets_[FS_MAX_PRESET];
|
||||
|
|
|
@ -1402,16 +1402,19 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G
|
|||
|
||||
Draw::DataFormat texFormat = srcPixelFormat == GE_FORMAT_DEPTH16 ? depthFormat : preferredPixelsFormat_;
|
||||
|
||||
int frameNumber = draw_->GetFrameCount();
|
||||
|
||||
// Look for a matching texture we can re-use.
|
||||
for (auto &iter : drawPixelsCache_) {
|
||||
if (iter.frameNumber > gpuStats.numFlips - 3 || iter.tex->Width() != width || iter.tex->Height() != height || iter.tex->Format() != texFormat) {
|
||||
if (iter.frameNumber >= frameNumber - 3 || iter.tex->Width() != width || iter.tex->Height() != height || iter.tex->Format() != texFormat) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// OK, current one seems good, let's use it (and mark it used).
|
||||
gpuStats.numDrawPixels++;
|
||||
draw_->UpdateTextureLevels(iter.tex, &srcPixels, generateTexture, 1);
|
||||
iter.frameNumber = gpuStats.numFlips;
|
||||
// NOTE: numFlips is no good - this is called every frame when paused sometimes!
|
||||
iter.frameNumber = frameNumber;
|
||||
return iter.tex;
|
||||
}
|
||||
|
||||
|
@ -1442,7 +1445,7 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G
|
|||
|
||||
INFO_LOG(G3D, "Creating drawPixelsCache texture: %dx%d", tex->Width(), tex->Height());
|
||||
|
||||
DrawPixelsEntry entry{ tex, gpuStats.numFlips };
|
||||
DrawPixelsEntry entry{ tex, frameNumber };
|
||||
drawPixelsCache_.push_back(entry);
|
||||
return tex;
|
||||
}
|
||||
|
@ -1695,7 +1698,7 @@ void FramebufferManagerCommon::DecimateFBOs() {
|
|||
// And DrawPixels cached textures.
|
||||
|
||||
for (auto it = drawPixelsCache_.begin(); it != drawPixelsCache_.end(); ) {
|
||||
int age = gpuStats.numFlips - it->frameNumber;
|
||||
int age = draw_->GetFrameCount() - it->frameNumber;
|
||||
if (age > 10) {
|
||||
INFO_LOG(G3D, "Releasing drawPixelsCache texture: %dx%d", it->tex->Width(), it->tex->Height());
|
||||
it->tex->Release();
|
||||
|
|
Loading…
Add table
Reference in a new issue