Permalink
Browse files

Merge pull request #10366 from hrydgard/gl-lost-device-rework

Rework GL lost-device to work more like Vulkan. Gets rid of gl_lost manager etc.
  • Loading branch information...
hrydgard committed Dec 7, 2017
2 parents b75c8b7 + 7d0fc9c commit 3eda3100094e93a8e21e1872af1c554d30eaff08
@@ -868,8 +868,6 @@ add_library(native STATIC
ext/native/gfx/gl_common.h
ext/native/gfx/gl_debug_log.cpp
ext/native/gfx/gl_debug_log.h
ext/native/gfx/gl_lost_manager.cpp
ext/native/gfx/gl_lost_manager.h
ext/native/gfx/texture_atlas.cpp
ext/native/gfx/texture_atlas.h
ext/native/gfx/d3d9_shader.cpp
@@ -132,7 +132,6 @@ DrawEngineGLES::DrawEngineGLES() : vai_(256) {
indexGen.Setup(decIndex);
InitDeviceObjects();
register_gl_resource_holder(this, "drawengine_gles", 1);
tessDataTransfer = new TessellationDataTransferGLES(gl_extensions.VersionGEThan(3, 0, 0));
}
@@ -143,8 +142,6 @@ DrawEngineGLES::~DrawEngineGLES() {
FreeMemoryPages(decIndex, DECODED_INDEX_BUFFER_SIZE);
FreeMemoryPages(splineBuffer, SPLINE_BUFFER_SIZE);
unregister_gl_resource_holder(this);
delete tessDataTransfer;
}
@@ -191,21 +188,6 @@ void DrawEngineGLES::DestroyDeviceObjects() {
}
}
void DrawEngineGLES::GLLost() {
ILOG("TransformDrawEngine::GLLost()");
// The objects have already been deleted by losing the context, so we don't call DestroyDeviceObjects.
bufferNameCache_.clear();
bufferNameInfo_.clear();
freeSizedBuffers_.clear();
bufferNameCacheSize_ = 0;
ClearTrackedVertexArrays();
}
void DrawEngineGLES::GLRestore() {
ILOG("TransformDrawEngine::GLRestore()");
InitDeviceObjects();
}
struct GlTypeInfo {
u16 type;
u8 count;
@@ -28,7 +28,6 @@
#include "GPU/Common/GPUStateUtils.h"
#include "GPU/GLES/FragmentShaderGeneratorGLES.h"
#include "gfx/gl_common.h"
#include "gfx/gl_lost_manager.h"
class LinkedShader;
class ShaderManagerGLES;
@@ -100,7 +99,7 @@ class VertexArrayInfo {
};
// Handles transform, lighting and drawing.
class DrawEngineGLES : public DrawEngineCommon, public GfxResourceHolder {
class DrawEngineGLES : public DrawEngineCommon {
public:
DrawEngineGLES();
virtual ~DrawEngineGLES();
@@ -122,8 +121,6 @@ class DrawEngineGLES : public DrawEngineCommon, public GfxResourceHolder {
void RestoreVAO();
void InitDeviceObjects();
void DestroyDeviceObjects();
void GLLost() override;
void GLRestore() override;
void ClearTrackedVertexArrays() override;
void DecimateTrackedVertexArrays();
@@ -75,6 +75,8 @@ static const char basic_vs[] =
" gl_Position = a_position;\n"
"}\n";
const int MAX_PBO = 2;
void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u32 width, u32 height, GEBufferFormat format);
void FramebufferManagerGLES::DisableState() {
@@ -189,25 +191,11 @@ void FramebufferManagerGLES::BindPostShader(const PostShaderUniforms &uniforms)
glUniform1f(videoLoc_, uniforms.video);
}
void FramebufferManagerGLES::DestroyDraw2DProgram() {
if (draw2dprogram_) {
glsl_destroy(draw2dprogram_);
draw2dprogram_ = nullptr;
}
if (postShaderProgram_) {
glsl_destroy(postShaderProgram_);
postShaderProgram_ = nullptr;
}
}
FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw) :
FramebufferManagerCommon(draw),
drawPixelsTex_(0),
drawPixelsTexFormat_(GE_FORMAT_INVALID),
convBuf_(nullptr),
draw2dprogram_(nullptr),
postShaderProgram_(nullptr),
stencilUploadProgram_(nullptr),
videoLoc_(-1),
timeLoc_(-1),
pixelDeltaLoc_(-1),
@@ -219,6 +207,7 @@ FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw) :
{
needBackBufferYSwap_ = true;
needGLESRebinds_ = true;
CreateDeviceObjects();
}
void FramebufferManagerGLES::Init() {
@@ -243,19 +232,38 @@ void FramebufferManagerGLES::SetDrawEngine(DrawEngineGLES *td) {
drawEngine_ = td;
}
FramebufferManagerGLES::~FramebufferManagerGLES() {
if (drawPixelsTex_)
void FramebufferManagerGLES::CreateDeviceObjects() {
CompileDraw2DProgram();
}
void FramebufferManagerGLES::DestroyDeviceObjects() {
if (draw2dprogram_) {
glsl_destroy(draw2dprogram_);
draw2dprogram_ = nullptr;
}
if (postShaderProgram_) {
glsl_destroy(postShaderProgram_);
postShaderProgram_ = nullptr;
}
if (drawPixelsTex_) {
glDeleteTextures(1, &drawPixelsTex_);
DestroyDraw2DProgram();
drawPixelsTex_ = 0;
}
if (stencilUploadProgram_) {
glsl_destroy(stencilUploadProgram_);
stencilUploadProgram_ = nullptr;
}
}
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
it->second.fbo->Release();
}
FramebufferManagerGLES::~FramebufferManagerGLES() {
DestroyDeviceObjects();
delete [] pixelBufObj_;
if (pixelBufObj_) {
for (int i = 0; i < MAX_PBO; i++) {
glDeleteBuffers(1, &pixelBufObj_[i].handle);
}
delete[] pixelBufObj_;
}
delete [] convBuf_;
}
@@ -761,7 +769,6 @@ void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u
void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) {
CHECK_GL_ERROR_IF_DEBUG();
const int MAX_PBO = 2;
GLubyte *packed = 0;
bool unbind = false;
const u8 nextPBO = (currentPBO_ + 1) % MAX_PBO;
@@ -1005,7 +1012,12 @@ void FramebufferManagerGLES::EndFrame() {
void FramebufferManagerGLES::DeviceLost() {
DestroyAllFBOs();
DestroyDraw2DProgram();
DestroyDeviceObjects();
}
void FramebufferManagerGLES::DeviceRestore(Draw::DrawContext *draw) {
draw_ = draw;
CreateDeviceObjects();
}
void FramebufferManagerGLES::DestroyAllFBOs() {
@@ -1046,8 +1058,6 @@ void FramebufferManagerGLES::Resized() {
DestroyAllFBOs();
}
DestroyDraw2DProgram();
#ifndef USING_GLES2
if (g_Config.iInternalResolution == 0) {
glLineWidth(std::max(1, (int)(renderWidth_ / 480)));
@@ -1057,10 +1067,6 @@ void FramebufferManagerGLES::Resized() {
glPointSize((float)g_Config.iInternalResolution);
}
#endif
if (!draw2dprogram_) {
CompileDraw2DProgram();
}
}
bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
@@ -1069,4 +1075,4 @@ bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
buffer.Allocate(w, h, GPU_DBG_FORMAT_888_RGB, true);
draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData(), w);
return true;
}
}
@@ -83,6 +83,8 @@ class FramebufferManagerGLES : public FramebufferManagerCommon {
bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override;
virtual void RebindFramebuffer() override;
void DeviceRestore(Draw::DrawContext *draw);
protected:
void SetViewport2D(int x, int y, int w, int h) override;
void DisableState() override;
@@ -94,6 +96,9 @@ class FramebufferManagerGLES : public FramebufferManagerCommon {
void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
private:
void CreateDeviceObjects();
void DestroyDeviceObjects();
void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) override;
void Bind2DShader() override;
void BindPostShader(const PostShaderUniforms &uniforms) override;
@@ -113,10 +118,9 @@ class FramebufferManagerGLES : public FramebufferManagerCommon {
u8 *convBuf_;
u32 convBufSize_;
GLSLProgram *draw2dprogram_;
GLSLProgram *plainColorProgram_;
GLSLProgram *postShaderProgram_;
GLSLProgram *stencilUploadProgram_;
GLSLProgram *draw2dprogram_ = nullptr;
GLSLProgram *postShaderProgram_ = nullptr;
GLSLProgram *stencilUploadProgram_ = nullptr;
int plainColorLoc_;
int videoLoc_;
int timeLoc_;
@@ -385,23 +385,24 @@ void GPU_GLES::BuildReportingInfo() {
void GPU_GLES::DeviceLost() {
ILOG("GPU_GLES: DeviceLost");
// Should only be executed on the GL thread.
// Simply drop all caches and textures.
// FBOs appear to survive? Or no?
// TransformDraw has registered as a GfxResourceHolder.
shaderManagerGL_->ClearCache(false);
textureCacheGL_->Clear(false);
fragmentTestCache_.Clear(false);
depalShaderCache_.Clear();
drawEngine_.ClearTrackedVertexArrays();
framebufferManagerGL_->DeviceLost();
}
void GPU_GLES::DeviceRestore() {
draw_ = (Draw::DrawContext *)PSP_CoreParameter().graphicsContext->GetDrawContext();
ILOG("GPU_GLES: DeviceRestore");
UpdateCmdInfo();
UpdateVsyncInterval(true);
textureCacheGL_->DeviceRestore(draw_);
framebufferManagerGL_->DeviceRestore(draw_);
}
void GPU_GLES::Reinitialize() {
@@ -917,6 +917,11 @@ 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())
glTexImage2D(GL_TEXTURE_2D, 0, components, w, h, 0, components2, dstFmt, pixelData);
else
@@ -925,7 +930,7 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
// TODO: We really, really should avoid calling glGetError.
GLenum err = glGetError();
if (err == GL_OUT_OF_MEMORY) {
WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode");
WARN_LOG(G3D, "Texture cache ran out of GPU memory; switching to low memory mode");
lowMemoryMode_ = true;
decimationCounter_ = 0;
Decimate();
@@ -939,15 +944,9 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r
host->NotifyUserMessage(err->T("Warning: Video memory FULL, switching to slow caching mode"), 2.0f);
}
} else if (err != GL_NO_ERROR) {
const char *str = "other";
switch (err) {
case GL_OUT_OF_MEMORY: str = "out_of_memory"; break;
case GL_INVALID_ENUM: str = "invalid_enum"; break;
case GL_INVALID_VALUE: str = "invalid_value"; break;
}
// We checked the err anyway, might as well log if there is one.
WARN_LOG(G3D, "Got an error in texture upload: %08x (%s) (components=%s components2=%s dstFmt=%s w=%d h=%d level=%d)",
err, str, GLEnumToString(components).c_str(), GLEnumToString(components2).c_str(), GLEnumToString(dstFmt).c_str(),
err, GLEnumToString(err).c_str(), GLEnumToString(components).c_str(), GLEnumToString(components2).c_str(), GLEnumToString(dstFmt).c_str(),
w, h, level);
}
}
@@ -1066,3 +1065,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level)
return false;
#endif
}
void TextureCacheGLES::DeviceRestore(Draw::DrawContext *draw) {
draw_ = draw;
}
@@ -69,6 +69,8 @@ class TextureCacheGLES : public TextureCacheCommon {
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight);
bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override;
void DeviceRestore(Draw::DrawContext *draw);
protected:
void BindTexture(TexCacheEntry *entry) override;
void Unbind() override;
@@ -1,7 +1,6 @@
#include "debugger_memorytex.h"
#include "gfx/GLStateCache.h"
#include "gfx/gl_common.h"
#include "gfx/gl_lost_manager.h"
#include "ui_debugger_memorytex.h"
#include "Core/MemMap.h"
#include <QImage>
@@ -1163,24 +1163,6 @@ void EmuScreen::renderUI() {
screenManager()->getUIContext()->End();
}
void EmuScreen::deviceLost() {
ILOG("EmuScreen::deviceLost()");
if (gpu)
gpu->DeviceLost();
else
ILOG("No gpu to deviceLost!");
}
void EmuScreen::deviceRestore() {
ILOG("EmuScreen::deviceRestore()");
if (gpu)
gpu->DeviceRestore();
else
ILOG("No gpu to deviceRestore!");
RecreateViews();
}
void EmuScreen::autoLoad() {
//check if save state has save, if so, load
int lastSlot = SaveState::GetNewestSlot(gamePath_);
@@ -40,8 +40,6 @@ class EmuScreen : public UIScreen {
void render() override;
void preRender() override;
void postRender() override;
void deviceLost() override;
void deviceRestore() override;
void dialogFinished(const Screen *dialog, DialogResult result) override;
void sendMessage(const char *msg, const char *value) override;
void resized() override;
Oops, something went wrong.

0 comments on commit 3eda310

Please sign in to comment.