mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
GLES: Reintroduce out of memory checks.
This commit is contained in:
parent
900e53b6dc
commit
acc3e39b67
4 changed files with 44 additions and 5 deletions
|
@ -207,6 +207,19 @@ void TextureCacheGLES::StartFrame() {
|
|||
InvalidateLastTexture();
|
||||
timesInvalidatedAllThisFrame_ = 0;
|
||||
|
||||
GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
if (!lowMemoryMode_ && renderManager->SawOutOfMemory()) {
|
||||
lowMemoryMode_ = true;
|
||||
decimationCounter_ = 0;
|
||||
|
||||
I18NCategory *err = GetI18NCategory("Error");
|
||||
if (standardScaleFactor_ > 1) {
|
||||
host->NotifyUserMessage(err->T("Warning: Video memory FULL, reducing upscaling and switching to slow caching mode"), 2.0f);
|
||||
} else {
|
||||
host->NotifyUserMessage(err->T("Warning: Video memory FULL, switching to slow caching mode"), 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (texelsScaledThisFrame_) {
|
||||
// INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_);
|
||||
}
|
||||
|
@ -803,11 +816,6 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
|
|||
// glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, components2, dstFmt, pixelData);
|
||||
} else {
|
||||
PROFILE_THIS_SCOPE("loadtex");
|
||||
// Avoid misleading errors in texture upload, these are common.
|
||||
GLenum err = glGetError();
|
||||
if (err) {
|
||||
WARN_LOG(G3D, "Got an error BEFORE texture upload: %08x (%s)", err, GLEnumToString(err).c_str());
|
||||
}
|
||||
if (IsFakeMipmapChange())
|
||||
render_->TextureImage(entry.textureName, 0, w, h, components, components2, dstFmt, pixelData);
|
||||
else
|
||||
|
|
|
@ -23,6 +23,9 @@ GLuint g_defaultFBO = 0;
|
|||
void GLQueueRunner::CreateDeviceObjects() {
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyLevel_);
|
||||
glGenVertexArrays(1, &globalVAO_);
|
||||
|
||||
// An eternal optimist.
|
||||
sawOutOfMemory_ = false;
|
||||
}
|
||||
|
||||
void GLQueueRunner::DestroyDeviceObjects() {
|
||||
|
@ -36,6 +39,7 @@ void GLQueueRunner::DestroyDeviceObjects() {
|
|||
void GLQueueRunner::RunInitSteps(const std::vector<GLRInitStep> &steps) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
GLuint boundTexture = (GLuint)-1;
|
||||
bool allocatedTextures = false;
|
||||
|
||||
for (int i = 0; i < steps.size(); i++) {
|
||||
const GLRInitStep &step = steps[i];
|
||||
|
@ -197,6 +201,7 @@ void GLQueueRunner::RunInitSteps(const std::vector<GLRInitStep> &steps) {
|
|||
{
|
||||
boundTexture = (GLuint)-1;
|
||||
InitCreateFramebuffer(step);
|
||||
allocatedTextures = true;
|
||||
break;
|
||||
}
|
||||
case GLRInitStepType::TEXTURE_IMAGE:
|
||||
|
@ -211,6 +216,7 @@ void GLQueueRunner::RunInitSteps(const std::vector<GLRInitStep> &steps) {
|
|||
Crash();
|
||||
// For things to show in RenderDoc, need to split into glTexImage2D(..., nullptr) and glTexSubImage.
|
||||
glTexImage2D(tex->target, step.texture_image.level, step.texture_image.internalFormat, step.texture_image.width, step.texture_image.height, 0, step.texture_image.format, step.texture_image.type, step.texture_image.data);
|
||||
allocatedTextures = true;
|
||||
delete[] step.texture_image.data;
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
tex->wrapS = GL_CLAMP_TO_EDGE;
|
||||
|
@ -242,6 +248,21 @@ void GLQueueRunner::RunInitSteps(const std::vector<GLRInitStep> &steps) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use GL_KHR_no_error or a debug callback, where supported?
|
||||
if (allocatedTextures) {
|
||||
// Users may use replacements or scaling, with high render resolutions, and run out of VRAM.
|
||||
// This detects that, rather than looking like PPSSPP is broken.
|
||||
// Calling glGetError() isn't great, but at the end of init shouldn't be too bad...
|
||||
GLenum err = glGetError();
|
||||
if (err == GL_OUT_OF_MEMORY) {
|
||||
WARN_LOG_REPORT(G3D, "GL ran out of GPU memory; switching to low memory mode");
|
||||
sawOutOfMemory_ = true;
|
||||
} else if (err != GL_NO_ERROR) {
|
||||
// We checked the err anyway, might as well log if there is one.
|
||||
WARN_LOG(G3D, "Got an error after init: %08x (%s)", err, GLEnumToString(err).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) {
|
||||
|
|
|
@ -328,6 +328,10 @@ public:
|
|||
targetWidth_ = width;
|
||||
targetHeight_ = height;
|
||||
}
|
||||
|
||||
bool SawOutOfMemory() {
|
||||
return sawOutOfMemory_;
|
||||
}
|
||||
private:
|
||||
void InitCreateFramebuffer(const GLRInitStep &step);
|
||||
|
||||
|
@ -374,4 +378,6 @@ private:
|
|||
GLuint AllocTextureName();
|
||||
// Texture name cache. Ripped straight from TextureCacheGLES.
|
||||
std::vector<GLuint> nameCache_;
|
||||
|
||||
bool sawOutOfMemory_ = false;
|
||||
};
|
||||
|
|
|
@ -653,6 +653,10 @@ public:
|
|||
|
||||
void StopThread();
|
||||
|
||||
bool SawOutOfMemory() {
|
||||
return queueRunner_.SawOutOfMemory();
|
||||
}
|
||||
|
||||
private:
|
||||
void BeginSubmitFrame(int frame);
|
||||
void EndSubmitFrame(int frame);
|
||||
|
|
Loading…
Add table
Reference in a new issue