Starting with backbuffer scaling refactor.

This commit is contained in:
Skyth 2025-01-18 18:19:12 +03:00
parent c53df15578
commit 6482b4632e
7 changed files with 48 additions and 84 deletions

View file

@ -1355,16 +1355,8 @@ static void CheckSwapChain()
if (g_needsResize) if (g_needsResize)
Video::ComputeViewportDimensions(); Video::ComputeViewportDimensions();
if (g_aspectRatio >= NARROW_ASPECT_RATIO) g_backBuffer->width = Video::s_viewportWidth;
{ g_backBuffer->height = Video::s_viewportHeight;
g_backBuffer->width = Video::s_viewportWidth * 720 / Video::s_viewportHeight;
g_backBuffer->height = 720;
}
else
{
g_backBuffer->width = 960;
g_backBuffer->height = Video::s_viewportHeight * 960 / Video::s_viewportWidth;
}
} }
static void BeginCommandList() static void BeginCommandList()
@ -2456,11 +2448,6 @@ static GuestSurface* GetBackBuffer()
return g_backBuffer; return g_backBuffer;
} }
GuestSurface* Video::GetBackBuffer()
{
return g_backBuffer;
}
void Video::ComputeViewportDimensions() void Video::ComputeViewportDimensions()
{ {
uint32_t width = g_swapChain->getWidth(); uint32_t width = g_swapChain->getWidth();
@ -2663,9 +2650,6 @@ static GuestSurface* CreateSurface(uint32_t width, uint32_t height, uint32_t for
static void FlushViewport() static void FlushViewport()
{ {
bool renderingToBackBuffer = g_renderTarget == g_backBuffer &&
g_backBuffer->texture != g_backBuffer->textureHolder.get();
auto& commandList = g_commandLists[g_frame]; auto& commandList = g_commandLists[g_frame];
if (g_dirtyStates.viewport) if (g_dirtyStates.viewport)
@ -2677,17 +2661,6 @@ static void FlushViewport()
viewport.y += 0.5f; viewport.y += 0.5f;
} }
if (renderingToBackBuffer)
{
float width = Video::s_viewportWidth;
float height = Video::s_viewportHeight;
viewport.x *= width / g_backBuffer->width;
viewport.y *= height / g_backBuffer->height;
viewport.width *= width / g_backBuffer->width;
viewport.height *= height / g_backBuffer->height;
}
if (viewport.minDepth > viewport.maxDepth) if (viewport.minDepth > viewport.maxDepth)
std::swap(viewport.minDepth, viewport.maxDepth); std::swap(viewport.minDepth, viewport.maxDepth);
@ -2704,17 +2677,6 @@ static void FlushViewport()
g_viewport.x + g_viewport.width, g_viewport.x + g_viewport.width,
g_viewport.y + g_viewport.height); g_viewport.y + g_viewport.height);
if (renderingToBackBuffer)
{
uint32_t width = Video::s_viewportWidth;
uint32_t height = Video::s_viewportHeight;
scissorRect.left = scissorRect.left * width / g_backBuffer->width;
scissorRect.top = scissorRect.top * height / g_backBuffer->height;
scissorRect.right = scissorRect.right * width / g_backBuffer->width;
scissorRect.bottom = scissorRect.bottom * height / g_backBuffer->height;
}
commandList->setScissors(scissorRect); commandList->setScissors(scissorRect);
g_dirtyStates.scissorRect = false; g_dirtyStates.scissorRect = false;

View file

@ -23,7 +23,6 @@ struct Video
static void Present(); static void Present();
static void StartPipelinePrecompilation(); static void StartPipelinePrecompilation();
static void WaitForGPU(); static void WaitForGPU();
static struct GuestSurface* GetBackBuffer();
static void ComputeViewportDimensions(); static void ComputeViewportDimensions();
}; };

View file

@ -185,13 +185,14 @@ void AspectRatioPatches::ComputeOffsets()
float height = Video::s_viewportHeight; float height = Video::s_viewportHeight;
g_aspectRatio = width / height; g_aspectRatio = width / height;
g_aspectRatioScale = 1.0f; g_aspectRatioGameplayScale = 1.0f;
if (g_aspectRatio >= NARROW_ASPECT_RATIO) if (g_aspectRatio >= NARROW_ASPECT_RATIO)
{ {
// height is locked to 720 in this case // height is locked to 720 in this case
g_aspectRatioOffsetX = 0.5f * (g_aspectRatio * 720.0f - 1280.0f); g_aspectRatioOffsetX = 0.5f * (g_aspectRatio * 720.0f - 1280.0f);
g_aspectRatioOffsetY = 0.0f; g_aspectRatioOffsetY = 0.0f;
g_aspectRatioScale = height / 720.0f;
// keep same scale above Steam Deck aspect ratio // keep same scale above Steam Deck aspect ratio
if (g_aspectRatio < WIDE_ASPECT_RATIO) if (g_aspectRatio < WIDE_ASPECT_RATIO)
@ -201,7 +202,7 @@ void AspectRatioPatches::ComputeOffsets()
float narrowScale = ComputeScale(NARROW_ASPECT_RATIO); float narrowScale = ComputeScale(NARROW_ASPECT_RATIO);
float lerpFactor = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (STEAM_DECK_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f); float lerpFactor = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (STEAM_DECK_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f);
g_aspectRatioScale = narrowScale + (steamDeckScale - narrowScale) * lerpFactor; g_aspectRatioGameplayScale = narrowScale + (steamDeckScale - narrowScale) * lerpFactor;
} }
} }
else else
@ -209,12 +210,21 @@ void AspectRatioPatches::ComputeOffsets()
// width is locked to 960 in this case to have 4:3 crop // width is locked to 960 in this case to have 4:3 crop
g_aspectRatioOffsetX = 0.5f * (960.0f - 1280.0f); g_aspectRatioOffsetX = 0.5f * (960.0f - 1280.0f);
g_aspectRatioOffsetY = 0.5f * (960.0f / g_aspectRatio - 720.0f); g_aspectRatioOffsetY = 0.5f * (960.0f / g_aspectRatio - 720.0f);
g_aspectRatioScale = ComputeScale(NARROW_ASPECT_RATIO); g_aspectRatioScale = width / 960.0f;
g_aspectRatioGameplayScale = ComputeScale(NARROW_ASPECT_RATIO);
} }
g_narrowOffsetScale = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (WIDE_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f); g_aspectRatioNarrowScale = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (WIDE_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f);
} }
static void GetViewport(void* application, be<uint32_t>* width, be<uint32_t>* height)
{
*width = 1280;
*height = 720;
}
GUEST_FUNCTION_HOOK(sub_82E169B8, GetViewport);
// SWA::CGameDocument::ComputeScreenPosition // SWA::CGameDocument::ComputeScreenPosition
PPC_FUNC_IMPL(__imp__sub_8250FC70); PPC_FUNC_IMPL(__imp__sub_8250FC70);
PPC_FUNC(sub_8250FC70) PPC_FUNC(sub_8250FC70)
@ -258,10 +268,10 @@ PPC_FUNC(sub_8258B558)
if (scene != NULL) if (scene != NULL)
{ {
ctx.r3.u32 = scene; ctx.r3.u32 = scene;
ctx.f1.f64 = offsetX + g_narrowOffsetScale * 140.0f; ctx.f1.f64 = offsetX + g_aspectRatioNarrowScale * 140.0f;
ctx.f2.f64 = offsetY; ctx.f2.f64 = offsetY;
if (Config::UIScaleMode == EUIScaleMode::Edge && g_narrowOffsetScale >= 1.0f) if (Config::UIScaleMode == EUIScaleMode::Edge && g_aspectRatioNarrowScale >= 1.0f)
ctx.f1.f64 += g_aspectRatioOffsetX; ctx.f1.f64 += g_aspectRatioOffsetX;
sub_830BB3D0(ctx, base); sub_830BB3D0(ctx, base);
@ -282,8 +292,8 @@ PPC_FUNC(sub_8258B558)
uint32_t textBox = PPC_LOAD_U32(menuTextBox + 0x4); uint32_t textBox = PPC_LOAD_U32(menuTextBox + 0x4);
if (textBox != NULL) if (textBox != NULL)
{ {
float value = 708.0f + g_narrowOffsetScale * 140.0f; float value = 708.0f + g_aspectRatioNarrowScale * 140.0f;
if (Config::UIScaleMode == EUIScaleMode::Edge && g_narrowOffsetScale >= 1.0f) if (Config::UIScaleMode == EUIScaleMode::Edge && g_aspectRatioNarrowScale >= 1.0f)
value += g_aspectRatioOffsetX; value += g_aspectRatioOffsetX;
PPC_STORE_U32(textBox + 0x38, reinterpret_cast<uint32_t&>(value)); PPC_STORE_U32(textBox + 0x38, reinterpret_cast<uint32_t&>(value));
@ -740,8 +750,6 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
modifier.flags &= ~(ALIGN_LEFT | ALIGN_RIGHT); modifier.flags &= ~(ALIGN_LEFT | ALIGN_RIGHT);
} }
auto backBuffer = Video::GetBackBuffer();
uint32_t size = ctx.r5.u32 * stride; uint32_t size = ctx.r5.u32 * stride;
ctx.r1.u32 -= size; ctx.r1.u32 -= size;
@ -755,7 +763,7 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
if ((modifier.flags & STRETCH_HORIZONTAL) != 0) if ((modifier.flags & STRETCH_HORIZONTAL) != 0)
{ {
scaleX = backBuffer->width / 1280.0f; scaleX = Video::s_viewportWidth / 1280.0f;
} }
else else
{ {
@ -777,13 +785,13 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
if ((modifier.flags & WORLD_MAP) != 0) if ((modifier.flags & WORLD_MAP) != 0)
{ {
if ((modifier.flags & ALIGN_LEFT) != 0) if ((modifier.flags & ALIGN_LEFT) != 0)
offsetX += (1.0f - g_narrowOffsetScale) * -20.0f; offsetX += (1.0f - g_aspectRatioNarrowScale) * -20.0f;
} }
} }
if ((modifier.flags & STRETCH_VERTICAL) != 0) if ((modifier.flags & STRETCH_VERTICAL) != 0)
{ {
scaleY = backBuffer->height / 720.0f; scaleY = Video::s_viewportHeight / 720.0f;
} }
else else
{ {
@ -852,11 +860,11 @@ static void Draw(PPCContext& ctx, uint8_t* base, PPCFunc* original, uint32_t str
} }
else if ((modifier.flags & EXTEND_RIGHT) != 0 && (i == 2 || i == 3)) else if ((modifier.flags & EXTEND_RIGHT) != 0 && (i == 2 || i == 3))
{ {
x = std::max(x, float(backBuffer->width)); x = std::max(x, float(Video::s_viewportWidth));
} }
position[0] = round(x / backBuffer->width * Video::s_viewportWidth) / Video::s_viewportWidth * backBuffer->width; position[0] = x;
position[1] = round(y / backBuffer->height * Video::s_viewportHeight) / Video::s_viewportHeight * backBuffer->height; position[1] = y;
} }
ctx.r4.u32 = ctx.r1.u32; ctx.r4.u32 = ctx.r1.u32;
@ -882,7 +890,6 @@ PPC_FUNC(sub_825E2E88)
PPC_FUNC_IMPL(__imp__sub_82E16C70); PPC_FUNC_IMPL(__imp__sub_82E16C70);
PPC_FUNC(sub_82E16C70) PPC_FUNC(sub_82E16C70)
{ {
auto backBuffer = Video::GetBackBuffer();
auto scissorRect = reinterpret_cast<GuestRect*>(base + ctx.r4.u32); auto scissorRect = reinterpret_cast<GuestRect*>(base + ctx.r4.u32);
scissorRect->left = scissorRect->left + g_aspectRatioOffsetX; scissorRect->left = scissorRect->left + g_aspectRatioOffsetX;
@ -928,8 +935,6 @@ PPC_FUNC(sub_830D1EF0)
if (!PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET)) if (!PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET))
{ {
auto backBuffer = Video::GetBackBuffer();
struct Vertex struct Vertex
{ {
be<float> x; be<float> x;
@ -945,8 +950,8 @@ PPC_FUNC(sub_830D1EF0)
for (size_t i = 0; i < 4; i++) for (size_t i = 0; i < 4; i++)
{ {
vertex[i].x = vertex[i].x * 1280.0f / backBuffer->width; vertex[i].x = vertex[i].x * 1280.0f / Video::s_viewportWidth;
vertex[i].y = vertex[i].y * 720.0f / backBuffer->height; vertex[i].y = vertex[i].y * 720.0f / Video::s_viewportHeight;
} }
bool letterboxTop = PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET + 0x1); bool letterboxTop = PPC_LOAD_U8(r3.u32 + PRIMITIVE_2D_PADDING_OFFSET + 0x1);
@ -954,8 +959,8 @@ PPC_FUNC(sub_830D1EF0)
if (letterboxTop || letterboxBottom) if (letterboxTop || letterboxBottom)
{ {
float halfPixelX = 1.0f / backBuffer->width; float halfPixelX = 1.0f / Video::s_viewportWidth;
float halfPixelY = 1.0f / backBuffer->height; float halfPixelY = 1.0f / Video::s_viewportHeight;
if (letterboxTop) if (letterboxTop)
{ {
@ -1031,8 +1036,7 @@ static double ComputeObjGetItemX(uint32_t type)
x += g_aspectRatioOffsetX + scaleOffset; x += g_aspectRatioOffsetX + scaleOffset;
} }
auto backBuffer = Video::GetBackBuffer(); return (x - (0.5 * Video::s_viewportWidth)) / (0.5 * Video::s_viewportHeight) * OBJ_GET_ITEM_TANGENT;
return (x - (0.5 * backBuffer->width)) / (0.5 * backBuffer->height) * OBJ_GET_ITEM_TANGENT;
} }
return 0.0; return 0.0;
@ -1068,8 +1072,7 @@ static double ComputeObjGetItemY(uint32_t type)
y *= g_aspectRatioScale; y *= g_aspectRatioScale;
y += g_aspectRatioOffsetY * 2.0 + 720.0 * (1.0 - g_aspectRatioScale); y += g_aspectRatioOffsetY * 2.0 + 720.0 * (1.0 - g_aspectRatioScale);
auto backBuffer = Video::GetBackBuffer(); return ((0.5 * Video::s_viewportHeight) - y) / (0.5 * Video::s_viewportHeight) * OBJ_GET_ITEM_TANGENT;
return ((0.5 * backBuffer->height) - y) / (0.5 * backBuffer->height) * OBJ_GET_ITEM_TANGENT;
} }
return 0.25; return 0.25;
@ -1133,12 +1136,11 @@ PPC_FUNC(sub_82B8AA40)
PPC_STORE_U8(ctx.r3.u32, shouldDrawLetterbox); PPC_STORE_U8(ctx.r3.u32, shouldDrawLetterbox);
if (shouldDrawLetterbox) if (shouldDrawLetterbox)
{ {
auto backBuffer = Video::GetBackBuffer(); //uint32_t height = std::min(720u, Video::s_viewportHeight);
uint32_t height = std::min(720u, backBuffer->height);
PPC_STORE_U32(ctx.r3.u32 + 0xC, backBuffer->width); //PPC_STORE_U32(ctx.r3.u32 + 0xC, Video::s_viewportWidth);
PPC_STORE_U32(ctx.r3.u32 + 0x10, height); //PPC_STORE_U32(ctx.r3.u32 + 0x10, height);
PPC_STORE_U32(ctx.r3.u32 + 0x14, (height - backBuffer->width * 9 / 16) / 2); //PPC_STORE_U32(ctx.r3.u32 + 0x14, (height - Video::s_viewportWidth * 9 / 16) / 2);
} }
__imp__sub_82B8AA40(ctx, base); __imp__sub_82B8AA40(ctx, base);
@ -1161,5 +1163,5 @@ void InspireSubtitleMidAsmHook(PPCRegister& r3)
constexpr float NARROW_OFFSET = 485.0f; constexpr float NARROW_OFFSET = 485.0f;
constexpr float WIDE_OFFSET = 560.0f; constexpr float WIDE_OFFSET = 560.0f;
*reinterpret_cast<be<float>*>(g_memory.base + r3.u32 + 0x3C) = NARROW_OFFSET + (WIDE_OFFSET - NARROW_OFFSET) * g_narrowOffsetScale; *reinterpret_cast<be<float>*>(g_memory.base + r3.u32 + 0x3C) = NARROW_OFFSET + (WIDE_OFFSET - NARROW_OFFSET) * g_aspectRatioNarrowScale;
} }

View file

@ -8,7 +8,8 @@ inline float g_aspectRatio;
inline float g_aspectRatioOffsetX; inline float g_aspectRatioOffsetX;
inline float g_aspectRatioOffsetY; inline float g_aspectRatioOffsetY;
inline float g_aspectRatioScale; inline float g_aspectRatioScale;
inline float g_narrowOffsetScale; inline float g_aspectRatioGameplayScale;
inline float g_aspectRatioNarrowScale;
struct AspectRatioPatches struct AspectRatioPatches
{ {

View file

@ -36,9 +36,8 @@ PPC_FUNC(sub_82AE30D8)
scaleV = g_aspectRatio / movieAspectRatio; scaleV = g_aspectRatio / movieAspectRatio;
} }
auto backBuffer = Video::GetBackBuffer(); float halfPixelX = 1.0f / Video::s_viewportWidth;
float halfPixelX = 1.0f / backBuffer->width; float halfPixelY = 1.0f / Video::s_viewportHeight;
float halfPixelY = 1.0f / backBuffer->height;
pTopLeft->X = -1.0f - halfPixelX; pTopLeft->X = -1.0f - halfPixelX;
pTopLeft->Y = 1.0f + halfPixelY; pTopLeft->Y = 1.0f + halfPixelY;

View file

