From f6a385c86376e615301c5105ad85abee0ec9cc2a Mon Sep 17 00:00:00 2001 From: Dima353 <75039669+Dima353@users.noreply.github.com> Date: Sun, 26 Jul 2026 13:42:56 +0300 Subject: [PATCH] Vita: modern-librw render path + enable Neo pipelines --- .github/workflows/build-vita.yml | 2 +- src/core/Game.cpp | 9 ------ src/core/MenuScreensCustom.cpp | 9 +++--- src/core/config.h | 8 ++---- src/core/main.cpp | 40 +++++++++++++------------- src/core/re3.cpp | 4 +++ src/extras/postfx.cpp | 49 ++------------------------------ src/fakerw/fake.cpp | 28 ------------------ src/rw/TexRead.cpp | 6 ++-- src/skel/glfw/MoviePlayer.cpp | 1 + 10 files changed, 37 insertions(+), 119 deletions(-) diff --git a/.github/workflows/build-vita.yml b/.github/workflows/build-vita.yml index 30edd025..0ce93554 100644 --- a/.github/workflows/build-vita.yml +++ b/.github/workflows/build-vita.yml @@ -33,7 +33,7 @@ jobs: - name: Build vitaGL run: | git clone --depth 1 https://github.com/Rinnegatamante/vitaGL.git - make -C vitaGL NO_DEBUG=1 PHYCONT_ON_DEMAND=1 ENABLE_LEGACY_PIPELINE=1 -j"$(nproc)" install + make -C vitaGL NO_DEBUG=1 PHYCONT_ON_DEMAND=1 ENABLE_LEGACY_PIPELINE=1 HAVE_SHADER_CACHE=1 NO_SPLASHSCREEN=1 -j"$(nproc)" install - name: Build librw-vita (fork, kept building against current vitaGL) run: | diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 40b3a5b1..b3dd1eda 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -244,14 +244,6 @@ CGame::InitialiseRenderWare(void) #endif #ifdef LIBRW -// librw-vita predates the envMap* knobs and only exposes modulateEnvMap. -#ifdef PSP2 -#ifdef PS2_MATFX - rw::MatFX::modulateEnvMap = true; -#else - rw::MatFX::modulateEnvMap = false; -#endif -#else #ifdef PS2_MATFX rw::MatFX::envMapApplyLight = true; rw::MatFX::envMapUseMatColor = true; @@ -263,7 +255,6 @@ CGame::InitialiseRenderWare(void) #endif rw::RGBA envcol = { 128, 128, 128, 255 }; rw::MatFX::envMapColor = envcol; -#endif #else #ifdef PS2_MATFX ReplaceMatFxCallback(); diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp index dbdfc444..f9203f4f 100644 --- a/src/core/MenuScreensCustom.cpp +++ b/src/core/MenuScreensCustom.cpp @@ -66,10 +66,11 @@ extern bool useRearpad; // touch input: front panel or rear, see crossplatform.c #define FREE_CAM_TOGGLE #endif -#ifdef PS2_ALPHA_TEST +#if defined(PS2_ALPHA_TEST) && !defined(PSP2) #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) }, #else - #define DUALPASS_SELECTOR + // PSP2: PS2 alpha test is forced on with no menu row (gPS2alphaTest defaults to true). + #define DUALPASS_SELECTOR #endif #ifdef PED_CAR_DENSITY_SLIDERS @@ -114,8 +115,8 @@ void RestoreDefGraphics(int8 action) { if (action != FEOPTION_ACTION_SELECT) return; - #ifdef PS2_ALPHA_TEST - gPS2alphaTest = false; + #if defined(PS2_ALPHA_TEST) && !defined(PSP2) + gPS2alphaTest = false; // PSP2: kept forced-on, no menu toggle #endif #ifdef MULTISAMPLING FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0; diff --git a/src/core/config.h b/src/core/config.h index 56c6df35..af17baba 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -342,15 +342,13 @@ enum Config { //#define USE_TEXTURE_POOL #ifdef LIBRW #define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) -// Not on PSP2: librw-vita is an old fork with no setupVertexInput, no three-argument -// Shader::create and no UNIFORM_VEC4, so the Neo pipelines and the droplets cannot -// build against it. They would also need Cg versions of every shader. -#ifndef PSP2 +// librw-vita is now the modern fork, so these build on PSP2 as well. Runtime defaults: +// NEW_RENDERER is on (gbNewRenderer, PSP2), the Neo pipeline stays MATFX (stock look, +// opt-in via the graphics menu), and SCREEN_DROPLETS only shows in rain. #define EXTENDED_PIPELINES // custom render pipelines (includes Neo) #define SCREEN_DROPLETS // neo water droplets #define NEW_RENDERER // leeds-like world rendering, needs librw #endif -#endif #define FIX_SPRITES // fix sprites aspect ratio(moon, coronas, particle etc) diff --git a/src/core/main.cpp b/src/core/main.cpp index 3da64a33..9db932ef 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -136,7 +136,13 @@ bool gbPrintMemoryUsage; #endif #ifdef NEW_RENDERER +#ifdef PSP2 +// On by default on Vita: the Leeds-like renderer's culling/batching boosts perf on +// the weak CPU (measurable in dense/moving scenes). INI/debug menu can still toggle it. +bool gbNewRenderer = true; +#else bool gbNewRenderer; +#endif #define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL) #else #define CLEARMODE (rwCAMERACLEARZ) @@ -378,11 +384,6 @@ RwGrabScreen(RwCamera *camera, RwChar *filename) #define TILE_WIDTH 576 #define TILE_HEIGHT 432 -#ifdef PSP2 -extern GLuint fxfb; -bool using_fbo = false; -#endif - void DoRWStuffEndOfFrame(void) { @@ -391,18 +392,6 @@ DoRWStuffEndOfFrame(void) FlushObrsPrintfs(); RwCameraEndUpdate(Scene.camera); -#if defined(PSP2) && defined(EXTENDED_COLOURFILTER) - // Arm the next frame's capture: bind our FBO once CPostFX has asked for it, so - // the scene renders into fxraster and the colour filter can sample it. - if(CPostFX::NeedBackBuffer()){ - if (using_fbo) { - glBindFramebuffer(GL_FRAMEBUFFER, fxfb); - using_fbo = false; - } else - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } -#endif - RsCameraShowRaster(Scene.camera); #ifndef MASTER char s[48]; @@ -1706,14 +1695,23 @@ Idle(void *arg) RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); #endif +#ifdef EXTENDED_PIPELINES + // Render the env-map reflection BEFORE the main scene, not after. On the Vita + // tile-based GPU the env-map RTT (a render-target switch with its own depth) + // left the depth-dependent late passes (coronas, shadows, glints) rendering + // against a disturbed state, so they showed through geometry. Doing it first + // makes RenderScene the last thing to touch the display + depth, so those + // passes see a clean scene. Also removes the one-frame lag on car reflections. + CustomPipes::EnvMapRender(); + // EnvMapRender leaves render state from the reflection pass; reset it so the + // main scene (and the depth-dependent passes after it) start clean. + DefinedState(); +#endif + tbStartTimer(0, "RenderScene"); RenderScene(); tbEndTimer("RenderScene"); -#ifdef EXTENDED_PIPELINES - CustomPipes::EnvMapRender(); -#endif - RenderDebugShit(); RenderEffects(); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index e7e394fb..6cdb9701 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -135,13 +135,17 @@ CustomFrontendOptionsPopulate(void) FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false); FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline"); FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight"); +#ifndef PSP2 FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps"); +#endif FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss"); #else FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false); FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline"); FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight"); +#ifndef PSP2 FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps"); +#endif FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss"); #endif CFileMgr::CloseFile(fd); diff --git a/src/extras/postfx.cpp b/src/extras/postfx.cpp index 0634026a..770f534c 100644 --- a/src/extras/postfx.cpp +++ b/src/extras/postfx.cpp @@ -13,11 +13,6 @@ #include "MBlur.h" #include "postfx.h" -#ifdef PSP2 -GLuint fxraster = 0xDEADBEEF, fxfb; -extern bool using_fbo; -#endif - RwRaster *CPostFX::pFrontBuffer; RwRaster *CPostFX::pBackBuffer; bool CPostFX::bJustInitialised; @@ -160,39 +155,22 @@ CPostFX::Open(RwCamera *cam) contrast_PS = rw::d3d::createPixelShader(contrastPS_cso); #endif #ifdef RW_OPENGL -#ifdef PSP2 - #include "shaders/im2d_v_cg.inc" -#endif using namespace rw::gl3; { -#ifdef PSP2 -#include "shaders/colourfilterIII_f_cg.inc" - const char *vs[] = { im2d_v_cg_src, nil }; - const char *fs[] = { colourfilterIII_f_cg_src, nil }; - colourFilterIII = Shader::create(vs, fs, true); -#else #include "shaders/obj/im2d_vert.inc" #include "shaders/obj/colourfilterIII_frag.inc" const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, colourfilterIII_frag_src, nil }; colourFilterIII = Shader::create(vs, fs); -#endif assert(colourFilterIII); } { -#ifdef PSP2 -#include "shaders/contrast_f_cg.inc" - const char *vs[] = { im2d_v_cg_src, nil }; - const char *fs[] = { contrast_f_cg_src, nil }; - contrast = Shader::create(vs, fs, true); -#else #include "shaders/obj/im2d_vert.inc" #include "shaders/obj/contrast_frag.inc" const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, contrast_frag_src, nil }; contrast = Shader::create(vs, fs); -#endif assert(contrast); } @@ -331,14 +309,8 @@ CPostFX::RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a) glUniform4fv(colourFilterIII->uniformLocations[u_blurcolor], 1, blurcolors); #endif } -#ifdef PSP2 - // The scene lives in our own FBO texture here, not in pBackBuffer. - glBindTexture(GL_TEXTURE_2D, fxraster); - RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, 255); - RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, 255); - RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, 255); - RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255); -#endif + // Vita now captures via GetBackBuffer (glBlitFramebuffer in librw's + // rasterRenderFast) into pBackBuffer, sampled through the texture raster set above. RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6); #ifdef RW_D3D9 rw::d3d::im2dOverridePS = nil; @@ -466,11 +438,8 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu assert(pFrontBuffer); assert(pBackBuffer); - // PSP2 captures the scene through its own FBO a frame ahead instead. -#ifndef PSP2 if(NeedBackBuffer()) GetBackBuffer(cam); -#endif DefinedState(); @@ -483,20 +452,6 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu if(!bJustInitialised) RenderOverlaySniper(cam, red, green, blue, blur); }else{ -#if defined(PSP2) && defined(EXTENDED_COLOURFILTER) - if (NeedBackBuffer()) { - if(fxraster == 0xDEADBEEF){ - glGenTextures(1, &fxraster); - glBindTexture(GL_TEXTURE_2D, fxraster); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 960, 544, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glGenFramebuffers(1, &fxfb); - glBindFramebuffer(GL_FRAMEBUFFER, fxfb); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fxraster, 0); - } - using_fbo = true; - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } -#endif switch(EffectSwitch){ case POSTFX_OFF: // no actual rendering here diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp index 38447751..a972e309 100644 --- a/src/fakerw/fake.cpp +++ b/src/fakerw/fake.cpp @@ -299,40 +299,12 @@ RwTextureAddressMode RwTextureGetAddressingV(const RwTexture *texture); // TODO void _rwD3D8TexDictionaryEnableRasterFormatConversion(bool enable) { } -#ifdef PSP2 -// librw-vita predates Raster::convertTexToCurrentPlatform, so do it by hand: -// round-trip through an Image, which also drops the palette the Vita cannot use. -static rw::Raster* -ConvertTexRaster(rw::Raster *ras) -{ - using namespace rw; - - if(ras->platform == rw::platform) - return ras; - // compatible platforms - if(ras->platform == PLATFORM_D3D8 && rw::platform == PLATFORM_D3D9 || - ras->platform == PLATFORM_D3D9 && rw::platform == PLATFORM_D3D8) - return ras; - - Image *img = ras->toImage(); - ras->destroy(); - img->unpalettize(); - ras = Raster::createFromImage(img); - img->destroy(); - return ras; -} -#endif - // hack for reading native textures RwBool rwNativeTextureHackRead(RwStream *stream, RwTexture **tex, RwInt32 size) { *tex = Texture::streamReadNative(stream); #ifdef LIBRW -#ifdef PSP2 - (*tex)->raster = ConvertTexRaster((*tex)->raster); -#else (*tex)->raster = rw::Raster::convertTexToCurrentPlatform((*tex)->raster); -#endif #endif return *tex != nil; } diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp index cee172fc..e35e358c 100644 --- a/src/rw/TexRead.cpp +++ b/src/rw/TexRead.cpp @@ -182,8 +182,7 @@ GetGPUcaps(GPUcaps *caps) caps->subplatform = 0; caps->dxtSupport = 0; // TODO: more later -// librw-vita has no gl3Caps. -#if defined(RW_GL3) && !defined(PSP2) +#ifdef RW_GL3 caps->subplatform = rw::gl3::gl3Caps.gles; caps->dxtSupport = rw::gl3::gl3Caps.dxtSupported; #endif @@ -401,8 +400,7 @@ CreateTxdImageForVideoCard() return false; } -// librw-vita has no needToReadBackTextures - it always keeps texture data around. -#if defined(RW_GL3) && !defined(PSP2) +#ifdef RW_GL3 // so we can read back DXT with GLES // only works for textures that are not yet loaded // so let's hope that is the case for all diff --git a/src/skel/glfw/MoviePlayer.cpp b/src/skel/glfw/MoviePlayer.cpp index 8fa37530..4505e2c1 100644 --- a/src/skel/glfw/MoviePlayer.cpp +++ b/src/skel/glfw/MoviePlayer.cpp @@ -816,6 +816,7 @@ void movie_player_draw(void) { sceAvPlayerClose(movie_player); movie_player_audio_shutdown(); player_state = PLAYER_INACTIVE; + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); vglSwapBuffers(GL_FALSE); }