// Copyright (c) 2012- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 2.0 or later versions. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License 2.0 for more details. // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include #include "Common/Data/Convert/ColorConv.h" #include "Common/Profiler/Profiler.h" #include "Common/GPU/OpenGL/GLCommon.h" #include "Common/GPU/OpenGL/GLDebugLog.h" #include "Common/GPU/OpenGL/GLSLProgram.h" #include "Common/GPU/thin3d.h" #include "Core/MemMap.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/Debugger/Stepping.h" #include "GPU/GLES/FramebufferManagerGLES.h" #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/GLES/DrawEngineGLES.h" #include "GPU/GLES/ShaderManagerGLES.h" static const char tex_fs[] = R"( #if __VERSION__ >= 130 #define varying in #define texture2D texture #define gl_FragColor fragColor0 out vec4 fragColor0; #endif #ifdef GL_ES precision mediump float; #endif uniform sampler2D sampler0; varying vec2 v_texcoord0; void main() { gl_FragColor = texture2D(sampler0, v_texcoord0); } )"; static const char basic_vs[] = R"( #if __VERSION__ >= 130 #define attribute in #define varying out #endif attribute vec4 a_position; attribute vec2 a_texcoord0; varying vec2 v_texcoord0; void main() { v_texcoord0 = a_texcoord0; gl_Position = a_position; } )"; FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw, GLRenderManager *render) : FramebufferManagerCommon(draw), render_(render) { needBackBufferYSwap_ = true; needGLESRebinds_ = true; presentation_->SetLanguage(draw_->GetShaderLanguageDesc().shaderLanguage); CreateDeviceObjects(); } void FramebufferManagerGLES::Init() { FramebufferManagerCommon::Init(); } void FramebufferManagerGLES::SetTextureCache(TextureCacheGLES *tc) { textureCache_ = tc; } void FramebufferManagerGLES::SetShaderManager(ShaderManagerGLES *sm) { shaderManager_ = sm; } void FramebufferManagerGLES::SetDrawEngine(DrawEngineGLES *td) { drawEngineGL_ = td; drawEngine_ = td; } void FramebufferManagerGLES::CreateDeviceObjects() { } void FramebufferManagerGLES::DestroyDeviceObjects() { if (stencilUploadPipeline_) { stencilUploadPipeline_->Release(); stencilUploadPipeline_ = nullptr; } if (depthDownloadProgram_) { render_->DeleteProgram(depthDownloadProgram_); depthDownloadProgram_ = nullptr; } } FramebufferManagerGLES::~FramebufferManagerGLES() { DestroyDeviceObjects(); delete [] convBuf_; } void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { _assert_msg_(nvfb->fbo, "Expecting a valid nvfb in UpdateDownloadTempBuffer"); // Discard the previous contents of this buffer where possible. if (gl_extensions.GLES3) { draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "UpdateDownloadTempBuffer"); } else if (gl_extensions.IsGLES) { draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "UpdateDownloadTempBuffer"); gstate_c.Dirty(DIRTY_BLEND_STATE); } } void FramebufferManagerGLES::EndFrame() { } void FramebufferManagerGLES::DeviceLost() { FramebufferManagerCommon::DeviceLost(); DestroyDeviceObjects(); } void FramebufferManagerGLES::DeviceRestore(Draw::DrawContext *draw) { FramebufferManagerCommon::DeviceRestore(draw); render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); CreateDeviceObjects(); } void FramebufferManagerGLES::Resized() { FramebufferManagerCommon::Resized(); render_->Resize(PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); } bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) { int w, h; draw_->GetFramebufferDimensions(nullptr, &w, &h); 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, "GetOutputFramebuffer"); return true; }