@ -224,6 +224,7 @@ void GameWindow::Init(const char* sdlVideoDriver)
SetTitle(); SetTitle();
SDL_SetWindowMinimumSize(s_pWindow, MIN_WIDTH, MIN_HEIGHT); SDL_SetWindowMinimumSize(s_pWindow, MIN_WIDTH, MIN_HEIGHT);
SDL_SetWindowMaximumSize(s_pWindow, 1280 * 2, 720 * 2);
SDL_SysWMinfo info; SDL_SysWMinfo info;
SDL_VERSION(&info.version); SDL_VERSION(&info.version);

View file

@ -161,7 +161,7 @@ static void DrawScanlineBars()
if (g_aspectRatio >= WIDE_ASPECT_RATIO) if (g_aspectRatio >= WIDE_ASPECT_RATIO)
optionsX = g_aspectRatioOffsetX; optionsX = g_aspectRatioOffsetX;
else else
optionsX = (1.0f - g_narrowOffsetScale) * -20.0f; optionsX = (1.0f - g_aspectRatioNarrowScale) * -20.0f;
// Options text // Options text
DrawTextWithOutline DrawTextWithOutline
@ -322,7 +322,7 @@ static bool DrawCategories()
constexpr float WIDE_PADDING_GRID_COUNT = 3.0f; constexpr float WIDE_PADDING_GRID_COUNT = 3.0f;
float gridSize = Scale(GRID_SIZE); float gridSize = Scale(GRID_SIZE);
float textPadding = gridSize * Lerp(NARROW_PADDING_GRID_COUNT, WIDE_PADDING_GRID_COUNT, g_narrowOffsetScale); float textPadding = gridSize * Lerp(NARROW_PADDING_GRID_COUNT, WIDE_PADDING_GRID_COUNT, g_aspectRatioNarrowScale);
float tabPadding = gridSize; float tabPadding = gridSize;
float size = Scale(32.0f); float size = Scale(32.0f);
@ -468,7 +468,7 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
constexpr float OPTION_WIDE_GRID_COUNT = 54.0f; constexpr float OPTION_WIDE_GRID_COUNT = 54.0f;
auto gridSize = Scale(GRID_SIZE); auto gridSize = Scale(GRID_SIZE);
auto optionWidth = gridSize * floor(Lerp(OPTION_NARROW_GRID_COUNT, OPTION_WIDE_GRID_COUNT, g_narrowOffsetScale)); auto optionWidth = gridSize * floor(Lerp(OPTION_NARROW_GRID_COUNT, OPTION_WIDE_GRID_COUNT, g_aspectRatioNarrowScale));
auto optionHeight = gridSize * 5.5f; auto optionHeight = gridSize * 5.5f;
auto optionPadding = gridSize * 0.5f; auto optionPadding = gridSize * 0.5f;
auto valueWidth = Scale(192.0f); auto valueWidth = Scale(192.0f);
@ -1220,9 +1220,9 @@ void OptionsMenu::Draw()
DrawScanlineBars(); DrawScanlineBars();
float settingsGridCount = floor(Lerp(SETTINGS_NARROW_GRID_COUNT, SETTINGS_WIDE_GRID_COUNT, g_narrowOffsetScale)); float settingsGridCount = floor(Lerp(SETTINGS_NARROW_GRID_COUNT, SETTINGS_WIDE_GRID_COUNT, g_aspectRatioNarrowScale));
float paddingGridCount = Lerp(PADDING_NARROW_GRID_COUNT, PADDING_WIDE_GRID_COUNT, g_narrowOffsetScale); float paddingGridCount = Lerp(PADDING_NARROW_GRID_COUNT, PADDING_WIDE_GRID_COUNT, g_aspectRatioNarrowScale);
float infoGridCount = floor(Lerp(INFO_NARROW_GRID_COUNT, INFO_WIDE_GRID_COUNT, g_narrowOffsetScale)); float infoGridCount = floor(Lerp(INFO_NARROW_GRID_COUNT, INFO_WIDE_GRID_COUNT, g_aspectRatioNarrowScale));
float totalGridCount = settingsGridCount + paddingGridCount + infoGridCount; float totalGridCount = settingsGridCount + paddingGridCount + infoGridCount;
float offsetX = g_aspectRatioOffsetX + (1280.0f - ((GRID_SIZE * totalGridCount) - 1)) / 2.0f; float offsetX = g_aspectRatioOffsetX + (1280.0f - ((GRID_SIZE * totalGridCount) - 1)) / 2.0f;