pvr: xform matrix 240p support. screen stretching changes
Use FB_R_CTRL.vclk_div to detect progressive mode. transform_matrix: Support non-4:3 aspect ratio such as 640x240. Don't expect 480 height. Issue #690 Add black bars at top and bottom if screen aspect ratio is too low. Issue #584. Framebuffer size doesn't depend on screen stretching. Stretching is done when blitting to screen. lr: correct subsequent stretching when drawing vmus and xhair
This commit is contained in:
parent
9d17fc15a3
commit
8e8935b9c4
|
@ -371,8 +371,10 @@ void rend_resize_renderer()
|
|||
{
|
||||
if (renderer == nullptr)
|
||||
return;
|
||||
int fbwidth = VO_CONTROL.pixel_double ? 320 : 640;
|
||||
int fbheight = (SPG_CONTROL.PAL == SPG_CONTROL.NTSC) || SPG_CONTROL.interlace == 1 ? 480 : 240;
|
||||
int fbwidth = 640 / (1 + VO_CONTROL.pixel_double) * (1 + SCALER_CTL.hscale);
|
||||
int fbheight = FB_R_CTRL.vclk_div == 1 || SPG_CONTROL.interlace == 1 ? 480 : 240;
|
||||
if (SPG_CONTROL.interlace == 0 && SCALER_CTL.vscalefactor > 0x400)
|
||||
fbheight *= std::roundf((float)SCALER_CTL.vscalefactor / 0x400);
|
||||
|
||||
float upscaling = config::RenderResolution / 480.f;
|
||||
float hres = fbwidth * upscaling;
|
||||
|
@ -380,18 +382,10 @@ void rend_resize_renderer()
|
|||
if (config::Widescreen && !config::Rotate90)
|
||||
{
|
||||
if (config::SuperWidescreen)
|
||||
hres = vres * settings.display.width / settings.display.height;
|
||||
hres *= (float)settings.display.width / settings.display.height / 4.f * 3.f;
|
||||
else
|
||||
hres *= 4.f / 3.f;
|
||||
}
|
||||
else if (config::Rotate90)
|
||||
{
|
||||
vres *= config::ScreenStretching / 100.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
hres *= config::ScreenStretching / 100.f;
|
||||
}
|
||||
if (!config::Rotate90)
|
||||
hres = std::roundf(hres / 2.f) * 2.f;
|
||||
DEBUG_LOG(RENDERER, "rend_resize_renderer: %d x %d", (int)hres, (int)vres);
|
||||
|
|
|
@ -178,7 +178,10 @@ void pvr_WriteReg(u32 paddr,u32 data)
|
|||
bool vclk_div_changed = (PvrReg(addr, u32) ^ data) & (1 << 23);
|
||||
PvrReg(addr, u32) = data;
|
||||
if (vclk_div_changed)
|
||||
{
|
||||
CalculateSync();
|
||||
rend_needs_resize = true;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
|
@ -36,30 +36,6 @@ static u32 lightgun_line = 0xffff;
|
|||
static u32 lightgun_hpos;
|
||||
static bool maple_int_pending;
|
||||
|
||||
static void setFramebufferScaling()
|
||||
{
|
||||
float scale_x = 1.f;
|
||||
float scale_y = 1.f;
|
||||
|
||||
if (SPG_CONTROL.interlace)
|
||||
{
|
||||
//u32 interl_mode=VO_CONTROL.field_mode;
|
||||
//if (interl_mode==2)//3 will be funny =P
|
||||
// scale_y=0.5f;//single interlace
|
||||
//else
|
||||
scale_y = 1.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FB_R_CTRL.vclk_div)
|
||||
scale_y = 1.0f;//non interlaced VGA mode has full resolution :)
|
||||
else
|
||||
scale_y = 0.5f;//non interlaced modes have half resolution
|
||||
}
|
||||
|
||||
rend_set_fb_scale(scale_x, scale_y);
|
||||
}
|
||||
|
||||
void CalculateSync()
|
||||
{
|
||||
u32 pixel_clock = PIXEL_CLOCK / (FB_R_CTRL.vclk_div ? 1 : 2);
|
||||
|
@ -72,8 +48,6 @@ void CalculateSync()
|
|||
if (SPG_CONTROL.interlace)
|
||||
Line_Cycles /= 2;
|
||||
|
||||
setFramebufferScaling();
|
||||
|
||||
Frame_Cycles = pvr_numscanlines * Line_Cycles;
|
||||
prv_cur_scanline = 0;
|
||||
clc_pvr_scanline = 0;
|
||||
|
@ -377,6 +351,4 @@ void spg_Deserialize(Deserializer& deser)
|
|||
}
|
||||
if (deser.version() < Deserializer::V14)
|
||||
CalculateSync();
|
||||
else
|
||||
setFramebufferScaling();
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ void DX11Overlay::draw(u32 width, u32 height, bool vmu, bool crosshair)
|
|||
#ifdef LIBRETRO
|
||||
if (i & 1)
|
||||
continue;
|
||||
w *= vmu_screen_params[i / 2].vmu_screen_size_mult;
|
||||
w *= (float)vmu_screen_params[i / 2].vmu_screen_size_mult / config::ScreenStretching * 100.f;
|
||||
h *= vmu_screen_params[i / 2].vmu_screen_size_mult;
|
||||
switch (vmu_screen_params[i / 2].vmu_screen_position)
|
||||
{
|
||||
|
@ -170,15 +170,18 @@ void DX11Overlay::draw(u32 width, u32 height, bool vmu, bool crosshair)
|
|||
float x, y;
|
||||
std::tie(x, y) = getCrosshairPosition(i);
|
||||
#ifdef LIBRETRO
|
||||
float halfWidth = LIGHTGUN_CROSSHAIR_SIZE / 2.f;
|
||||
float halfWidth = LIGHTGUN_CROSSHAIR_SIZE / 2.f / config::ScreenStretching * 100.f;
|
||||
float halfHeight = LIGHTGUN_CROSSHAIR_SIZE / 2.f;
|
||||
x /= config::ScreenStretching / 100.f;
|
||||
#else
|
||||
float halfWidth = XHAIR_WIDTH * settings.display.uiScale / 2.f;
|
||||
float halfHeight = halfWidth;
|
||||
#endif
|
||||
D3D11_VIEWPORT vp{};
|
||||
vp.TopLeftX = x - halfWidth;
|
||||
vp.TopLeftY = y - halfWidth;
|
||||
vp.TopLeftY = y - halfHeight;
|
||||
vp.Width = halfWidth * 2;
|
||||
vp.Height = halfWidth * 2;
|
||||
vp.Height = halfHeight * 2;
|
||||
vp.MinDepth = 0.f;
|
||||
vp.MaxDepth = 1.f;
|
||||
deviceContext->RSSetViewports(1, &vp);
|
||||
|
|
|
@ -503,28 +503,22 @@ void DX11Renderer::renderFramebuffer()
|
|||
deviceContext->ClearRenderTargetView(theDX11Context.getRenderTarget(), colors);
|
||||
int outwidth = settings.display.width;
|
||||
int outheight = settings.display.height;
|
||||
float renderAR = getOutputFramebufferAspectRatio();
|
||||
float screenAR = (float)outwidth / outheight;
|
||||
if (config::Rotate90)
|
||||
std::swap(outwidth, outheight);
|
||||
float renderAR = (float)width / height;
|
||||
float screenAR = (float)outwidth / outheight;
|
||||
int dy = 0;
|
||||
int dx = 0;
|
||||
if (renderAR > screenAR)
|
||||
dy = (int)roundf((outheight - outwidth / renderAR) / 2.f);
|
||||
dy = (int)roundf(outheight * (1 - screenAR / renderAR) / 2.f);
|
||||
else
|
||||
dx = (int)roundf((outwidth - outheight * renderAR) / 2.f);
|
||||
dx = (int)roundf(outwidth * (1 - renderAR / screenAR) / 2.f);
|
||||
|
||||
float x = (float)dx;
|
||||
float y = (float)dy;
|
||||
float w = (float)(outwidth - 2 * dx);
|
||||
float h = (float)(outheight - 2 * dy);
|
||||
|
||||
float x = 0, y = 0, w = (float)outwidth, h = (float)outheight;
|
||||
if (dx != 0)
|
||||
{
|
||||
x = (float)dx;
|
||||
w = (float)(outwidth - 2 * dx);
|
||||
}
|
||||
else
|
||||
{
|
||||
y = (float)dy;
|
||||
h = (float)(outheight - 2 * dy);
|
||||
}
|
||||
// Normalize
|
||||
x = x * 2.f / outwidth - 1.f;
|
||||
w *= 2.f / outwidth;
|
||||
|
|
|
@ -1103,33 +1103,19 @@ void D3DRenderer::renderFramebuffer()
|
|||
{
|
||||
devCache.SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
|
||||
device->ColorFill(backbuffer, 0, D3DCOLOR_ARGB(255, VO_BORDER_COL._red, VO_BORDER_COL._green, VO_BORDER_COL._blue));
|
||||
int fx = 0;
|
||||
int sx = 0;
|
||||
float renderAR = getOutputFramebufferAspectRatio();
|
||||
float screenAR = (float)settings.display.width / settings.display.height;
|
||||
int fbwidth = width;
|
||||
int fbheight = height;
|
||||
if (config::Rotate90)
|
||||
std::swap(fbwidth, fbheight);
|
||||
float renderAR = (float)fbwidth / fbheight;
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
if (renderAR > screenAR)
|
||||
fx = (int)roundf((fbwidth - screenAR * fbheight) / 2.f);
|
||||
dy = (int)roundf(settings.display.height * (1 - screenAR / renderAR) / 2.f);
|
||||
else
|
||||
sx = (int)roundf((settings.display.width - renderAR * settings.display.height) / 2.f);
|
||||
dx = (int)roundf(settings.display.width * (1 - renderAR / screenAR) / 2.f);
|
||||
|
||||
if (!config::Rotate90)
|
||||
{
|
||||
RECT rs { 0, 0, (long)width, (long)height };
|
||||
RECT rd { 0, 0, settings.display.width, settings.display.height };
|
||||
if (sx != 0)
|
||||
{
|
||||
rd.left = sx;
|
||||
rd.right = settings.display.width - sx;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs.left = fx;
|
||||
rs.right = width - fx;
|
||||
}
|
||||
RECT rd { dx, dy, settings.display.width - dx, settings.display.height - dy };
|
||||
device->StretchRect(framebufferSurface, &rs, backbuffer, &rd,
|
||||
config::TextureFiltering == 1 ? D3DTEXF_POINT : D3DTEXF_LINEAR); // This can fail if window is minimized
|
||||
}
|
||||
|
@ -1154,10 +1140,10 @@ void D3DRenderer::renderFramebuffer()
|
|||
|
||||
device->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1);
|
||||
D3DVIEWPORT9 viewport;
|
||||
viewport.X = sx;
|
||||
viewport.Y = fx * settings.display.width / height;
|
||||
viewport.Width = settings.display.width - sx * 2;
|
||||
viewport.Height = settings.display.height - 2 * fx * settings.display.width / height;
|
||||
viewport.X = dx;
|
||||
viewport.Y = dy;
|
||||
viewport.Width = settings.display.width - dx * 2;
|
||||
viewport.Height = settings.display.height - dy * 2;
|
||||
viewport.MinZ = 0;
|
||||
viewport.MaxZ = 1;
|
||||
verifyWin(device->SetViewport(&viewport));
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "rend/tileclip.h"
|
||||
#include "rend/osd.h"
|
||||
#include "naomi2.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
|
||||
/*
|
||||
|
||||
|
@ -700,12 +701,7 @@ void DrawStrips()
|
|||
|
||||
void DrawFramebuffer()
|
||||
{
|
||||
float aspectRatio = 4.f / 3.f;
|
||||
if (config::Rotate90)
|
||||
aspectRatio /= config::ScreenStretching / 100.f;
|
||||
else
|
||||
aspectRatio *= config::ScreenStretching / 100.f;
|
||||
int sx = (int)roundf((gl.ofbo.width - aspectRatio * gl.ofbo.height) / 2.f);
|
||||
int sx = (int)roundf((gl.ofbo.width - 4.f / 3.f * gl.ofbo.height) / 2.f);
|
||||
glViewport(sx, 0, gl.ofbo.width - sx * 2, gl.ofbo.height);
|
||||
drawQuad(fbTextureId, false, true);
|
||||
glcache.DeleteTextures(1, &fbTextureId);
|
||||
|
@ -715,27 +711,21 @@ void DrawFramebuffer()
|
|||
bool render_output_framebuffer()
|
||||
{
|
||||
glcache.Disable(GL_SCISSOR_TEST);
|
||||
int fx = 0;
|
||||
int sx = 0;
|
||||
float screenAR = (float)settings.display.width / settings.display.height;
|
||||
int fbwidth = gl.ofbo.width;
|
||||
int fbheight = gl.ofbo.height;
|
||||
if (config::Rotate90)
|
||||
std::swap(fbwidth, fbheight);
|
||||
float renderAR = (float)fbwidth / fbheight;
|
||||
float renderAR = getOutputFramebufferAspectRatio();
|
||||
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
if (renderAR > screenAR)
|
||||
fx = (int)roundf((fbwidth - screenAR * fbheight) / 2.f);
|
||||
dy = (int)roundf(settings.display.height * (1 - screenAR / renderAR) / 2.f);
|
||||
else
|
||||
sx = (int)roundf((settings.display.width - renderAR * settings.display.height) / 2.f);
|
||||
dx = (int)roundf(settings.display.width * (1 - renderAR / screenAR) / 2.f);
|
||||
|
||||
if (gl.gl_major < 3 || config::Rotate90)
|
||||
{
|
||||
if (gl.ofbo.tex == 0)
|
||||
return false;
|
||||
if (sx != 0)
|
||||
glViewport(sx, 0, settings.display.width - sx * 2, settings.display.height);
|
||||
else
|
||||
glViewport(-fx, 0, settings.display.width + fx * 2, settings.display.height);
|
||||
glViewport(dx, dy, settings.display.width - dx * 2, settings.display.height - dy * 2);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl.ofbo.origFbo);
|
||||
glcache.ClearColor(VO_BORDER_COL.red(), VO_BORDER_COL.green(), VO_BORDER_COL.blue(), 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
@ -752,8 +742,8 @@ bool render_output_framebuffer()
|
|||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gl.ofbo.origFbo);
|
||||
glcache.ClearColor(VO_BORDER_COL.red(), VO_BORDER_COL.green(), VO_BORDER_COL.blue(), 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glBlitFramebuffer(fx, 0, gl.ofbo.width - fx, gl.ofbo.height,
|
||||
sx, 0, settings.display.width - sx, settings.display.height,
|
||||
glBlitFramebuffer(0, 0, gl.ofbo.width, gl.ofbo.height,
|
||||
dx, dy, settings.display.width - dx, settings.display.height - dy,
|
||||
GL_COLOR_BUFFER_BIT, config::TextureFiltering == 1 ? GL_NEAREST : GL_LINEAR);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl.ofbo.origFbo);
|
||||
#endif
|
||||
|
@ -834,7 +824,7 @@ void DrawVmuTexture(u8 vmu_screen_number)
|
|||
const float vmu_padding = 8.f;
|
||||
float x = (config::Widescreen && config::ScreenStretching == 100 ? -(640.f * 4.f / 3.f - 640.f) / 2 : 0) + vmu_padding;
|
||||
float y = vmu_padding;
|
||||
float w = VMU_SCREEN_WIDTH * vmu_screen_params[vmu_screen_number].vmu_screen_size_mult;
|
||||
float w = (float)VMU_SCREEN_WIDTH * vmu_screen_params[vmu_screen_number].vmu_screen_size_mult / config::ScreenStretching * 100.f;
|
||||
float h = VMU_SCREEN_HEIGHT * vmu_screen_params[vmu_screen_number].vmu_screen_size_mult;
|
||||
|
||||
if (vmu_lcd_changed[vmu_screen_number * 2] || vmuTextureId[vmu_screen_number] == 0)
|
||||
|
@ -938,11 +928,12 @@ void DrawGunCrosshair(u8 port)
|
|||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
float x = lightgun_params[port].x;
|
||||
float stretch = config::ScreenStretching / 100.f;
|
||||
float x = lightgun_params[port].x / stretch;
|
||||
float y = lightgun_params[port].y;
|
||||
|
||||
float w = LIGHTGUN_CROSSHAIR_SIZE;
|
||||
float h = LIGHTGUN_CROSSHAIR_SIZE;
|
||||
float w = (float)LIGHTGUN_CROSSHAIR_SIZE / stretch;
|
||||
float h = (float)LIGHTGUN_CROSSHAIR_SIZE;
|
||||
x -= w / 2;
|
||||
y -= h / 2;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ class TransformMatrix
|
|||
{
|
||||
public:
|
||||
TransformMatrix() = default;
|
||||
TransformMatrix(const rend_context& renderingContext, int width = 0, int height = 0)
|
||||
TransformMatrix(const rend_context& renderingContext, int width, int height)
|
||||
{
|
||||
CalcMatrices(&renderingContext, width, height);
|
||||
}
|
||||
|
@ -141,36 +141,28 @@ public:
|
|||
normalMatrix = glm::translate(glm::vec3(startx, starty, 0));
|
||||
scissorMatrix = normalMatrix;
|
||||
|
||||
const float screen_stretching = config::ScreenStretching / 100.f;
|
||||
float scissoring_scale_x, scissoring_scale_y;
|
||||
GetFramebufferScaling(true, scissoring_scale_x, scissoring_scale_y);
|
||||
|
||||
float x_coef;
|
||||
float y_coef;
|
||||
glm::mat4 trans_rot;
|
||||
|
||||
if (config::Rotate90)
|
||||
if (config::Widescreen && !config::Rotate90)
|
||||
{
|
||||
float dc2s_scale_h = renderViewport.x / 640.0f;
|
||||
|
||||
sidebarWidth = 0;
|
||||
y_coef = 2.0f / (renderViewport.y / dc2s_scale_h * scale_y) * screen_stretching * screenFlipY;
|
||||
x_coef = 2.0f / dcViewport.x;
|
||||
sidebarWidth = (1 - dcViewport.x / dcViewport.y * renderViewport.y / renderViewport.x) / 2;
|
||||
if (config::SuperWidescreen)
|
||||
dcViewport.x *= (float)settings.display.width / settings.display.height / 4.f * 3.f;
|
||||
else
|
||||
dcViewport.x *= 4.f / 3.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float dc2s_scale_h = renderViewport.y / 480.0f;
|
||||
sidebarWidth = 0;
|
||||
float x_coef = 2.0f / dcViewport.x;
|
||||
float y_coef = 2.0f / dcViewport.y * screenFlipY;
|
||||
|
||||
sidebarWidth = (renderViewport.x - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
x_coef = 2.0f / (renderViewport.x / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
y_coef = 2.0f / dcViewport.y * screenFlipY;
|
||||
}
|
||||
trans_rot = glm::translate(glm::vec3(-1 + 2 * sidebarWidth / renderViewport.x, -screenFlipY, 0));
|
||||
glm::mat4 trans = glm::translate(glm::vec3(-1 + 2 * sidebarWidth, -screenFlipY, 0));
|
||||
|
||||
normalMatrix = trans_rot
|
||||
normalMatrix = trans
|
||||
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
||||
* normalMatrix;
|
||||
scissorMatrix = trans_rot
|
||||
scissorMatrix = trans
|
||||
* glm::scale(glm::vec3(x_coef * scissoring_scale_x, y_coef * scissoring_scale_y, 1.f))
|
||||
* scissorMatrix;
|
||||
}
|
||||
|
@ -200,11 +192,8 @@ private:
|
|||
|
||||
if (!renderingContext->isRTT && !renderingContext->isRenderFramebuffer)
|
||||
{
|
||||
if (!scissor)
|
||||
{
|
||||
scale_x = fb_scale_x;
|
||||
scale_y = fb_scale_y;
|
||||
}
|
||||
if (!scissor && (FB_R_CTRL.vclk_div == 0 && SPG_CONTROL.interlace == 0))
|
||||
scale_y /= 2.f;
|
||||
if (SCALER_CTL.vscalefactor > 0x400)
|
||||
{
|
||||
// Interlace mode A (single framebuffer)
|
||||
|
@ -216,9 +205,8 @@ private:
|
|||
}
|
||||
|
||||
// VO pixel doubling is done after fb rendering/clipping
|
||||
// so it should be used for scissoring as well
|
||||
if (VO_CONTROL.pixel_double && !scissor)
|
||||
scale_x *= 0.5f;
|
||||
scale_x /= 2.f;
|
||||
|
||||
// the X Scaler halves the horizontal resolution but
|
||||
// before clipping/scissoring
|
||||
|
@ -238,3 +226,25 @@ private:
|
|||
float scale_y = 0;
|
||||
float sidebarWidth = 0;
|
||||
};
|
||||
|
||||
inline static float getOutputFramebufferAspectRatio()
|
||||
{
|
||||
float renderAR;
|
||||
if (config::Rotate90)
|
||||
{
|
||||
renderAR = 3.f / 4.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config::Widescreen)
|
||||
{
|
||||
if (config::SuperWidescreen)
|
||||
renderAR = (float)settings.display.width / settings.display.height;
|
||||
else
|
||||
renderAR = 16.f / 9.f;
|
||||
}
|
||||
else
|
||||
renderAR = 4.f / 3.f;
|
||||
}
|
||||
return renderAR * config::ScreenStretching / 100.f;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
if ((u32)w == viewport.width && (u32)h == viewport.height)
|
||||
return;
|
||||
BaseVulkanRenderer::Resize(w, h);
|
||||
GetContext()->WaitIdle();
|
||||
screenDrawer.Init(&samplerManager, &oitShaderManager, &oitBuffers, viewport);
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,8 @@ void VulkanOverlay::Draw(vk::CommandBuffer commandBuffer, vk::Extent2D viewport,
|
|||
vmu_width *= 2.f;
|
||||
float blendConstants[4] = { 0.75f, 0.75f, 0.75f, 0.75f };
|
||||
color = blendConstants;
|
||||
#else
|
||||
vmu_width /= config::ScreenStretching / 100.f;
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < vmuTextures.size(); i++)
|
||||
|
@ -207,8 +209,9 @@ void VulkanOverlay::Draw(vk::CommandBuffer commandBuffer, vk::Extent2D viewport,
|
|||
std::tie(x, y) = getCrosshairPosition(i);
|
||||
|
||||
#ifdef LIBRETRO
|
||||
float w = LIGHTGUN_CROSSHAIR_SIZE * scaling;
|
||||
float w = LIGHTGUN_CROSSHAIR_SIZE * scaling / config::ScreenStretching * 100.f;
|
||||
float h = LIGHTGUN_CROSSHAIR_SIZE * scaling;
|
||||
x /= config::ScreenStretching / 100.f;
|
||||
#else
|
||||
float w = XHAIR_WIDTH * scaling;
|
||||
float h = XHAIR_HEIGHT * scaling;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "emulator.h"
|
||||
#include "oslib/oslib.h"
|
||||
#include "vulkan_driver.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
|
||||
void ReInitOSD();
|
||||
|
||||
|
@ -861,14 +862,18 @@ void VulkanContext::DrawFrame(vk::ImageView imageView, const vk::Extent2D& exten
|
|||
else
|
||||
quadPipeline->BindPipeline(commandBuffer);
|
||||
|
||||
float marginWidth;
|
||||
if (config::Rotate90)
|
||||
marginWidth = ((float)width - (float)extent.height / extent.width * height) / 2.f;
|
||||
float renderAR = getOutputFramebufferAspectRatio();
|
||||
float screenAR = (float)width / height;
|
||||
float dx = 0;
|
||||
float dy = 0;
|
||||
if (renderAR > screenAR)
|
||||
dy = height * (1 - screenAR / renderAR) / 2;
|
||||
else
|
||||
marginWidth = ((float)width - (float)extent.width / extent.height * height) / 2.f;
|
||||
vk::Viewport viewport(marginWidth, 0, width - marginWidth * 2.f, height);
|
||||
dx = width * (1 - renderAR / screenAR) / 2;
|
||||
|
||||
vk::Viewport viewport(dx, dy, width - dx * 2, height - dy * 2);
|
||||
commandBuffer.setViewport(0, 1, &viewport);
|
||||
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(std::max(0.f, marginWidth), 0), vk::Extent2D(width - marginWidth * 2.f, height)));
|
||||
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(dx, dy), vk::Extent2D(width - dx * 2, height - dy * 2)));
|
||||
if (config::Rotate90)
|
||||
quadRotateDrawer->Draw(commandBuffer, imageView, vtx, config::TextureFiltering == 1);
|
||||
else
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
if ((u32)w == viewport.width && (u32)h == viewport.height)
|
||||
return;
|
||||
BaseVulkanRenderer::Resize(w, h);
|
||||
GetContext()->WaitIdle();
|
||||
screenDrawer.Init(&samplerManager, &shaderManager, viewport);
|
||||
}
|
||||
|
||||
|
|
|
@ -153,8 +153,6 @@ public:
|
|||
|
||||
void Resize(int w, int h) override
|
||||
{
|
||||
if ((u32)w == viewport.width && (u32)h == viewport.height)
|
||||
return;
|
||||
viewport.width = w;
|
||||
viewport.height = h;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue