From 72ae497350d03c8a52824f226d0e9883ae3e4ed0 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 6 Sep 2015 12:23:14 +0200 Subject: [PATCH 1/8] Remove glstate usage except in the GPU implementation. Prepare for moving it into PPSSPP. --- Core/HLE/sceDisplay.cpp | 4 +--- GPU/Directx9/FramebufferDX9.cpp | 6 +++--- GPU/Directx9/GPU_DX9.cpp | 5 +++++ GPU/Directx9/GPU_DX9.h | 1 + GPU/GLES/GLES_GPU.cpp | 5 +++++ GPU/GLES/GLES_GPU.h | 1 + GPU/GPUCommon.cpp | 1 - GPU/GPUCommon.h | 2 +- GPU/Software/SoftGpu.cpp | 12 +++++------ UI/DevScreens.cpp | 1 - UI/EmuScreen.cpp | 3 +-- UI/MiscScreens.cpp | 1 - UI/NativeApp.cpp | 35 +------------------------------- Windows/OpenGLBase.cpp | 4 +--- android/jni/TestRunner.cpp | 7 ++----- headless/WindowsHeadlessHost.cpp | 8 ++------ native | 2 +- 17 files changed, 31 insertions(+), 67 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 7d3b595c8b..a834376165 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -33,9 +33,7 @@ #include "base/timeutil.h" #include "profiler/profiler.h" -#ifndef _XBOX -#include "gfx_es2/gl_state.h" -#endif +#include "gfx_es2/gpu_features.h" #include "Common/ChunkFile.h" #include "Core/CoreTiming.h" diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 452a5fe584..8d1349f74f 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -775,7 +775,7 @@ namespace DX9 { fbo_bind_as_render_target(extraFBOs_[0]); int fbo_w, fbo_h; fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h); - glstate.viewport.set(0, 0, fbo_w, fbo_h); + dxstate.viewport.set(0, 0, fbo_w, fbo_h); DrawActiveTexture(colorTexture, 0, 0, fbo_w, fbo_h, fbo_w, fbo_h, true, 1.0f, 1.0f, postShaderProgram_); fbo_unbind(); @@ -787,12 +787,12 @@ namespace DX9 { return; } colorTexture = fbo_get_color_texture(extraFBOs_[0]); - glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); // These are in the output display coordinates DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, 480.0f / (float)vfb->width, 272.0f / (float)vfb->height); } else { // Use post-shader, but run shader at output resolution. - glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); // These are in the output display coordinates DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, 480.0f / (float)vfb->width, 272.0f / (float)vfb->height, postShaderProgram_); } diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 12ff6c44d6..0e7fa8eba5 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -509,6 +509,11 @@ void DIRECTX9_GPU::BeginFrame() { ScheduleEvent(GPU_EVENT_BEGIN_FRAME); } +void DIRECTX9_GPU::ReapplyGfxStateInternal() { + DX9::dxstate.Restore(); + GPUCommon::ReapplyGfxStateInternal(); +} + void DIRECTX9_GPU::BeginFrameInternal() { if (resized_) { UpdateCmdInfo(); diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index 6673212adf..0fc3fb929f 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -41,6 +41,7 @@ public: void PreExecuteOp(u32 op, u32 diff) override; void ExecuteOp(u32 op, u32 diff) override; + void ReapplyGfxStateInternal() override; void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override; void CopyDisplayToOutput() override; void BeginFrame() override; diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index 52686ef8e1..07e899506d 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -678,6 +678,11 @@ void GLES_GPU::UpdateCmdInfo() { } } +void GLES_GPU::ReapplyGfxStateInternal() { + glstate.Restore(); + GPUCommon::ReapplyGfxStateInternal(); +} + void GLES_GPU::BeginFrameInternal() { if (resized_) { CheckGPUFeatures(); diff --git a/GPU/GLES/GLES_GPU.h b/GPU/GLES/GLES_GPU.h index b2a97684e1..a40090e85e 100644 --- a/GPU/GLES/GLES_GPU.h +++ b/GPU/GLES/GLES_GPU.h @@ -46,6 +46,7 @@ public: void Execute_Generic(u32 op, u32 diff); void ExecuteOp(u32 op, u32 diff) override; + void ReapplyGfxStateInternal() override; void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override; void CopyDisplayToOutput() override; void BeginFrame() override; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index cb97da1071..786952e256 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -620,7 +620,6 @@ void GPUCommon::ReapplyGfxState() { } void GPUCommon::ReapplyGfxStateInternal() { - // ShaderManager_DirtyShader(); // The commands are embedded in the command memory so we can just reexecute the words. Convenient. // To be safe we pass 0xFFFFFFFF as the diff. diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index fa1288fd41..87d4d8d84d 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -133,7 +133,7 @@ protected: void CheckDrawSync(); int GetNextListIndex(); void ProcessDLQueueInternal(); - void ReapplyGfxStateInternal(); + virtual void ReapplyGfxStateInternal(); virtual void FastLoadBoneMatrix(u32 target); virtual void ProcessEvent(GPUEvent ev); virtual bool ShouldExitEventLoop() { diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 39cfd7e4b3..79dd804036 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -29,7 +29,7 @@ #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "gfx/gl_common.h" -#include "gfx_es2/gl_state.h" +// #include "gfx_es2/gl_state.h" #include "profiler/profiler.h" #include "GPU/Software/SoftGpu.h" @@ -187,9 +187,9 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) float dstwidth = (float)PSP_CoreParameter().pixelWidth; float dstheight = (float)PSP_CoreParameter().pixelHeight; - glstate.blend.disable(); - glstate.viewport.set(0, 0, dstwidth, dstheight); - glstate.scissorTest.disable(); + glDisable(GL_BLEND); + glViewport(0, 0, dstwidth, dstheight); + glDisable(GL_SCISSOR_TEST); glBindTexture(GL_TEXTURE_2D, temp_texture); @@ -275,8 +275,8 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {texvert_u, 1} }; - glstate.arrayBuffer.unbind(); - glstate.elementArrayBuffer.unbind(); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts); glEnableVertexAttribArray(attr_pos); diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 514e729751..037307ae99 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -18,7 +18,6 @@ #include #include "base/compat.h" -#include "gfx_es2/gl_state.h" #include "gfx_es2/gpu_features.h" #include "i18n/i18n.h" #include "ui/ui_context.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index f218ae5d43..213a210367 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -23,8 +23,7 @@ #include "base/timeutil.h" #include "profiler/profiler.h" -#include "gfx_es2/glsl_program.h" -#include "gfx_es2/gl_state.h" +#include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/fbo.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 22ab4e9541..c2827cc7b5 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -51,7 +51,6 @@ #include "base/timeutil.h" #include "base/colorutil.h" #include "gfx_es2/draw_buffer.h" -#include "gfx_es2/gl_state.h" #include "util/random/rng.h" #include "UI/ui_atlas.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 4a7584e679..f7f59c40a0 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -48,8 +48,8 @@ #include "file/zip_read.h" #include "thread/thread.h" #include "net/http_client.h" -#include "gfx_es2/gl_state.h" // TODO: Get rid of this from here #include "gfx_es2/draw_text.h" +#include "gfx_es2/gpu_features.h" #include "gfx/gl_lost_manager.h" #include "gfx/texture.h" #include "i18n/i18n.h" @@ -85,9 +85,6 @@ #include "EmuScreen.h" #include "GameInfoCache.h" #include "HostTypes.h" -#ifdef _WIN32 -#include "GPU/Directx9/helper/dx_state.h" -#endif #include "UI/OnScreenDisplay.h" #include "UI/MiscScreens.h" #include "UI/TiltEventProcessor.h" @@ -571,11 +568,6 @@ void NativeInitGraphics() { screenManager->setUIContext(uiContext); screenManager->setThin3DContext(thin3d); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - #ifdef _WIN32 winAudioBackend = CreateAudioBackend((AudioBackendType)g_Config.iAudioBackend); winAudioBackend->Init(MainWindow::GetHWND(), &Win32Mix, 44100); @@ -684,19 +676,6 @@ void NativeRender() { viewport.MaxDepth = 1.0; viewport.MinDepth = 0.0; thin3d->SetViewports(1, &viewport); - - if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) { - glstate.depthWrite.set(GL_TRUE); - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glstate.Restore(); - } else { -#ifdef _WIN32 - DX9::dxstate.depthWrite.set(true); - DX9::dxstate.colorMask.set(true, true, true, true); - DX9::dxstate.Restore(); -#endif - } - thin3d->SetTargetSize(pixel_xres, pixel_yres); float xres = dp_xres; @@ -727,17 +706,6 @@ void NativeRender() { TakeScreenshot(); } - thin3d->SetScissorEnabled(false); - if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) { - glstate.depthWrite.set(GL_TRUE); - glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } else { -#ifdef _WIN32 - DX9::dxstate.depthWrite.set(true); - DX9::dxstate.colorMask.set(true, true, true, true); -#endif - } - if (resized) { resized = false; if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) { @@ -780,7 +748,6 @@ void NativeDeviceLost() { if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) { gl_lost(); - glstate.Restore(); } // Should dirty EVERYTHING } diff --git a/Windows/OpenGLBase.cpp b/Windows/OpenGLBase.cpp index a2e0075273..572fb95ed9 100644 --- a/Windows/OpenGLBase.cpp +++ b/Windows/OpenGLBase.cpp @@ -1,6 +1,6 @@ #include "Common/CommonWindows.h" -#include "native/gfx_es2/gl_state.h" #include "native/gfx/gl_common.h" +#include "native/gfx_es2/gpu_features.h" #include "GL/gl.h" #include "GL/wglew.h" #include "Core/Config.h" @@ -237,7 +237,6 @@ bool GL_Init(HWND window, std::string *error_message) { return false; } - if (!m_hrc) { *error_message = "No m_hrc"; return false; @@ -245,7 +244,6 @@ bool GL_Init(HWND window, std::string *error_message) { hRC = m_hrc; - glstate.Initialize(); if (wglSwapIntervalEXT) wglSwapIntervalEXT(0); if (enableGLDebug && glewIsSupported("GL_ARB_debug_output")) { diff --git a/android/jni/TestRunner.cpp b/android/jni/TestRunner.cpp index ab96ef612f..80f0266f28 100644 --- a/android/jni/TestRunner.cpp +++ b/android/jni/TestRunner.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - // TO USE: // Simply copy pspautotests to the root of the USB memory / SD card of your android device. // Then go to Settings / Developer Menu / Run CPU tests. @@ -29,7 +28,7 @@ #include "base/basictypes.h" #include "base/display.h" #include "base/logging.h" -#include "gfx_es2/gl_state.h" +#include "gfx/gl_common.h" #include "Core/Core.h" #include "Core/System.h" @@ -38,7 +37,6 @@ #include "Core/MIPS/MIPS.h" #include "TestRunner.h" - static const char * const testsToRun[] = { "cpu/cpu_alu/cpu_alu", "cpu/fpu/fpu", @@ -153,8 +151,7 @@ void RunTests() } PSP_Shutdown(); } - glstate.Restore(); - glstate.viewport.set(0,0,pixel_xres,pixel_yres); + glViewport(0,0,pixel_xres,pixel_yres); PSP_CoreParameter().pixelWidth = pixel_xres; PSP_CoreParameter().pixelHeight = pixel_yres; PSP_CoreParameter().headLess = false; diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 9fddc19d8a..a2977d5cab 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -28,7 +28,6 @@ #include "GPU/GPUState.h" #include "base/logging.h" -#include "gfx_es2/gl_state.h" #include "gfx/gl_common.h" #include "file/vfs.h" #include "file/zip_read.h" @@ -40,8 +39,7 @@ const int WINDOW_HEIGHT = 272; typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int value); PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = NULL; -HWND CreateHiddenWindow() -{ +HWND CreateHiddenWindow() { static WNDCLASSEX wndClass = { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_OWNDC, @@ -187,7 +185,6 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message) SetVSync(0); glewInit(); - glstate.Initialize(); LoadNativeAssets(); @@ -218,8 +215,7 @@ bool WindowsHeadlessHost::ResizeGL() RECT rc; GetWindowRect(hWnd, &rc); - glstate.viewport.set(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glstate.viewport.restore(); + glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, WINDOW_WIDTH, WINDOW_HEIGHT, 0.0f, -1.0f, 1.0f); diff --git a/native b/native index e875f0a0c3..3f05c8d990 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit e875f0a0c3932fb7b80846e78c318fa36b2b5c6f +Subproject commit 3f05c8d99031931149a072c64cae51eb5635202b From d822cbf60b7bdfc6de8ec50ec893ee6b6ce3e79c Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 6 Sep 2015 13:05:18 +0200 Subject: [PATCH 2/8] Move fbo.cpp/h from native into PPSSPP --- CMakeLists.txt | 4 +- GPU/Directx9/FramebufferDX9.cpp | 2 +- GPU/Directx9/FramebufferDX9.h | 2 +- GPU/Directx9/GPU_DX9.h | 2 +- GPU/Directx9/StencilBufferDX9.cpp | 2 +- GPU/Directx9/TextureCacheDX9.h | 2 +- GPU/Directx9/helper/{fbo.cpp => dx_fbo.cpp} | 19 +- GPU/Directx9/helper/{fbo.h => dx_fbo.h} | 17 + GPU/Directx9/helper/global.cpp | 6 +- GPU/GLES/FBO.cpp | 430 ++++++++++++++++++++ GPU/GLES/FBO.h | 66 +++ GPU/GLES/Framebuffer.cpp | 2 +- GPU/GLES/Framebuffer.h | 4 +- GPU/GLES/GLES_GPU.h | 3 +- GPU/GLES/TextureCache.h | 2 +- GPU/GPU.vcxproj | 6 +- GPU/GPU.vcxproj.filters | 18 +- Qt/Debugger/debugger_displaylist.h | 4 +- Qt/GPU.pro | 1 + UI/EmuScreen.cpp | 2 +- Windows/D3D9Base.cpp | 2 +- android/jni/Android.mk | 1 + headless/WindowsHeadlessHostDx9.cpp | 2 +- ios/ViewController.mm | 2 +- native | 2 +- 25 files changed, 573 insertions(+), 30 deletions(-) rename GPU/Directx9/helper/{fbo.cpp => dx_fbo.cpp} (83%) rename GPU/Directx9/helper/{fbo.h => dx_fbo.h} (66%) create mode 100644 GPU/GLES/FBO.cpp create mode 100644 GPU/GLES/FBO.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 515761f6d4..08c83a569e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -923,8 +923,6 @@ add_library(native STATIC native/gfx_es2/draw_buffer.h native/gfx_es2/draw_text.cpp native/gfx_es2/draw_text.h - native/gfx_es2/fbo.cpp - native/gfx_es2/fbo.h native/gfx_es2/gl_state.cpp native/gfx_es2/gl_state.h native/gfx_es2/gpu_features.cpp @@ -1485,6 +1483,8 @@ add_library(GPU OBJECT GPU/Debugger/Stepping.h GPU/GLES/DepalettizeShader.cpp GPU/GLES/DepalettizeShader.h + GPU/GLES/FBO.cpp + GPU/GLES/FBO.h GPU/GLES/GLES_GPU.cpp GPU/GLES/GLES_GPU.h GPU/GLES/FragmentShaderGenerator.cpp diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 8d1349f74f..89d7b930ba 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -28,7 +28,7 @@ #include "GPU/Debugger/Stepping.h" #include "helper/dx_state.h" -#include "helper/fbo.h" +#include "helper/dx_fbo.h" #include "GPU/Common/FramebufferCommon.h" #include "GPU/Common/TextureDecoder.h" diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index cf41991731..f577340838 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -23,7 +23,7 @@ #include "d3d9.h" -#include "GPU/Directx9/helper/fbo.h" +#include "GPU/Directx9/helper/dx_fbo.h" // Keeps track of allocated FBOs. // Also provides facilities for drawing and later converting raw // pixel data. diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index 0fc3fb929f..bdf5384b99 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -25,7 +25,7 @@ #include "GPU/Directx9/TransformPipelineDX9.h" #include "GPU/Directx9/TextureCacheDX9.h" #include "GPU/Directx9/DepalettizeShaderDX9.h" -#include "GPU/Directx9/helper/fbo.h" +#include "GPU/Directx9/helper/dx_fbo.h" #include "GPU/Common/VertexDecoderCommon.h" namespace DX9 { diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 22e512ef3c..11cfa72069 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -18,7 +18,7 @@ #include "base/logging.h" #include "helper/dx_state.h" -#include "helper/fbo.h" +#include "helper/dx_fbo.h" #include "Core/Reporting.h" #include "GPU/Directx9/FramebufferDX9.h" #include "GPU/Directx9/PixelShaderGeneratorDX9.h" diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index eb25632717..f24399de6d 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -21,7 +21,7 @@ #include "../Globals.h" #include "helper/global.h" -#include "helper/fbo.h" +#include "helper/dx_fbo.h" #include "GPU/GPU.h" #include "GPU/GPUInterface.h" #include "GPU/Directx9/TextureScalerDX9.h" diff --git a/GPU/Directx9/helper/fbo.cpp b/GPU/Directx9/helper/dx_fbo.cpp similarity index 83% rename from GPU/Directx9/helper/fbo.cpp rename to GPU/Directx9/helper/dx_fbo.cpp index 1edff95ba5..87e17c0695 100644 --- a/GPU/Directx9/helper/fbo.cpp +++ b/GPU/Directx9/helper/dx_fbo.cpp @@ -1,9 +1,26 @@ +// 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 "global.h" #include #include #include #include "base/logging.h" -#include "fbo.h" +#include "dx_fbo.h" #include "dx_state.h" struct FBO { diff --git a/GPU/Directx9/helper/fbo.h b/GPU/Directx9/helper/dx_fbo.h similarity index 66% rename from GPU/Directx9/helper/fbo.h rename to GPU/Directx9/helper/dx_fbo.h index c19d3de1fa..4ce1561388 100644 --- a/GPU/Directx9/helper/fbo.h +++ b/GPU/Directx9/helper/dx_fbo.h @@ -1,3 +1,20 @@ +// 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/. + #pragma once // Simple wrapper around FBO functionality. diff --git a/GPU/Directx9/helper/global.cpp b/GPU/Directx9/helper/global.cpp index 1864b31f4f..d814cb3211 100644 --- a/GPU/Directx9/helper/global.cpp +++ b/GPU/Directx9/helper/global.cpp @@ -1,5 +1,7 @@ -#include "global.h" -#include "fbo.h" + + +#include "GPU/Directx9/helper/global.h" +#include "GPU/Directx9/helper/dx_fbo.h" #include "thin3d/d3dx9_loader.h" #include "Common/CommonFuncs.h" diff --git a/GPU/GLES/FBO.cpp b/GPU/GLES/FBO.cpp new file mode 100644 index 0000000000..5465723133 --- /dev/null +++ b/GPU/GLES/FBO.cpp @@ -0,0 +1,430 @@ +// 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 "base/logging.h" +#include "gfx/gl_common.h" +#include "gfx_es2/gl_state.h" + +#include "GPU/GLES/FBO.h" + +#ifdef IOS +extern void bindDefaultFBO(); +#endif + +struct FBO { + GLuint handle; + GLuint color_texture; + GLuint z_stencil_buffer; // Either this is set, or the two below. + GLuint z_buffer; + GLuint stencil_buffer; + + int width; + int height; + FBOColorDepth colorDepth; + bool native_fbo; +}; + +static FBO *g_overriddenBackbuffer; + +static GLuint currentDrawHandle_ = 0; +static GLuint currentReadHandle_ = 0; + +// On PC, we always use GL_DEPTH24_STENCIL8. +// On Android, we try to use what's available. + +#ifndef USING_GLES2 +FBO *fbo_ext_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth) { + FBO *fbo = new FBO(); + fbo->native_fbo = false; + fbo->width = width; + fbo->height = height; + fbo->colorDepth = colorDepth; + + // Color texture is same everywhere + glGenFramebuffersEXT(1, &fbo->handle); + glGenTextures(1, &fbo->color_texture); + + // Create the surfaces. + glBindTexture(GL_TEXTURE_2D, fbo->color_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // TODO: We could opt to only create 16-bit render targets on slow devices. For later. + switch (colorDepth) { + case FBO_8888: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + break; + case FBO_4444: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL); + break; + case FBO_5551: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL); + break; + case FBO_565: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); + break; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + // 24-bit Z, 8-bit stencil + glGenRenderbuffersEXT(1, &fbo->z_stencil_buffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, width, height); + //glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, width, height); + + // Bind it all together + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo->color_texture, 0); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->z_stencil_buffer); + + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + switch(status) { + case GL_FRAMEBUFFER_COMPLETE_EXT: + // ILOG("Framebuffer verified complete."); + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); + break; + default: + FLOG("Other framebuffer error: %i", status); + break; + } + // Unbind state we don't need + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + currentDrawHandle_ = fbo->handle; + currentReadHandle_ = fbo->handle; + return fbo; +} +#endif + +int fbo_check_framebuffer_status(FBO *fbo) { + GLenum fbStatus; +#ifndef USING_GLES2 + if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) { + fbStatus = glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER); + } else if (gl_extensions.ARB_framebuffer_object) { + fbStatus = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + } else { + fbStatus = 0; + } +#else + fbStatus = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); +#endif + return (int)fbStatus; +} + +FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth) { + CheckGLExtensions(); + +#ifndef USING_GLES2 + if (!gl_extensions.ARB_framebuffer_object && gl_extensions.EXT_framebuffer_object) { + return fbo_ext_create(width, height, num_color_textures, z_stencil, colorDepth); + } else if (!gl_extensions.ARB_framebuffer_object) { + return nullptr; + } + // If GLES2, we have basic FBO support and can just proceed. +#endif + + FBO *fbo = new FBO(); + fbo->native_fbo = false; + fbo->width = width; + fbo->height = height; + fbo->colorDepth = colorDepth; + + // Color texture is same everywhere + glGenFramebuffers(1, &fbo->handle); + glGenTextures(1, &fbo->color_texture); + + // Create the surfaces. + glBindTexture(GL_TEXTURE_2D, fbo->color_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // TODO: We could opt to only create 16-bit render targets on slow devices. For later. + switch (colorDepth) { + case FBO_8888: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + break; + case FBO_4444: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NULL); + break; + case FBO_5551: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, NULL); + break; + case FBO_565: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); + break; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if (gl_extensions.IsGLES) { + if (gl_extensions.OES_packed_depth_stencil) { + ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", width, height); + // Standard method + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + // 24-bit Z, 8-bit stencil combined + glGenRenderbuffers(1, &fbo->z_stencil_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + } else { + ILOG("Creating %i x %i FBO using separate stencil", width, height); + // TEGRA + fbo->z_stencil_buffer = 0; + // 16/24-bit Z, separate 8-bit stencil + glGenRenderbuffers(1, &fbo->z_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_buffer); + glRenderbufferStorage(GL_RENDERBUFFER, gl_extensions.OES_depth24 ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16, width, height); + + // 8-bit stencil buffer + glGenRenderbuffers(1, &fbo->stencil_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->stencil_buffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height); + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer); + } + } else { + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + // 24-bit Z, 8-bit stencil + glGenRenderbuffers(1, &fbo->z_stencil_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, fbo->z_stencil_buffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch(status) { + case GL_FRAMEBUFFER_COMPLETE: + // ILOG("Framebuffer verified complete."); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); + break; + default: + FLOG("Other framebuffer error: %i", status); + break; + } + // Unbind state we don't need + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + currentDrawHandle_ = fbo->handle; + currentReadHandle_ = fbo->handle; + return fbo; +} + +FBO *fbo_create_from_native_fbo(GLuint native_fbo, FBO *fbo) +{ + if (!fbo) + fbo = new FBO(); + + fbo->native_fbo = true; + fbo->handle = native_fbo; + fbo->color_texture = 0; + fbo->z_stencil_buffer = 0; + fbo->z_buffer = 0; + fbo->stencil_buffer = 0; + fbo->width = 0; + fbo->height = 0; + fbo->colorDepth = FBO_8888; + + return fbo; +} + +static GLenum fbo_get_fb_target(bool read, GLuint **cached) { + bool supportsBlit = gl_extensions.ARB_framebuffer_object; + if (gl_extensions.IsGLES) { + supportsBlit = (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit); + } + + // Note: GL_FRAMEBUFFER_EXT and GL_FRAMEBUFFER have the same value, same with _NV. + if (supportsBlit) { + if (read) { + *cached = ¤tReadHandle_; + return GL_READ_FRAMEBUFFER; + } else { + *cached = ¤tDrawHandle_; + return GL_DRAW_FRAMEBUFFER; + } + } else { + *cached = ¤tDrawHandle_; + return GL_FRAMEBUFFER; + } +} + +static void fbo_bind_fb_target(bool read, GLuint name) { + GLuint *cached; + GLenum target = fbo_get_fb_target(read, &cached); + + if (*cached != name) { + if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { + glBindFramebuffer(target, name); + } else { +#ifndef USING_GLES2 + glBindFramebufferEXT(target, name); +#endif + } + *cached = name; + } +} + +void fbo_unbind() { + if (g_overriddenBackbuffer) { + fbo_bind_as_render_target(g_overriddenBackbuffer); + return; + } + + CheckGLExtensions(); +#ifndef USING_GLES2 + if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } else if (gl_extensions.EXT_framebuffer_object) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } +#else + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif + +#ifdef IOS + bindDefaultFBO(); +#endif + + currentDrawHandle_ = 0; + currentReadHandle_ = 0; +} + +void fbo_override_backbuffer(FBO *fbo) { + g_overriddenBackbuffer = fbo; +} + +void fbo_bind_as_render_target(FBO *fbo) { + // Without FBO_ARB / GLES3, this will collide with bind_for_read, but there's nothing + // in ES 2.0 that actually separate them anyway of course, so doesn't matter. + fbo_bind_fb_target(false, fbo->handle); + // Always restore viewport after render target binding + glstate.viewport.restore(); +} + +void fbo_unbind_render_target() { + fbo_unbind(); +} + +// For GL_EXT_FRAMEBUFFER_BLIT and similar. +void fbo_bind_for_read(FBO *fbo) { + fbo_bind_fb_target(true, fbo->handle); +} + +void fbo_unbind_read() { + fbo_bind_fb_target(true, 0); +} + +void fbo_bind_color_as_texture(FBO *fbo, int color) { + if (fbo) { + glBindTexture(GL_TEXTURE_2D, fbo->color_texture); + } +} + +void fbo_destroy(FBO *fbo) { + if (fbo->native_fbo) { + delete fbo; + return; + } + + if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &fbo->handle); + glDeleteRenderbuffers(1, &fbo->z_stencil_buffer); + glDeleteRenderbuffers(1, &fbo->z_buffer); + glDeleteRenderbuffers(1, &fbo->stencil_buffer); + } else if (gl_extensions.EXT_framebuffer_object) { +#ifndef USING_GLES2 + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->handle); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glDeleteFramebuffersEXT(1, &fbo->handle); + glDeleteRenderbuffersEXT(1, &fbo->z_stencil_buffer); +#endif + } + + currentDrawHandle_ = 0; + currentReadHandle_ = 0; + + glDeleteTextures(1, &fbo->color_texture); + delete fbo; +} + +void fbo_get_dimensions(FBO *fbo, int *w, int *h) { + *w = fbo->width; + *h = fbo->height; +} + +int fbo_get_color_texture(FBO *fbo) { + return fbo->color_texture; +} + +int fbo_get_depth_buffer(FBO *fbo) { + return fbo->z_buffer; +} + +int fbo_get_stencil_buffer(FBO *fbo) { + return fbo->stencil_buffer; +} diff --git a/GPU/GLES/FBO.h b/GPU/GLES/FBO.h new file mode 100644 index 0000000000..24c06cb13a --- /dev/null +++ b/GPU/GLES/FBO.h @@ -0,0 +1,66 @@ +// 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/. + +#pragma once + +// Simple wrapper around FBO functionality. +// Very C-ish API because that's what I felt like, and it's cool to completely +// hide the data from callers... + +#include "gfx/gl_common.h" + +struct FBO; + + +enum FBOColorDepth { + FBO_8888, + FBO_565, + FBO_4444, + FBO_5551, +}; + + +// Creates a simple FBO with a RGBA32 color buffer stored in a texture, and +// optionally an accompanying Z/stencil buffer. +// No mipmap support. +// num_color_textures must be 1 for now. +// you lose bound texture state. + +// On some hardware, you might get a 24-bit depth buffer even though you only wanted a 16-bit one. +FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, FBOColorDepth colorDepth = FBO_8888); + +// Create an opaque FBO from a native GL FBO, optionally reusing an existing FBO structure. +// Useful for overriding the backbuffer FBO that is generated outside of this wrapper. +FBO *fbo_create_from_native_fbo(GLuint native_fbo, FBO *fbo = NULL); +int fbo_check_framebuffer_status(FBO *fbo); + +// These functions should be self explanatory. +void fbo_bind_as_render_target(FBO *fbo); +// color must be 0, for now. +void fbo_bind_color_as_texture(FBO *fbo, int color); +void fbo_bind_for_read(FBO *fbo); +void fbo_unbind(); +void fbo_unbind_render_target(); +void fbo_unbind_read(); +void fbo_destroy(FBO *fbo); +void fbo_get_dimensions(FBO *fbo, int *w, int *h); + +int fbo_get_color_texture(FBO *fbo); +int fbo_get_depth_buffer(FBO *fbo); +int fbo_get_stencil_buffer(FBO *fbo); + +void fbo_override_backbuffer(FBO *fbo); // Makes unbind bind this instead of the real backbuffer. diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 8164547c5c..4f2b4fe840 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -22,7 +22,6 @@ #include "gfx_es2/glsl_program.h" #include "gfx_es2/gl_state.h" -#include "gfx_es2/fbo.h" #include "base/timeutil.h" #include "math/lin/matrix4x4.h" @@ -41,6 +40,7 @@ #include "GPU/Common/TextureDecoder.h" #include "GPU/Common/FramebufferCommon.h" #include "GPU/Debugger/Stepping.h" +#include "GPU/GLES/FBO.h" #include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/TextureCache.h" #include "GPU/GLES/TransformPipeline.h" diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 341f4b19bc..1b39d0e20d 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -22,14 +22,14 @@ #include #include "gfx/gl_common.h" -#include "gfx_es2/fbo.h" // Keeps track of allocated FBOs. // Also provides facilities for drawing and later converting raw // pixel data. -#include "../Globals.h" +#include "Globals.h" #include "GPU/GPUCommon.h" +#include "GPU/GLES/FBO.h" #include "GPU/Common/FramebufferCommon.h" #include "Core/Config.h" diff --git a/GPU/GLES/GLES_GPU.h b/GPU/GLES/GLES_GPU.h index a40090e85e..f71df08d88 100644 --- a/GPU/GLES/GLES_GPU.h +++ b/GPU/GLES/GLES_GPU.h @@ -20,9 +20,8 @@ #include #include -#include "gfx_es2/fbo.h" - #include "GPU/GPUCommon.h" +#include "GPU/GLES/FBO.h" #include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/TransformPipeline.h" #include "GPU/GLES/TextureCache.h" diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 9b7a9593ac..bc9cd034f3 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -19,12 +19,12 @@ #include -#include "gfx_es2/fbo.h" #include "gfx_es2/gpu_features.h" #include "Globals.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" +#include "GPU/GLES/FBO.h" #include "GPU/GLES/TextureScaler.h" #include "GPU/Common/TextureCacheCommon.h" diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 0117fc4505..cd8ef72cf3 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -204,7 +204,7 @@ - + @@ -217,6 +217,7 @@ + @@ -278,7 +279,7 @@ - + @@ -291,6 +292,7 @@ + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index bc8fa1fb20..493bf25451 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -126,9 +126,6 @@ DirectX9\helper - - DirectX9\helper - DirectX9\helper @@ -186,6 +183,12 @@ Common + + GLES + + + DirectX9\helper + @@ -284,9 +287,6 @@ DirectX9\helper - - DirectX9\helper - DirectX9\helper @@ -359,5 +359,11 @@ Common + + GLES + + + DirectX9\helper + \ No newline at end of file diff --git a/Qt/Debugger/debugger_displaylist.h b/Qt/Debugger/debugger_displaylist.h index f2ccf6b2cd..ce68d1079a 100644 --- a/Qt/Debugger/debugger_displaylist.h +++ b/Qt/Debugger/debugger_displaylist.h @@ -2,10 +2,12 @@ #define DEBUGGER_DISPLAYLIST_H #include "Core/Debugger/DebugInterface.h" + #include #include + #include "GPU/GPUState.h" -#include "native/gfx_es2/fbo.h" +#include "GPU/GLES/FBO.h" class MainWindow; namespace Ui { diff --git a/Qt/GPU.pro b/Qt/GPU.pro index f8a1a307dd..a5d7206776 100644 --- a/Qt/GPU.pro +++ b/Qt/GPU.pro @@ -27,6 +27,7 @@ SOURCES += $$P/GPU/GeDisasm.cpp \ # GPU $$P/GPU/GPUState.cpp \ $$P/GPU/Math3D.cpp \ $$P/GPU/Null/NullGpu.cpp \ + $$P/GPU/GLES/FBO.cpp \ $$P/GPU/GLES/DepalettizeShader.cpp \ $$P/GPU/GLES/FragmentShaderGenerator.cpp \ $$P/GPU/GLES/FragmentTestCache.cpp \ diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 213a210367..c2aeb4927f 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -25,7 +25,6 @@ #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" -#include "gfx_es2/fbo.h" #include "input/input_state.h" #include "ui/ui.h" @@ -43,6 +42,7 @@ #include "Core/System.h" #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" +#include "GPU/GLES/FBO.h" #include "GPU/GLES/Framebuffer.h" #include "Core/HLE/sceCtrl.h" #include "Core/HLE/sceDisplay.h" diff --git a/Windows/D3D9Base.cpp b/Windows/D3D9Base.cpp index 7363ebfd70..9733f9fa19 100644 --- a/Windows/D3D9Base.cpp +++ b/Windows/D3D9Base.cpp @@ -3,7 +3,7 @@ #include #include "GPU/Directx9/helper/global.h" -#include "GPU/Directx9/helper/fbo.h" +#include "GPU/Directx9/helper/dx_fbo.h" #include "base/logging.h" #include "util/text/utf8.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 1f81df8120..ef9ad6d65a 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -170,6 +170,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/GLES/Framebuffer.cpp \ $(SRC)/GPU/GLES/DepalettizeShader.cpp \ $(SRC)/GPU/GLES/GLES_GPU.cpp.arm \ + $(SRC)/GPU/GLES/FBO.cpp \ $(SRC)/GPU/GLES/StencilBuffer.cpp.arm \ $(SRC)/GPU/GLES/TextureCache.cpp.arm \ $(SRC)/GPU/GLES/TransformPipeline.cpp.arm \ diff --git a/headless/WindowsHeadlessHostDx9.cpp b/headless/WindowsHeadlessHostDx9.cpp index da9260c89f..4fbb57021f 100644 --- a/headless/WindowsHeadlessHostDx9.cpp +++ b/headless/WindowsHeadlessHostDx9.cpp @@ -25,7 +25,7 @@ #include "base/logging.h" #include "thin3d/d3dx9_loader.h" #include "GPU/Directx9/helper/global.h" -#include "GPU/Directx9/helper/fbo.h" +#include "GPU/Directx9/helper/dx_fbo.h" #include "file/vfs.h" #include "file/zip_read.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index ee1682aa66..944f6ad035 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -18,7 +18,7 @@ #include "input/keycodes.h" #include "Core/Config.h" -#include "gfx_es2/fbo.h" +#include "GPU/GLES/FBO.h" #define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) #define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) diff --git a/native b/native index 3f05c8d990..f78c4f6f84 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 3f05c8d99031931149a072c64cae51eb5635202b +Subproject commit f78c4f6f84a5beea8c82040a1c169512bc857242 From 08735b806f975f634cbe1db723bf5c85389e80a4 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 6 Sep 2015 13:36:33 +0200 Subject: [PATCH 3/8] Remove silly use of gstate.SetVSyncInterval --- GPU/GLES/GLES_GPU.cpp | 11 +++++++++-- GPU/GLES/TransformPipeline.cpp | 4 ---- Windows/OpenGLBase.cpp | 29 +++++++++++++++++++++++++++-- Windows/OpenGLBase.h | 1 + headless/Headless.cpp | 1 + headless/WindowsHeadlessHost.cpp | 25 +++++-------------------- native | 2 +- unittest/UnitTest.cpp | 1 + 8 files changed, 45 insertions(+), 29 deletions(-) diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index 07e899506d..c29eb499f8 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -45,6 +45,10 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceGe.h" +#ifdef _WIN32 +#include "Windows/OpenGLBase.h" +#endif + enum { FLAG_FLUSHBEFORE = 1, FLAG_FLUSHBEFOREONCHANGE = 2, @@ -463,7 +467,10 @@ GLES_GPU::~GLES_GPU() { fragmentTestCache_.Clear(); delete shaderManager_; shaderManager_ = nullptr; - glstate.SetVSyncInterval(0); + +#ifdef _WIN32 + GL_SwapInterval(0); +#endif } // Take the raw GL extension and versioning data and turn into feature flags. @@ -649,7 +656,7 @@ inline void GLES_GPU::UpdateVsyncInterval(bool force) { // // See http://developer.download.nvidia.com/opengl/specs/WGL_EXT_swap_control_tear.txt // glstate.SetVSyncInterval(-desiredVSyncInterval); //} else { - glstate.SetVSyncInterval(desiredVSyncInterval); + GL_SwapInterval(desiredVSyncInterval); //} lastVsync_ = desiredVSyncInterval; } diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index a3a8b8b7f6..f47599c4ee 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -593,7 +593,6 @@ void TransformDrawEngine::DoFlush() { if (vshader->UseHWTransform()) { GLuint vbo = 0, ebo = 0; int vertexCount = 0; - int maxIndex = 0; // Compiler warns about this because it's only used in the #ifdeffed out RangeElements path. bool useElements = true; // Cannot cache vertex data with morph enabled. @@ -709,7 +708,6 @@ void TransformDrawEngine::DoFlush() { vbo = vai->vbo; ebo = vai->ebo; vertexCount = vai->numVerts; - maxIndex = vai->maxIndex; prim = static_cast(vai->prim); break; } @@ -728,7 +726,6 @@ void TransformDrawEngine::DoFlush() { glstate.arrayBuffer.bind(vbo); glstate.elementArrayBuffer.bind(ebo); vertexCount = vai->numVerts; - maxIndex = vai->maxIndex; prim = static_cast(vai->prim); gstate_c.vertexFullAlpha = vai->flags & VAI_FLAG_VERTEXFULLALPHA; @@ -754,7 +751,6 @@ rotateVBO: gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); useElements = !indexGen.SeenOnlyPurePrims(); vertexCount = indexGen.VertexCount(); - maxIndex = indexGen.MaxIndex(); if (!useElements && indexGen.PureCount()) { vertexCount = indexGen.PureCount(); } diff --git a/Windows/OpenGLBase.cpp b/Windows/OpenGLBase.cpp index 572fb95ed9..b154562875 100644 --- a/Windows/OpenGLBase.cpp +++ b/Windows/OpenGLBase.cpp @@ -1,3 +1,23 @@ +// 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/. + +// TODO: What a mess this is :( + +#include "Common/Log.h" #include "Common/CommonWindows.h" #include "native/gfx/gl_common.h" #include "native/gfx_es2/gpu_features.h" @@ -244,8 +264,8 @@ bool GL_Init(HWND window, std::string *error_message) { hRC = m_hrc; - if (wglSwapIntervalEXT) - wglSwapIntervalEXT(0); + GL_SwapInterval(0); + if (enableGLDebug && glewIsSupported("GL_ARB_debug_output")) { glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); // print debug output to stderr glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); @@ -253,6 +273,11 @@ bool GL_Init(HWND window, std::string *error_message) { return true; // Success } +void GL_SwapInterval(int interval) { + if (wglSwapIntervalEXT) + wglSwapIntervalEXT(0); +} + void GL_Shutdown() { if (hRC) { // Are we able to release the DC and RC contexts? diff --git a/Windows/OpenGLBase.h b/Windows/OpenGLBase.h index e103ece39e..51a15418bc 100644 --- a/Windows/OpenGLBase.h +++ b/Windows/OpenGLBase.h @@ -4,4 +4,5 @@ bool GL_Init(HWND window, std::string *error_message); void GL_Shutdown(); +void GL_SwapInterval(int interval); void GL_SwapBuffers(); diff --git a/headless/Headless.cpp b/headless/Headless.cpp index d15a881830..8b6d2d29d2 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -70,6 +70,7 @@ struct InputState; // Temporary hacks around annoying linking errors. void D3D9_SwapBuffers() { } void GL_SwapBuffers() { } +void GL_SwapInterval(int) { } void NativeUpdate(InputState &input_state) { } void NativeRender() { } void NativeResized() { } diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index a2977d5cab..0342ce6d5f 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -15,17 +15,18 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include + #include "WindowsHeadlessHost.h" #include "Compare.h" -#include #include "Common/CommonWindows.h" -#include #include "Core/CoreParameter.h" #include "Core/System.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/GPUState.h" +#include "Windows/OpenGLBase.h" #include "base/logging.h" #include "gfx/gl_common.h" @@ -36,9 +37,6 @@ const bool WINDOW_VISIBLE = false; const int WINDOW_WIDTH = 480; const int WINDOW_HEIGHT = 272; -typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int value); -PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = NULL; - HWND CreateHiddenWindow() { static WNDCLASSEX wndClass = { sizeof(WNDCLASSEX), @@ -60,18 +58,6 @@ HWND CreateHiddenWindow() { return CreateWindowEx(0, _T("PPSSPPHeadless"), _T("PPSSPPHeadless"), style, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, NULL, NULL); } -void SetVSync(int value) -{ - const char *extensions = (const char *) glGetString(GL_EXTENSIONS); - - if (!strstr(extensions, "WGL_EXT_swap_control")) - return; - - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC) wglGetProcAddress("wglSwapIntervalEXT"); - if (wglSwapIntervalEXT != NULL) - wglSwapIntervalEXT(value); -} - void WindowsHeadlessHost::LoadNativeAssets() { VFSRegister("", new DirectoryAssetReader("assets/")); @@ -182,7 +168,7 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message) ENFORCE(hRC = wglCreateContext(hDC), "Unable to create GL context."); ENFORCE(wglMakeCurrent(hDC, hRC), "Unable to activate GL context."); - SetVSync(0); + GL_SwapInterval(0); glewInit(); @@ -193,8 +179,7 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message) void WindowsHeadlessHost::ShutdownGraphics() { - if (hRC) - { + if (hRC) { wglMakeCurrent(NULL, NULL); wglDeleteContext(hRC); hRC = NULL; diff --git a/native b/native index f78c4f6f84..65e3d31e24 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit f78c4f6f84a5beea8c82040a1c169512bc857242 +Subproject commit 65e3d31e249ca811809121529f1971e408c154d3 diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 2b0b4c48ed..233d247ec4 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -48,6 +48,7 @@ std::string System_GetProperty(SystemProperty prop) { return ""; } int System_GetPropertyInt(SystemProperty prop) { return -1; } void NativeMessageReceived(const char *message, const char *value) {} +void GL_SwapInterval(int) {} #define M_PI_2 1.57079632679489661923 From ab3468ea027384b6713990f7f6dd46a3ccc10134 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 6 Sep 2015 13:45:17 +0200 Subject: [PATCH 4/8] Move native/gfx_es2/gl_state.cpp/h into GPU/GLES/GLStateCache.cpp/h --- CMakeLists.txt | 4 +- GPU/Common/DepalettizeShaderCommon.cpp | 2 +- GPU/GLES/DepalettizeShader.cpp | 1 + GPU/GLES/DepalettizeShader.h | 2 +- GPU/GLES/FBO.cpp | 2 +- GPU/GLES/FragmentTestCache.h | 5 +- GPU/GLES/Framebuffer.cpp | 2 +- GPU/GLES/GLES_GPU.cpp | 2 +- GPU/GLES/GLStateCache.cpp | 52 ++++++ GPU/GLES/GLStateCache.h | 240 +++++++++++++++++++++++++ GPU/GLES/ShaderManager.cpp | 2 +- GPU/GLES/StateMapping.cpp | 2 +- GPU/GLES/StencilBuffer.cpp | 2 +- GPU/GLES/TextureCache.cpp | 7 +- GPU/GLES/TransformPipeline.cpp | 2 +- GPU/GPU.vcxproj | 2 + GPU/GPU.vcxproj.filters | 6 + GPU/Software/SoftGpu.cpp | 1 - Qt/Debugger/debugger_memorytex.cpp | 2 +- native | 2 +- 20 files changed, 320 insertions(+), 20 deletions(-) create mode 100644 GPU/GLES/GLStateCache.cpp create mode 100644 GPU/GLES/GLStateCache.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 08c83a569e..19b16ba0df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -923,8 +923,6 @@ add_library(native STATIC native/gfx_es2/draw_buffer.h native/gfx_es2/draw_text.cpp native/gfx_es2/draw_text.h - native/gfx_es2/gl_state.cpp - native/gfx_es2/gl_state.h native/gfx_es2/gpu_features.cpp native/gfx_es2/gpu_features.h native/gfx_es2/glsl_program.cpp @@ -1487,6 +1485,8 @@ add_library(GPU OBJECT GPU/GLES/FBO.h GPU/GLES/GLES_GPU.cpp GPU/GLES/GLES_GPU.h + GPU/GLES/GLStateCache.cpp + GPU/GLES/GLStateCache.h GPU/GLES/FragmentShaderGenerator.cpp GPU/GLES/FragmentShaderGenerator.h GPU/GLES/FragmentTestCache.cpp diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index a6e52bdb4a..721fdf18a3 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -17,10 +17,10 @@ #include -#include "gfx_es2/gl_state.h" #include "Common/Log.h" #include "Core/Reporting.h" #include "GPU/GPUState.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/Common/DepalettizeShaderCommon.h" diff --git a/GPU/GLES/DepalettizeShader.cpp b/GPU/GLES/DepalettizeShader.cpp index 1a2859aa2c..d82191c83e 100644 --- a/GPU/GLES/DepalettizeShader.cpp +++ b/GPU/GLES/DepalettizeShader.cpp @@ -22,6 +22,7 @@ #include "Core/Reporting.h" #include "DepalettizeShader.h" #include "GPU/GLES/TextureCache.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/Common/DepalettizeShaderCommon.h" static const int DEPAL_TEXTURE_OLD_AGE = 120; diff --git a/GPU/GLES/DepalettizeShader.h b/GPU/GLES/DepalettizeShader.h index 82479b8cff..1916d43df4 100644 --- a/GPU/GLES/DepalettizeShader.h +++ b/GPU/GLES/DepalettizeShader.h @@ -18,7 +18,7 @@ #include #include "Common/CommonTypes.h" -#include "gfx_es2/gl_state.h" +#include "gfx/gl_common.h" #include "GPU/ge_constants.h" class DepalShader { diff --git a/GPU/GLES/FBO.cpp b/GPU/GLES/FBO.cpp index 5465723133..889ed00767 100644 --- a/GPU/GLES/FBO.cpp +++ b/GPU/GLES/FBO.cpp @@ -19,8 +19,8 @@ #include "base/logging.h" #include "gfx/gl_common.h" -#include "gfx_es2/gl_state.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/FBO.h" #ifdef IOS diff --git a/GPU/GLES/FragmentTestCache.h b/GPU/GLES/FragmentTestCache.h index 1600161b24..31df1233d9 100644 --- a/GPU/GLES/FragmentTestCache.h +++ b/GPU/GLES/FragmentTestCache.h @@ -19,10 +19,11 @@ #include #include "Common/CommonTypes.h" -#include "gfx_es2/gl_state.h" -#include "GPU/ge_constants.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/TextureCache.h" +#include "GPU/ge_constants.h" + struct FragmentTestID { union { struct { diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 4f2b4fe840..ac1eaf7592 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -21,7 +21,6 @@ #include "profiler/profiler.h" #include "gfx_es2/glsl_program.h" -#include "gfx_es2/gl_state.h" #include "base/timeutil.h" #include "math/lin/matrix4x4.h" @@ -40,6 +39,7 @@ #include "GPU/Common/TextureDecoder.h" #include "GPU/Common/FramebufferCommon.h" #include "GPU/Debugger/Stepping.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/FBO.h" #include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/TextureCache.h" diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index c29eb499f8..ce7337026d 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -16,7 +16,6 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "base/logging.h" -#include "gfx_es2/gl_state.h" #include "profiler/profiler.h" #include "Common/ChunkFile.h" @@ -34,6 +33,7 @@ #include "GPU/GeDisasm.h" #include "GPU/Common/FramebufferCommon.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/ShaderManager.h" #include "GPU/GLES/GLES_GPU.h" #include "GPU/GLES/Framebuffer.h" diff --git a/GPU/GLES/GLStateCache.cpp b/GPU/GLES/GLStateCache.cpp new file mode 100644 index 0000000000..d4b1cd4854 --- /dev/null +++ b/GPU/GLES/GLStateCache.cpp @@ -0,0 +1,52 @@ +#include + +#include "base/logging.h" + +#include "GPU/GLES/GLStateCache.h" + +OpenGLState glstate; + +int OpenGLState::state_count = 0; + +void OpenGLState::Restore() { + int count = 0; + + blend.restore(); count++; + blendEquationSeparate.restore(); count++; + blendFuncSeparate.restore(); count++; + blendColor.restore(); count++; + + scissorTest.restore(); count++; + scissorRect.restore(); count++; + + cullFace.restore(); count++; + cullFaceMode.restore(); count++; + frontFace.restore(); count++; + + depthTest.restore(); count++; + depthRange.restore(); count++; + depthFunc.restore(); count++; + depthWrite.restore(); count++; + + colorMask.restore(); count++; + viewport.restore(); count++; + + stencilTest.restore(); count++; + stencilOp.restore(); count++; + stencilFunc.restore(); count++; + stencilMask.restore(); count++; + + dither.restore(); count++; + +#if !defined(USING_GLES2) + colorLogicOp.restore(); count++; + logicOp.restore(); count++; +#endif + + arrayBuffer.restore(); count++; + elementArrayBuffer.restore(); count++; + + if (count != state_count) { + FLOG("OpenGLState::Restore is missing some states"); + } +} diff --git a/GPU/GLES/GLStateCache.h b/GPU/GLES/GLStateCache.h new file mode 100644 index 0000000000..c1d6f2669d --- /dev/null +++ b/GPU/GLES/GLStateCache.h @@ -0,0 +1,240 @@ +#pragma once + +#include +#include +#include + +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" + +// OpenGL state cache. +// Probably only really worth it in rendering cores on weak mobile hardware. +class OpenGLState { +private: + template + class BoolState { + private: + bool _value; + public: + BoolState() : _value(init) { + OpenGLState::state_count++; + } + + inline void set(bool value) { + if (value && value != _value) { + _value = value; + glEnable(cap); + } + if (!value && value != _value) { + _value = value; + glDisable(cap); + } + } + inline void enable() { + set(true); + } + inline void disable() { + set(false); + } + operator bool() const { + return isset(); + } + inline bool isset() { + return _value; + } + void restore() { + if (_value) + glEnable(cap); + else + glDisable(cap); + } + }; + +#define STATE1(func, p1type, p1def) \ + class SavedState1_##func { \ + p1type p1; \ + public: \ + SavedState1_##func() : p1(p1def) { \ + OpenGLState::state_count++; \ + } \ + void set(p1type newp1) { \ + if (newp1 != p1) { \ + p1 = newp1; \ + func(p1); \ + } \ + } \ + void restore() { \ + func(p1); \ + } \ + } + +#define STATE2(func, p1type, p2type, p1def, p2def) \ + class SavedState2_##func { \ + p1type p1; \ + p2type p2; \ + public: \ + SavedState2_##func() : p1(p1def), p2(p2def) { \ + OpenGLState::state_count++; \ + } \ + inline void set(p1type newp1, p2type newp2) { \ + if (newp1 != p1 || newp2 != p2) { \ + p1 = newp1; \ + p2 = newp2; \ + func(p1, p2); \ + } \ + } \ + inline void restore() { \ + func(p1, p2); \ + } \ + } + +#define STATE3(func, p1type, p2type, p3type, p1def, p2def, p3def) \ + class SavedState3_##func { \ + p1type p1; \ + p2type p2; \ + p3type p3; \ + public: \ + SavedState3_##func() : p1(p1def), p2(p2def), p3(p3def) { \ + OpenGLState::state_count++; \ + } \ + inline void set(p1type newp1, p2type newp2, p3type newp3) { \ + if (newp1 != p1 || newp2 != p2 || newp3 != p3) { \ + p1 = newp1; \ + p2 = newp2; \ + p3 = newp3; \ + func(p1, p2, p3); \ + } \ + } \ + inline void restore() { \ + func(p1, p2, p3); \ + } \ + } + + #define STATE4(func, p1type, p2type, p3type, p4type, p1def, p2def, p3def, p4def) \ + class SavedState4_##func { \ + p1type p1; \ + p2type p2; \ + p3type p3; \ + p4type p4; \ + public: \ + SavedState4_##func() : p1(p1def), p2(p2def), p3(p3def), p4(p4def) { \ + OpenGLState::state_count++; \ + } \ + inline void set(p1type newp1, p2type newp2, p3type newp3, p4type newp4) { \ + if (newp1 != p1 || newp2 != p2 || newp3 != p3 || newp4 != p4) { \ + p1 = newp1; \ + p2 = newp2; \ + p3 = newp3; \ + p4 = newp4; \ + func(p1, p2, p3, p4); \ + } \ + } \ + inline void restore() { \ + func(p1, p2, p3, p4); \ + } \ + } + +#define STATEFLOAT4(func, def) \ + class SavedState4_##func { \ + float p[4]; \ + public: \ + SavedState4_##func() { \ + for (int i = 0; i < 4; i++) {p[i] = def;} \ + OpenGLState::state_count++; \ + } \ + inline void set(const float v[4]) { \ + if (memcmp(p,v,sizeof(float)*4)) { \ + memcpy(p,v,sizeof(float)*4); \ + func(p[0], p[1], p[2], p[3]); \ + } \ + } \ + inline void restore() { \ + func(p[0], p[1], p[2], p[3]); \ + } \ + } + +#define STATEBIND(func, target) \ + class SavedBind_##func_##target { \ + GLuint val_; \ + public: \ + SavedBind_##func_##target() { \ + val_ = 0; \ + OpenGLState::state_count++; \ + } \ + inline void bind(GLuint val) { \ + if (val_ != val) { \ + func(target, val); \ + val_ = val; \ + } \ + } \ + inline void unbind() { \ + bind(0); \ + } \ + inline void restore() { \ + func(target, val_); \ + } \ + } + +public: + static int state_count; + OpenGLState() {} + void Restore(); + + // When adding a state here, don't forget to add it to OpenGLState::Restore() too + + // Blending + BoolState blend; + STATE4(glBlendFuncSeparate, GLenum, GLenum, GLenum, GLenum, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) blendFuncSeparate; + + // On OpenGL ES, using minmax blend requires glBlendEquationEXT (in theory at least but I don't think it's true in practice) + STATE2(glBlendEquationSeparate, GLenum, GLenum, GL_FUNC_ADD, GL_FUNC_ADD) blendEquationSeparate; + STATEFLOAT4(glBlendColor, 1.0f) blendColor; + + // Logic Ops. Not available on OpenGL ES at all. +#if !defined(USING_GLES2) + BoolState colorLogicOp; + STATE1(glLogicOp, GLenum, GL_COPY) logicOp; +#endif + + // Dither + BoolState dither; + + // Cull Face + BoolState cullFace; + STATE1(glCullFace, GLenum, GL_FRONT) cullFaceMode; + STATE1(glFrontFace, GLenum, GL_CCW) frontFace; + + // Depth Test + BoolState depthTest; +#if defined(USING_GLES2) + STATE2(glDepthRangef, float, float, 0.f, 1.f) depthRange; +#else + STATE2(glDepthRange, double, double, 0.0, 1.0) depthRange; +#endif + STATE1(glDepthFunc, GLenum, GL_LESS) depthFunc; + STATE1(glDepthMask, GLboolean, GL_TRUE) depthWrite; + + // Color Mask + STATE4(glColorMask, bool, bool, bool, bool, true, true, true, true) colorMask; + + // Viewport + STATE4(glViewport, GLint, GLint, GLsizei, GLsizei, 0, 0, 128, 128) viewport; + + // Scissor Test + BoolState scissorTest; + STATE4(glScissor, GLint, GLint, GLsizei, GLsizei, 0, 0, 128, 128) scissorRect; + + // Stencil Test + BoolState stencilTest; + STATE3(glStencilOp, GLenum, GLenum, GLenum, GL_KEEP, GL_KEEP, GL_KEEP) stencilOp; + STATE3(glStencilFunc, GLenum, GLint, GLuint, GL_ALWAYS, 0, 0xFF) stencilFunc; + STATE1(glStencilMask, GLuint, 0xFF) stencilMask; + + STATEBIND(glBindBuffer, GL_ARRAY_BUFFER) arrayBuffer; + STATEBIND(glBindBuffer, GL_ELEMENT_ARRAY_BUFFER) elementArrayBuffer; +}; + +#undef STATE1 +#undef STATE2 + +extern OpenGLState glstate; diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index dc86026fec..c305d5a079 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -27,7 +27,6 @@ #include "base/logging.h" #include "math/math_util.h" -#include "gfx_es2/gl_state.h" #include "math/lin/matrix4x4.h" #include "profiler/profiler.h" @@ -36,6 +35,7 @@ #include "GPU/Math3D.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/ShaderManager.h" #include "GPU/GLES/TransformPipeline.h" #include "UI/OnScreenDisplay.h" diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index e1cba640be..1d728c7a1c 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -21,7 +21,6 @@ #include "StateMapping.h" -#include "gfx_es2/gl_state.h" #include "profiler/profiler.h" #include "GPU/Math3D.h" @@ -31,6 +30,7 @@ #include "Core/Config.h" #include "Core/Reporting.h" #include "GPU/GLES/GLES_GPU.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/ShaderManager.h" #include "GPU/GLES/TextureCache.h" #include "GPU/GLES/Framebuffer.h" diff --git a/GPU/GLES/StencilBuffer.cpp b/GPU/GLES/StencilBuffer.cpp index 6cfd6ad52e..fe6b7cb70e 100644 --- a/GPU/GLES/StencilBuffer.cpp +++ b/GPU/GLES/StencilBuffer.cpp @@ -16,8 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "gfx_es2/glsl_program.h" -#include "gfx_es2/gl_state.h" #include "Core/Reporting.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/ShaderManager.h" #include "GPU/GLES/TextureCache.h" diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index aba39f7ad1..d796230bc4 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -18,6 +18,8 @@ #include #include +#include "ext/xxhash.h" +#include "math/math_util.h" #include "profiler/profiler.h" #include "Common/ColorConv.h" @@ -26,6 +28,7 @@ #include "Core/Reporting.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/TextureCache.h" #include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/FragmentShaderGenerator.h" @@ -35,10 +38,6 @@ #include "Core/Config.h" #include "Core/Host.h" -#include "ext/xxhash.h" -#include "math/math_util.h" -#include "native/gfx_es2/gl_state.h" - #ifdef _M_SSE #include #endif diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index f47599c4ee..bf313174e5 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -72,7 +72,6 @@ #include "Core/Config.h" #include "Core/CoreTiming.h" -#include "gfx_es2/gl_state.h" #include "profiler/profiler.h" #include "GPU/Math3D.h" @@ -83,6 +82,7 @@ #include "GPU/Common/SplineCommon.h" #include "GPU/Common/VertexDecoderCommon.h" #include "GPU/Common/SoftwareTransformCommon.h" +#include "GPU/GLES/GLStateCache.h" #include "GPU/GLES/FragmentTestCache.h" #include "GPU/GLES/StateMapping.h" #include "GPU/GLES/TextureCache.h" diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index cd8ef72cf3..151c945a0d 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -222,6 +222,7 @@ + @@ -297,6 +298,7 @@ + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 493bf25451..c1f9d54f59 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -189,6 +189,9 @@ DirectX9\helper + + GLES + @@ -365,5 +368,8 @@ DirectX9\helper + + GLES + \ No newline at end of file diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 79dd804036..c60bd16018 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -29,7 +29,6 @@ #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "gfx/gl_common.h" -// #include "gfx_es2/gl_state.h" #include "profiler/profiler.h" #include "GPU/Software/SoftGpu.h" diff --git a/Qt/Debugger/debugger_memorytex.cpp b/Qt/Debugger/debugger_memorytex.cpp index fef57135ed..c95ac9bd27 100644 --- a/Qt/Debugger/debugger_memorytex.cpp +++ b/Qt/Debugger/debugger_memorytex.cpp @@ -1,5 +1,5 @@ #include "debugger_memorytex.h" -#include "gfx_es2/gl_state.h" +#include "GPU/GLES/GLStateCache.h" #include "gfx/gl_common.h" #include "gfx/gl_lost_manager.h" #include "ui_debugger_memorytex.h" diff --git a/native b/native index 65e3d31e24..3f02f9fc77 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 65e3d31e249ca811809121529f1971e408c154d3 +Subproject commit 3f02f9fc778b5b4c45db92a96f0a4087f947d5a2 From 8cd69f8a57a0576f98d5e3768537500f7770600b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 6 Sep 2015 14:39:34 +0200 Subject: [PATCH 5/8] Update native --- native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native b/native index 3f02f9fc77..bdd09be76b 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 3f02f9fc778b5b4c45db92a96f0a4087f947d5a2 +Subproject commit bdd09be76b7b065ff932a8aac162e54a63fb44b4 From 48fbc83abe8c2228fec84028a87632b732bf41f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 6 Sep 2015 15:26:36 +0200 Subject: [PATCH 6/8] Android buildfix --- android/jni/Android.mk | 1 + native | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/android/jni/Android.mk b/android/jni/Android.mk index ef9ad6d65a..9f1a4371b9 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -170,6 +170,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/GLES/Framebuffer.cpp \ $(SRC)/GPU/GLES/DepalettizeShader.cpp \ $(SRC)/GPU/GLES/GLES_GPU.cpp.arm \ + $(SRC)/GPU/GLES/GLStateCache.cpp.arm \ $(SRC)/GPU/GLES/FBO.cpp \ $(SRC)/GPU/GLES/StencilBuffer.cpp.arm \ $(SRC)/GPU/GLES/TextureCache.cpp.arm \ diff --git a/native b/native index bdd09be76b..b502db61c8 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit bdd09be76b7b065ff932a8aac162e54a63fb44b4 +Subproject commit b502db61c8143dc10dca4ac918fadd936f3ce4df From 7c71855f5dab829d5eead3c3609144ddb034b2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 6 Sep 2015 16:03:36 +0200 Subject: [PATCH 7/8] Symbian / Qt buildfixes --- Qt/GPU.pro | 1 + native | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Qt/GPU.pro b/Qt/GPU.pro index a5d7206776..cebea5ef92 100644 --- a/Qt/GPU.pro +++ b/Qt/GPU.pro @@ -32,6 +32,7 @@ SOURCES += $$P/GPU/GeDisasm.cpp \ # GPU $$P/GPU/GLES/FragmentShaderGenerator.cpp \ $$P/GPU/GLES/FragmentTestCache.cpp \ $$P/GPU/GLES/Framebuffer.cpp \ + $$P/GPU/GLES/GLStateCache.cpp \ $$P/GPU/GLES/GLES_GPU.cpp \ $$P/GPU/GLES/ShaderManager.cpp \ $$P/GPU/GLES/StateMapping.cpp \ diff --git a/native b/native index b502db61c8..d2866194fd 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit b502db61c8143dc10dca4ac918fadd936f3ce4df +Subproject commit d2866194fde945ac702f76bbed6b3f394eaaeae3 From 87329ec63595738231ad7b25c1da16928cd56462 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 6 Sep 2015 17:33:08 +0200 Subject: [PATCH 8/8] Update native --- native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native b/native index d2866194fd..9ce1822a83 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit d2866194fde945ac702f76bbed6b3f394eaaeae3 +Subproject commit 9ce1822a8362e9d886b56f157bbe272dc740704b