From fb8aff5a8c710f4159b9dfec124d1c7b4869f6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 3 Feb 2023 21:06:43 +0100 Subject: [PATCH] Split out the depth stuff from the file, move to GPU/Common --- CMakeLists.txt | 3 +- .../DepthBufferCommon.cpp} | 83 +-------- GPU/GLES/StencilBufferGLES.cpp | 170 ++++++++++++++++++ GPU/GPU.vcxproj | 8 +- GPU/GPU.vcxproj.filters | 9 +- UWP/GPU_UWP/GPU_UWP.vcxproj | 3 +- UWP/GPU_UWP/GPU_UWP.vcxproj.filters | 3 +- android/jni/Android.mk | 3 +- libretro/Makefile.common | 3 +- 9 files changed, 193 insertions(+), 92 deletions(-) rename GPU/{GLES/DepthBufferGLES.cpp => Common/DepthBufferCommon.cpp} (75%) create mode 100644 GPU/GLES/StencilBufferGLES.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 105200b0ea01..7403596347ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1499,7 +1499,7 @@ if(NOT MOBILE_DEVICE) endif() set(GPU_GLES - GPU/GLES/DepthBufferGLES.cpp + GPU/GLES/StencilBufferGLES.cpp GPU/GLES/GPU_GLES.cpp GPU/GLES/GPU_GLES.h GPU/GLES/FragmentTestCacheGLES.cpp @@ -1580,6 +1580,7 @@ set(GPU_SOURCES ${GPU_NEON} GPU/Common/Draw2D.cpp GPU/Common/Draw2D.h + GPU/Common/DepthBufferCommon.cpp GPU/Common/TextureShaderCommon.cpp GPU/Common/TextureShaderCommon.h GPU/Common/DepalettizeShaderCommon.cpp diff --git a/GPU/GLES/DepthBufferGLES.cpp b/GPU/Common/DepthBufferCommon.cpp similarity index 75% rename from GPU/GLES/DepthBufferGLES.cpp rename to GPU/Common/DepthBufferCommon.cpp index b249331b1c6f..620131a0bd03 100644 --- a/GPU/GLES/DepthBufferGLES.cpp +++ b/GPU/Common/DepthBufferCommon.cpp @@ -21,10 +21,9 @@ #include "Common/LogReporting.h" #include "Core/ConfigValues.h" #include "GPU/Common/GPUStateUtils.h" -#include "GPU/GLES/DrawEngineGLES.h" -#include "GPU/GLES/FramebufferManagerGLES.h" -#include "GPU/GLES/ShaderManagerGLES.h" -#include "GPU/GLES/TextureCacheGLES.h" +#include "GPU/Common/DrawEngineCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" +#include "GPU/Common/TextureCacheCommon.h" #include "Common/GPU/ShaderWriter.h" @@ -123,7 +122,7 @@ static bool SupportsDepthTexturing() { return gl_extensions.ARB_texture_float; } -static Draw::Pipeline *CreateReadbackPipeline(Draw::DrawContext *draw, const char *tag, const UniformBufferDesc *ubDesc, const char *fs, const char *fsTag, const char *vs, const char *vsTag) { +Draw::Pipeline *CreateReadbackPipeline(Draw::DrawContext *draw, const char *tag, const UniformBufferDesc *ubDesc, const char *fs, const char *fsTag, const char *vs, const char *vsTag) { using namespace Draw; const ShaderLanguageDesc &shaderLanguageDesc = draw->GetShaderLanguageDesc(); @@ -268,7 +267,7 @@ bool FramebufferManagerCommon::ReadbackDepthbufferSync(Draw::Framebuffer *fbo, i // TODO: Apply this in the shader? May have precision issues if it becomes important to match. // We downloaded float values directly in this case. uint16_t *dest = pixels; - const GLfloat *packedf = (GLfloat *)convBuf_; + const float *packedf = (float *)convBuf_; DepthScaleFactors depthScale = GetDepthScaleFactors(); for (int yp = 0; yp < h; ++yp) { for (int xp = 0; xp < w; ++xp) { @@ -289,75 +288,3 @@ bool FramebufferManagerCommon::ReadbackDepthbufferSync(Draw::Framebuffer *fbo, i gstate_c.Dirty(DIRTY_ALL_RENDER_STATE); return true; } - -// Well, this is not depth, but it's depth/stencil related. -bool FramebufferManagerGLES::ReadbackStencilbufferSync(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint8_t *pixels, int pixelsStride) { - using namespace Draw; - - if (!fbo) { - ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "ReadbackStencilbufferSync: bad fbo"); - return false; - } - - const bool useColorPath = gl_extensions.IsGLES; - if (!useColorPath) { - return draw_->CopyFramebufferToMemorySync(fbo, FB_STENCIL_BIT, x, y, w, h, DataFormat::S8, pixels, pixelsStride, "ReadbackStencilbufferSync"); - } - - // Unsupported below GLES 3.1 or without ARB_stencil_texturing. - // OES_texture_stencil8 is related, but used to specify texture data. - if ((gl_extensions.IsGLES && !gl_extensions.VersionGEThan(3, 1)) && !gl_extensions.ARB_stencil_texturing) - return false; - - // Pixel size always 4 here because we always request RGBA back. - const u32 bufSize = w * h * 4; - if (!convBuf_ || convBufSize_ < bufSize) { - delete[] convBuf_; - convBuf_ = new u8[bufSize]; - convBufSize_ = bufSize; - } - - if (!stencilReadbackPipeline_) { - stencilReadbackPipeline_ = CreateReadbackPipeline(draw_, "stencil_dl", &depthUBDesc, stencil_dl_fs, "stencil_dl_fs", stencil_vs, "stencil_vs"); - stencilReadbackSampler_ = draw_->CreateSamplerState({}); - } - - shaderManager_->DirtyLastShader(); - auto *blitFBO = GetTempFBO(TempFBO::COPY, fbo->Width(), fbo->Height()); - draw_->BindFramebufferAsRenderTarget(blitFBO, { RPAction::DONT_CARE, RPAction::DONT_CARE, RPAction::DONT_CARE }, "ReadbackStencilbufferSync"); - Draw::Viewport viewport = { 0.0f, 0.0f, (float)fbo->Width(), (float)fbo->Height(), 0.0f, 1.0f }; - draw_->SetViewports(1, &viewport); - - draw_->BindFramebufferAsTexture(fbo, TEX_SLOT_PSP_TEXTURE, FB_STENCIL_BIT, 0); - draw_->BindSamplerStates(TEX_SLOT_PSP_TEXTURE, 1, &stencilReadbackSampler_); - - // We must bind the program after starting the render pass. - draw_->SetScissorRect(0, 0, w, h); - draw_->BindPipeline(stencilReadbackPipeline_); - - // Fullscreen triangle coordinates. - static const float positions[6] = { - 0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - }; - draw_->DrawUP(positions, 3); - - draw_->CopyFramebufferToMemorySync(blitFBO, FB_COLOR_BIT, x, y, w, h, DataFormat::R8G8B8A8_UNORM, convBuf_, w, "ReadbackStencilbufferSync"); - - textureCache_->ForgetLastTexture(); - - // TODO: Use 1/4 width to write all values directly and skip CPU conversion? - uint8_t *dest = pixels; - const u32_le *packed32 = (u32_le *)convBuf_; - for (int yp = 0; yp < h; ++yp) { - for (int xp = 0; xp < w; ++xp) { - dest[xp] = packed32[xp] & 0xFF; - } - dest += pixelsStride; - packed32 += w; - } - - gstate_c.Dirty(DIRTY_ALL_RENDER_STATE); - return true; -} diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp new file mode 100644 index 000000000000..32cd92497d5d --- /dev/null +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -0,0 +1,170 @@ +// 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/GPU/OpenGL/GLFeatures.h" +#include "Common/LogReporting.h" +#include "Core/ConfigValues.h" +#include "GPU/Common/GPUStateUtils.h" +#include "GPU/Common/DrawEngineCommon.h" +#include "GPU/Common/TextureCacheCommon.h" +#include "GPU/GLES/FramebufferManagerGLES.h" +#include "Common/GPU/ShaderWriter.h" + +static const InputDef vs_inputs[] = { + { "vec2", "a_position", Draw::SEM_POSITION }, +}; + +struct DepthUB { + float u_depthFactor[4]; + float u_depthShift[4]; + float u_depthTo8[4]; +}; + +const UniformDef depthUniforms[] = { + { "vec4", "u_depthFactor", 0 }, + { "vec4", "u_depthShift", 1}, + { "vec4", "u_depthTo8", 2}, +}; + +const UniformBufferDesc depthUBDesc{ sizeof(DepthUB), { + { "u_depthFactor", -1, -1, UniformType::FLOAT4, 0 }, + { "u_depthShift", -1, -1, UniformType::FLOAT4, 16 }, + { "u_depthTo8", -1, -1, UniformType::FLOAT4, 32 }, +} }; + +static const SamplerDef samplers[] = { + { 0, "tex" }, +}; + +static const VaryingDef varyings[] = { + { "vec2", "v_texcoord", Draw::SEM_TEXCOORD0, 0, "highp" }, +}; + +static const char *stencil_dl_fs = R"( +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif +#if __VERSION__ >= 130 +#define varying in +#define texture2D texture +#define gl_FragColor fragColor0 +out vec4 fragColor0; +#endif +varying vec2 v_texcoord; +lowp uniform usampler2D tex; +void main() { + uint stencil = texture2D(tex, v_texcoord).r; + float scaled = float(stencil) / 255.0; + gl_FragColor = vec4(scaled, scaled, scaled, scaled); +} +)"; + +static const char *stencil_vs = R"( +#ifdef GL_ES +precision highp float; +#endif +#if __VERSION__ >= 130 +#define attribute in +#define varying out +#endif +attribute vec2 a_position; +varying vec2 v_texcoord; +void main() { + v_texcoord = a_position * 2.0; + gl_Position = vec4(v_texcoord * 2.0 - vec2(1.0, 1.0), 0.0, 1.0); +} +)"; + +Draw::Pipeline *CreateReadbackPipeline(Draw::DrawContext *draw, const char *tag, const UniformBufferDesc *ubDesc, const char *fs, const char *fsTag, const char *vs, const char *vsTag); + +// Well, this is not depth, but it's depth/stencil related. +bool FramebufferManagerGLES::ReadbackStencilbufferSync(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint8_t *pixels, int pixelsStride) { + using namespace Draw; + + if (!fbo) { + ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "ReadbackStencilbufferSync: bad fbo"); + return false; + } + + const bool useColorPath = gl_extensions.IsGLES; + if (!useColorPath) { + return draw_->CopyFramebufferToMemorySync(fbo, FB_STENCIL_BIT, x, y, w, h, DataFormat::S8, pixels, pixelsStride, "ReadbackStencilbufferSync"); + } + + // Unsupported below GLES 3.1 or without ARB_stencil_texturing. + // OES_texture_stencil8 is related, but used to specify texture data. + if ((gl_extensions.IsGLES && !gl_extensions.VersionGEThan(3, 1)) && !gl_extensions.ARB_stencil_texturing) + return false; + + // Pixel size always 4 here because we always request RGBA back. + const u32 bufSize = w * h * 4; + if (!convBuf_ || convBufSize_ < bufSize) { + delete[] convBuf_; + convBuf_ = new u8[bufSize]; + convBufSize_ = bufSize; + } + + if (!stencilReadbackPipeline_) { + stencilReadbackPipeline_ = CreateReadbackPipeline(draw_, "stencil_dl", &depthUBDesc, stencil_dl_fs, "stencil_dl_fs", stencil_vs, "stencil_vs"); + stencilReadbackSampler_ = draw_->CreateSamplerState({}); + } + + shaderManager_->DirtyLastShader(); + auto *blitFBO = GetTempFBO(TempFBO::COPY, fbo->Width(), fbo->Height()); + draw_->BindFramebufferAsRenderTarget(blitFBO, { RPAction::DONT_CARE, RPAction::DONT_CARE, RPAction::DONT_CARE }, "ReadbackStencilbufferSync"); + Draw::Viewport viewport = { 0.0f, 0.0f, (float)fbo->Width(), (float)fbo->Height(), 0.0f, 1.0f }; + draw_->SetViewports(1, &viewport); + + draw_->BindFramebufferAsTexture(fbo, TEX_SLOT_PSP_TEXTURE, FB_STENCIL_BIT, 0); + draw_->BindSamplerStates(TEX_SLOT_PSP_TEXTURE, 1, &stencilReadbackSampler_); + + // We must bind the program after starting the render pass. + draw_->SetScissorRect(0, 0, w, h); + draw_->BindPipeline(stencilReadbackPipeline_); + + // Fullscreen triangle coordinates. + static const float positions[6] = { + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + }; + draw_->DrawUP(positions, 3); + + draw_->CopyFramebufferToMemorySync(blitFBO, FB_COLOR_BIT, x, y, w, h, DataFormat::R8G8B8A8_UNORM, convBuf_, w, "ReadbackStencilbufferSync"); + + textureCache_->ForgetLastTexture(); + + // TODO: Use 1/4 width to write all values directly and skip CPU conversion? + uint8_t *dest = pixels; + const u32_le *packed32 = (u32_le *)convBuf_; + for (int yp = 0; yp < h; ++yp) { + for (int xp = 0; xp < w; ++xp) { + dest[xp] = packed32[xp] & 0xFF; + } + dest += pixelsStride; + packed32 += w; + } + + gstate_c.Dirty(DIRTY_ALL_RENDER_STATE); + return true; +} diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 860dbc38f306..0f8711b03b4d 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -454,6 +454,7 @@ + @@ -525,12 +526,6 @@ - - true - true - true - true - true true @@ -561,6 +556,7 @@ true true + true true diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index b8a990374ae4..828e4c526575 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -461,9 +461,6 @@ Debugger - - GLES - Debugger @@ -518,6 +515,12 @@ Common + + Common + + + GLES + diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 05b783973699..369a75da7215 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -441,6 +441,7 @@ + @@ -531,4 +532,4 @@ - + \ No newline at end of file diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index 2296b16a16e1..2481c765c966 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -60,6 +60,7 @@ + @@ -123,4 +124,4 @@ - + \ No newline at end of file diff --git a/android/jni/Android.mk b/android/jni/Android.mk index eae8a9c672c9..6932d49ecfc6 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -372,6 +372,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/Common/GPUStateUtils.cpp.arm \ $(SRC)/GPU/Common/SoftwareTransformCommon.cpp.arm \ $(SRC)/GPU/Common/ReinterpretFramebuffer.cpp \ + $(SRC)/GPU/Common/DepthBufferCommon.cpp \ $(SRC)/GPU/Common/VertexDecoderCommon.cpp.arm \ $(SRC)/GPU/Common/TextureCacheCommon.cpp.arm \ $(SRC)/GPU/Common/TextureScalerCommon.cpp.arm \ @@ -392,7 +393,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/Debugger/Record.cpp \ $(SRC)/GPU/Debugger/Stepping.cpp \ $(SRC)/GPU/GLES/FramebufferManagerGLES.cpp \ - $(SRC)/GPU/GLES/DepthBufferGLES.cpp \ + $(SRC)/GPU/GLES/StencilBufferGLES.cpp \ $(SRC)/GPU/GLES/GPU_GLES.cpp.arm \ $(SRC)/GPU/GLES/TextureCacheGLES.cpp.arm \ $(SRC)/GPU/GLES/DrawEngineGLES.cpp.arm \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 4095102bbad5..2b62ff352d15 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -391,6 +391,7 @@ SOURCES_CXX += \ $(GPUDIR)/Common/TextureCacheCommon.cpp \ $(GPUDIR)/Common/TextureScalerCommon.cpp \ $(GPUDIR)/Common/SoftwareTransformCommon.cpp \ + $(GPUDIR)/Common/DepthBufferCommon.cpp \ $(GPUDIR)/Common/StencilCommon.cpp \ $(GPUDIR)/Software/TransformUnit.cpp \ $(GPUDIR)/Software/SoftGpu.cpp \ @@ -409,7 +410,7 @@ SOURCES_CXX += \ $(GPUDIR)/Software/Rasterizer.cpp \ $(GPUDIR)/Software/RasterizerRectangle.cpp \ $(GPUDIR)/Software/RasterizerRegCache.cpp \ - $(GPUDIR)/GLES/DepthBufferGLES.cpp \ + $(GPUDIR)/GLES/StencilBufferGLES.cpp \ $(GPUDIR)/GLES/DrawEngineGLES.cpp \ $(GPUDIR)/GLES/GPU_GLES.cpp \ $(GPUDIR)/GLES/FragmentTestCacheGLES.cpp \