GLES: Reintroduce out of memory checks.

This commit is contained in:
Unknown W. Brackets 2018-01-20 09:35:43 -08:00 committed by Henrik Rydgård
parent 900e53b6dc
commit acc3e39b67
4 changed files with 44 additions and 5 deletions

View file

@ -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

View file

@ -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) {

View file

@ -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;
};

View file

@ -653,6 +653,10 @@ public:
void StopThread();
bool SawOutOfMemory() {
return queueRunner_.SawOutOfMemory();
}
private:
void BeginSubmitFrame(int frame);
void EndSubmitFrame(int frame);