Vita: modern-librw render path + enable Neo pipelines

This commit is contained in:
Dima353
2026-07-26 13:47:11 +03:00
parent ceb5bee044
commit f21b7bd3ff
12 changed files with 43 additions and 134 deletions
+1 -1
View File
@@ -35,7 +35,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: |
+1 -1
View File
@@ -17,7 +17,7 @@ CC = $(PREFIX)-gcc
CXX = $(PREFIX)-g++
ARCH := -mtune=cortex-a9 -march=armv7-a -mfpu=neon
CFLAGS := -g -Wl,-q,--no-enum-size-warning -fno-short-enums -fno-optimize-sibling-calls -O2 -ftree-vectorize -mfloat-abi=hard -fno-builtin-memcpy $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) -DPSP2 -DNDEBUG -DMASTER -DLIBRW -DRW_GL3 -DAUDIO_OAL -DLIBRW_GLAD
CFLAGS += $(INCLUDE) -DPSP2 -DMASTER -DLIBRW -DRW_GL3 -DAUDIO_OAL -DLIBRW_GLAD
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map)
-9
View File
@@ -244,14 +244,6 @@ CGame::InitialiseRenderWare(void)
CreateDebugFont();
#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 = { 64, 64, 64, 255 };
rw::MatFX::envMapColor = envcol;
#endif
#else
#ifdef PS2_MATFX
ReplaceMatFxCallback();
+4 -4
View File
@@ -67,10 +67,10 @@ 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) }, 0, 0, MENUALIGN_LEFT,
#else
#define DUALPASS_SELECTOR
#define DUALPASS_SELECTOR
#endif
#ifdef PED_CAR_DENSITY_SLIDERS
@@ -115,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;
+3 -5
View File
@@ -349,15 +349,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)
+17 -21
View File
@@ -135,8 +135,12 @@ bool gbPrintMemoryUsage;
#endif
#ifdef NEW_RENDERER
#ifdef PSP2
bool gbNewRenderer = true;
#else
bool gbNewRenderer;
#endif
#endif
#ifdef FIX_BUGS
// need to clear stencil for mblur fx. no idea why it works in the original game
// also for clearing out water rects in new renderer
@@ -355,11 +359,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)
{
@@ -368,18 +367,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];
@@ -1632,14 +1619,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();
+4
View File
@@ -142,13 +142,17 @@ CustomFrontendOptionsPopulate(void)
FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
#ifndef PSP2 // World Lightmaps need Xbox neo resources (absent in PC data) - hide on Vita
FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
#endif
FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
#else
FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false);
FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
#ifndef PSP2 // World Lightmaps need Xbox neo resources (absent in PC data) - hide on Vita
FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
#endif
FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
#endif
CFileMgr::CloseFile(fd);
+6 -57
View File
@@ -13,13 +13,6 @@
#include "MBlur.h"
#include "postfx.h"
#ifdef PSP2
// The Vita captures the scene into its own FBO instead of reading the backbuffer:
// see DoRWStuffEndOfFrame, which flips the binding a frame ahead.
GLuint fxraster = 0xDEADBEEF, fxfb;
extern bool using_fbo;
#endif
RwRaster *CPostFX::pFrontBuffer;
RwRaster *CPostFX::pBackBuffer;
bool CPostFX::bJustInitialised;
@@ -169,43 +162,27 @@ CPostFX::Open(RwCamera *cam)
contrast_PS = rw::d3d::createPixelShader(contrastPS_cso);
#endif
#ifdef RW_OPENGL
#ifdef PSP2
// Cg source, not the precompiled GXP blobs: librw-vita is built with
// PSP2_USE_SHADER_COMPILER, so Shader::create expects source strings, and
// glShaderBinary would now be handed a blob it cannot parse.
#include "shaders/im2d_v_cg.inc"
#endif
// The Vita used to take a separate path here: Cg sources and librw-vita's
// 3-argument Shader::create(vs, fs, is_2d). Modern librw has neither, so it
// goes through the common GLSL path; vitaGL's GLSL translator understands the
// attribute/varying dialect that shaderDecl100es emits.
using namespace rw::gl3;
{
#ifdef PSP2
#include "shaders/colourfilterVC_f_cg.inc"
const char *vs[] = { im2d_v_cg_src, nil };
const char *fs[] = { colourfilterVC_f_cg_src, nil };
colourFilterVC = Shader::create(vs, fs, true);
#else
#include "shaders/obj/im2d_vert.inc"
#include "shaders/obj/colourfilterVC_frag.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, colourfilterVC_frag_src, nil };
colourFilterVC = Shader::create(vs, fs);
#endif
assert(colourFilterVC);
}
{
#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);
}
@@ -342,14 +319,8 @@ CPostFX::RenderOverlayShader(RwCamera *cam, int32 r, int32 g, int32 b, int32 a)
glUniform4fv(colourFilterVC->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;
@@ -463,11 +434,8 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
blur = AvgAlpha;
}
// PSP2 captures the scene through its own FBO a frame ahead instead.
#ifndef PSP2
if(NeedBackBuffer())
GetBackBuffer(cam);
#endif
DefinedState();
@@ -480,25 +448,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)
// Arm the capture for the next frame: DoRWStuffEndOfFrame binds fxfb once
// using_fbo is set, so the scene lands in fxraster and this pass samples it.
if (NeedBackBuffer()) {
if(fxraster == 0xDEADBEEF){
glGenTextures(1, &fxraster);
glBindTexture(GL_TEXTURE_2D, fxraster);
// Screen-sized, not a POT block: the fullscreen quad samples this
// over 0..1, so anything bigger leaves the scene in a sub-rect and
// the remainder reads as black.
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:
case POSTFX_SIMPLE:
-28
View File
@@ -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;
}
+3 -3
View File
@@ -183,7 +183,7 @@ CShadowCamera::Update(RpClump *clump)
RpGeometry *geometry;
RwRGBA bgColor = { 255, 255, 255, 0 };
RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
if ( RwCameraBeginUpdate(m_pCamera) )
@@ -219,10 +219,10 @@ CShadowCamera::Update(RpAtomic *atomic)
RwRGBA bgColor = { 255, 255, 255, 0 };
RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
if ( RwCameraBeginUpdate(m_pCamera) )
{
geometry = RpAtomicGetGeometry(atomic);
geometry = RpAtomicGetGeometry(atomic);
ASSERT(geometry != nil);
flags = RpGeometryGetFlags(geometry);
+3 -5
View File
@@ -185,8 +185,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
@@ -293,8 +292,8 @@ bool
CanVideoCardDoDXT(void)
{
#ifdef LIBRW
// TODO
#ifdef RW_OPENGL
// TODO: other GL targets still take the conversion path
return false;
#else
return true;
@@ -432,8 +431,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
+1
View File
@@ -820,6 +820,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);
}