pvr: copy pvr regs at start_render time to avoid concurrent update
copy TA_GLOB_TILE_CLIP and SCALER_CTL to rend context when starting render. Use rend context copy to calculate framebuffer size. Fixes framebuffer size glitches in vf4 water stages. lr: pass aspect ratio when resizing. dx11: Wrong sizing of rotated games. gl: test automation fixes.
This commit is contained in:
parent
5722dc90f0
commit
c1f0dd81d2
|
@ -20,7 +20,7 @@ void retro_rend_present()
|
|||
sh4_cpu.Stop();
|
||||
}
|
||||
#endif
|
||||
void retro_resize_renderer(int w, int h);
|
||||
void retro_resize_renderer(int w, int h, float aspectRatio);
|
||||
|
||||
u32 FrameCount=1;
|
||||
|
||||
|
@ -175,7 +175,8 @@ private:
|
|||
bool renderToScreen = !_pvrrc->rend.isRTT && !config::EmulateFramebuffer;
|
||||
#ifdef LIBRETRO
|
||||
if (renderToScreen)
|
||||
retro_resize_renderer(_pvrrc->rend.framebufferWidth, _pvrrc->rend.framebufferHeight);
|
||||
retro_resize_renderer(_pvrrc->rend.framebufferWidth, _pvrrc->rend.framebufferHeight,
|
||||
getOutputFramebufferAspectRatio(_pvrrc->rend));
|
||||
#endif
|
||||
bool proc = renderer->Process(_pvrrc);
|
||||
if (!proc || renderToScreen)
|
||||
|
@ -198,8 +199,8 @@ private:
|
|||
{
|
||||
#ifdef LIBRETRO
|
||||
int w, h;
|
||||
getTAViewport(w, h); // FIXME ?
|
||||
retro_resize_renderer(w, h);
|
||||
getDCFramebufferReadSize(w, h);
|
||||
retro_resize_renderer(w, h, getDCFramebufferAspectRatio());
|
||||
#endif
|
||||
renderer->RenderFramebuffer(config);
|
||||
}
|
||||
|
@ -344,6 +345,8 @@ void rend_start_render()
|
|||
ctx->rend.fb_W_SOF1 = FB_W_SOF1;
|
||||
ctx->rend.fb_W_CTRL.full = FB_W_CTRL.full;
|
||||
|
||||
ctx->rend.ta_GLOB_TILE_CLIP = TA_GLOB_TILE_CLIP;
|
||||
ctx->rend.scaler_ctl = SCALER_CTL;
|
||||
ctx->rend.fb_X_CLIP = FB_X_CLIP;
|
||||
ctx->rend.fb_Y_CLIP = FB_Y_CLIP;
|
||||
ctx->rend.fb_W_LINESTRIDE = FB_W_LINESTRIDE.stride;
|
||||
|
@ -354,7 +357,7 @@ void rend_start_render()
|
|||
if (!ctx->rend.isRTT)
|
||||
{
|
||||
int width, height;
|
||||
getScaledFramebufferSize(width, height);
|
||||
getScaledFramebufferSize(ctx->rend, width, height);
|
||||
ctx->rend.framebufferWidth = width;
|
||||
ctx->rend.framebufferHeight = height;
|
||||
}
|
||||
|
|
|
@ -227,6 +227,8 @@ struct rend_context
|
|||
bool Overrun;
|
||||
bool isRTT;
|
||||
|
||||
TA_GLOB_TILE_CLIP_type ta_GLOB_TILE_CLIP;
|
||||
SCALER_CTL_type scaler_ctl;
|
||||
FB_X_CLIP_type fb_X_CLIP;
|
||||
FB_Y_CLIP_type fb_Y_CLIP;
|
||||
u32 fb_W_LINESTRIDE;
|
||||
|
|
|
@ -443,9 +443,10 @@ bool DX11Renderer::Render()
|
|||
}
|
||||
else
|
||||
{
|
||||
aspectRatio = getOutputFramebufferAspectRatio(pvrrc);
|
||||
#ifndef LIBRETRO
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
renderFramebuffer();
|
||||
displayFramebuffer();
|
||||
DrawOSD(false);
|
||||
theDX11Context.setFrameRendered();
|
||||
#else
|
||||
|
@ -461,7 +462,7 @@ bool DX11Renderer::Render()
|
|||
return !is_rtt;
|
||||
}
|
||||
|
||||
void DX11Renderer::renderFramebuffer()
|
||||
void DX11Renderer::displayFramebuffer()
|
||||
{
|
||||
#ifndef LIBRETRO
|
||||
D3D11_VIEWPORT vp{};
|
||||
|
@ -479,10 +480,12 @@ 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)
|
||||
float renderAR = aspectRatio;
|
||||
if (config::Rotate90) {
|
||||
std::swap(outwidth, outheight);
|
||||
renderAR = 1 / renderAR;
|
||||
}
|
||||
float screenAR = (float)outwidth / outheight;
|
||||
int dy = 0;
|
||||
int dx = 0;
|
||||
if (renderAR > screenAR)
|
||||
|
@ -874,7 +877,7 @@ bool DX11Renderer::RenderLastFrame()
|
|||
{
|
||||
if (!frameRenderedOnce)
|
||||
return false;
|
||||
renderFramebuffer();
|
||||
displayFramebuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -952,9 +955,10 @@ void DX11Renderer::RenderFramebuffer(const FramebufferInfo& info)
|
|||
float bar = (this->width - this->height * 640.f / 480.f) / 2.f;
|
||||
quad->draw(dcfbTextureView, samplers->getSampler(true), nullptr, bar / this->width * 2.f - 1.f, -1.f, (this->width - bar * 2.f) / this->width * 2.f, 2.f);
|
||||
|
||||
aspectRatio = getDCFramebufferAspectRatio();
|
||||
#ifndef LIBRETRO
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
renderFramebuffer();
|
||||
displayFramebuffer();
|
||||
DrawOSD(false);
|
||||
theDX11Context.setFrameRendered();
|
||||
#else
|
||||
|
|
|
@ -93,7 +93,7 @@ protected:
|
|||
void updateFogTexture();
|
||||
void updatePaletteTexture();
|
||||
void readRttRenderTarget(u32 texAddress);
|
||||
void renderFramebuffer();
|
||||
void displayFramebuffer();
|
||||
void setCullMode(int mode);
|
||||
virtual void setRTTSize(int width, int height) {}
|
||||
void writeFramebufferToVRAM();
|
||||
|
@ -122,6 +122,7 @@ protected:
|
|||
bool frameRendered = false;
|
||||
bool frameRenderedOnce = false;
|
||||
Naomi2Helper n2Helper;
|
||||
float aspectRatio = 4.f / 3.f;
|
||||
|
||||
private:
|
||||
void readDCFramebuffer();
|
||||
|
|
|
@ -672,9 +672,10 @@ struct DX11OITRenderer : public DX11Renderer
|
|||
}
|
||||
else
|
||||
{
|
||||
aspectRatio = getOutputFramebufferAspectRatio(pvrrc);
|
||||
#ifndef LIBRETRO
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
renderFramebuffer();
|
||||
displayFramebuffer();
|
||||
DrawOSD(false);
|
||||
theDX11Context.setFrameRendered();
|
||||
#else
|
||||
|
|
|
@ -287,6 +287,7 @@ void D3DRenderer::RenderFramebuffer(const FramebufferInfo& info)
|
|||
RECT rd{ (LONG)bar, 0, (LONG)(this->width - bar), (LONG)this->height };
|
||||
device->StretchRect(dcfbSurface, nullptr, framebufferSurface, &rd, D3DTEXF_LINEAR);
|
||||
|
||||
aspectRatio = getDCFramebufferAspectRatio();
|
||||
displayFramebuffer();
|
||||
DrawOSD(false);
|
||||
frameRendered = true;
|
||||
|
@ -1088,6 +1089,7 @@ bool D3DRenderer::Render()
|
|||
}
|
||||
else
|
||||
{
|
||||
aspectRatio = getOutputFramebufferAspectRatio(pvrrc);
|
||||
displayFramebuffer();
|
||||
DrawOSD(false);
|
||||
frameRendered = true;
|
||||
|
@ -1118,14 +1120,13 @@ void D3DRenderer::displayFramebuffer()
|
|||
{
|
||||
devCache.SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
|
||||
device->ColorFill(backbuffer, 0, D3DCOLOR_ARGB(255, VO_BORDER_COL._red, VO_BORDER_COL._green, VO_BORDER_COL._blue));
|
||||
float renderAR = getOutputFramebufferAspectRatio();
|
||||
float screenAR = (float)settings.display.width / settings.display.height;
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
if (renderAR > screenAR)
|
||||
dy = (int)roundf(settings.display.height * (1 - screenAR / renderAR) / 2.f);
|
||||
if (aspectRatio > screenAR)
|
||||
dy = (int)roundf(settings.display.height * (1 - screenAR / aspectRatio) / 2.f);
|
||||
else
|
||||
dx = (int)roundf(settings.display.width * (1 - renderAR / screenAR) / 2.f);
|
||||
dx = (int)roundf(settings.display.width * (1 - aspectRatio / screenAR) / 2.f);
|
||||
|
||||
if (!config::Rotate90)
|
||||
{
|
||||
|
|
|
@ -180,5 +180,6 @@ private:
|
|||
bool frameRendered = false;
|
||||
bool frameRenderedOnce = false;
|
||||
int maxAnisotropy = 1;
|
||||
float aspectRatio = 4.f / 3.f;
|
||||
};
|
||||
|
||||
|
|
|
@ -941,7 +941,7 @@ static bool RenderFrame(int width, int height)
|
|||
writeFramebufferToVRAM();
|
||||
#ifndef LIBRETRO
|
||||
else {
|
||||
gl.ofbo.aspectRatio = getOutputFramebufferAspectRatio();
|
||||
gl.ofbo.aspectRatio = getOutputFramebufferAspectRatio(_pvrrc->rend);
|
||||
render_output_framebuffer();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -708,7 +708,7 @@ void OpenGLRenderer::RenderFramebuffer(const FramebufferInfo& info)
|
|||
gl.ofbo2.framebuffer.reset();
|
||||
|
||||
if (gl.ofbo2.framebuffer == nullptr)
|
||||
gl.ofbo2.framebuffer = std::unique_ptr<GlFramebuffer>(new GlFramebuffer(gl.dcfb.width, gl.dcfb.height));
|
||||
gl.ofbo2.framebuffer = std::unique_ptr<GlFramebuffer>(new GlFramebuffer(gl.dcfb.width, gl.dcfb.height, false, true));
|
||||
else
|
||||
gl.ofbo2.framebuffer->bind();
|
||||
glCheck();
|
||||
|
|
|
@ -373,13 +373,16 @@ void do_swap_automation()
|
|||
static FILE* video_file = fopen(cfgLoadStr("record", "rawvid","").c_str(), "wb");
|
||||
extern bool do_screenshot;
|
||||
|
||||
GlFramebuffer *framebuffer = gl.ofbo2.ready ? gl.ofbo2.framebuffer.get() : gl.ofbo.framebuffer.get();
|
||||
if (framebuffer == nullptr)
|
||||
return;
|
||||
int bytesz = framebuffer->getWidth() * framebuffer->getHeight() * 3;
|
||||
if (video_file)
|
||||
{
|
||||
int bytesz = gl.ofbo.width * gl.ofbo.height * 3;
|
||||
u8* img = new u8[bytesz];
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, gl.ofbo.fbo);
|
||||
glReadPixels(0, 0, gl.ofbo.width, gl.ofbo.height, GL_RGB, GL_UNSIGNED_BYTE, img);
|
||||
framebuffer->bind(GL_READ_FRAMEBUFFER);
|
||||
glReadPixels(0, 0, framebuffer->getWidth(), framebuffer->getHeight(), GL_RGB, GL_UNSIGNED_BYTE, img);
|
||||
fwrite(img, 1, bytesz, video_file);
|
||||
delete[] img;
|
||||
fflush(video_file);
|
||||
|
@ -387,13 +390,12 @@ void do_swap_automation()
|
|||
|
||||
if (do_screenshot)
|
||||
{
|
||||
int bytesz = gl.ofbo.width * gl.ofbo.height * 3;
|
||||
u8* img = new u8[bytesz];
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, gl.ofbo.fbo);
|
||||
framebuffer->bind(GL_READ_FRAMEBUFFER);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, gl.ofbo.width, gl.ofbo.height, GL_RGB, GL_UNSIGNED_BYTE, img);
|
||||
dump_screenshot(img, gl.ofbo.width, gl.ofbo.height);
|
||||
glReadPixels(0, 0, framebuffer->getWidth(), framebuffer->getHeight(), GL_RGB, GL_UNSIGNED_BYTE, img);
|
||||
dump_screenshot(img, framebuffer->getWidth(), framebuffer->getHeight());
|
||||
delete[] img;
|
||||
dc_exit();
|
||||
flycast_term();
|
||||
|
@ -1380,7 +1382,7 @@ bool RenderFrame(int width, int height)
|
|||
writeFramebufferToVRAM();
|
||||
#ifndef LIBRETRO
|
||||
else {
|
||||
gl.ofbo.aspectRatio = getOutputFramebufferAspectRatio();
|
||||
gl.ofbo.aspectRatio = getOutputFramebufferAspectRatio(_pvrrc->rend);
|
||||
render_output_framebuffer();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -157,6 +157,7 @@ class GlFramebuffer
|
|||
{
|
||||
public:
|
||||
GlFramebuffer(int width, int height, bool withDepth = false, GLuint texture = 0);
|
||||
GlFramebuffer(int width, int height, bool withDepth, bool withTexture);
|
||||
~GlFramebuffer();
|
||||
|
||||
void bind(GLenum type = GL_FRAMEBUFFER) const {
|
||||
|
@ -175,6 +176,8 @@ public:
|
|||
GLuint getFramebuffer() const { return framebuffer; }
|
||||
|
||||
private:
|
||||
void makeFramebuffer(bool withDepth);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
GLuint texture;
|
||||
|
|
|
@ -440,7 +440,11 @@ GlFramebuffer::GlFramebuffer(int width, int height, bool withDepth, GLuint textu
|
|||
#endif
|
||||
}
|
||||
}
|
||||
makeFramebuffer(withDepth);
|
||||
}
|
||||
|
||||
void GlFramebuffer::makeFramebuffer(bool withDepth)
|
||||
{
|
||||
// Create the framebuffer
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
bind();
|
||||
|
@ -491,6 +495,33 @@ GlFramebuffer::GlFramebuffer(int width, int height, bool withDepth, GLuint textu
|
|||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
|
||||
}
|
||||
|
||||
GlFramebuffer::GlFramebuffer(int width, int height, bool withDepth, bool withTexture)
|
||||
{
|
||||
if (gl.gl_major < 3 || withTexture)
|
||||
{
|
||||
// Create a texture for rendering to
|
||||
texture = glcache.GenTexture();
|
||||
glcache.BindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use a renderbuffer and glBlitFramebuffer
|
||||
glGenRenderbuffers(1, &colorBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
|
||||
#ifdef GL_RGBA8
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
|
||||
#endif
|
||||
}
|
||||
|
||||
makeFramebuffer(withDepth);
|
||||
}
|
||||
|
||||
GlFramebuffer::~GlFramebuffer()
|
||||
{
|
||||
glDeleteFramebuffers(1, &framebuffer);
|
||||
|
|
|
@ -26,22 +26,22 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
inline static void getTAViewport(int& width, int& height)
|
||||
inline static void getTAViewport(const rend_context& rendCtx, int& width, int& height)
|
||||
{
|
||||
width = (TA_GLOB_TILE_CLIP.tile_x_num + 1) * 32;
|
||||
height = (TA_GLOB_TILE_CLIP.tile_y_num + 1) * 32;
|
||||
width = (rendCtx.ta_GLOB_TILE_CLIP.tile_x_num + 1) * 32;
|
||||
height = (rendCtx.ta_GLOB_TILE_CLIP.tile_y_num + 1) * 32;
|
||||
}
|
||||
|
||||
inline static void getPvrFramebufferSize(int& width, int& height)
|
||||
inline static void getPvrFramebufferSize(const rend_context& rendCtx, int& width, int& height)
|
||||
{
|
||||
getTAViewport(width, height);
|
||||
getTAViewport(rendCtx, width, height);
|
||||
if (!config::EmulateFramebuffer)
|
||||
{
|
||||
int maxHeight = FB_R_CTRL.vclk_div == 0 && SPG_CONTROL.interlace == 0 ? 240 : 480;
|
||||
if (SCALER_CTL.vscalefactor != 0
|
||||
&& (SCALER_CTL.vscalefactor > 1025 || SCALER_CTL.vscalefactor < 1024)
|
||||
if (rendCtx.scaler_ctl.vscalefactor != 0
|
||||
&& (rendCtx.scaler_ctl.vscalefactor > 1025 || rendCtx.scaler_ctl.vscalefactor < 1024)
|
||||
&& SPG_CONTROL.interlace == 0)
|
||||
maxHeight /= 1024.f / SCALER_CTL.vscalefactor;
|
||||
maxHeight /= 1024.f / rendCtx.scaler_ctl.vscalefactor;
|
||||
if (FB_R_CTRL.fb_line_double)
|
||||
maxHeight /= 2;
|
||||
height = std::min(maxHeight, height);
|
||||
|
@ -72,7 +72,7 @@ public:
|
|||
bool IsClipped() const
|
||||
{
|
||||
int width, height;
|
||||
getTAViewport(width, height);
|
||||
getTAViewport(*renderingContext, width, height);
|
||||
float sx, sy;
|
||||
GetScissorScaling(sx, sy);
|
||||
return renderingContext->fb_X_CLIP.min != 0
|
||||
|
@ -120,7 +120,7 @@ public:
|
|||
else
|
||||
{
|
||||
int w, h;
|
||||
getPvrFramebufferSize(w, h);
|
||||
getPvrFramebufferSize(*renderingContext, w, h);
|
||||
dcViewport.x = w;
|
||||
dcViewport.y = h;
|
||||
|
||||
|
@ -217,17 +217,17 @@ private:
|
|||
|
||||
if (!renderingContext->isRTT && !config::EmulateFramebuffer)
|
||||
{
|
||||
if (SCALER_CTL.vscalefactor > 0x400)
|
||||
scale_y *= std::round(SCALER_CTL.vscalefactor / 1024.f);
|
||||
if (SCALER_CTL.hscale)
|
||||
if (renderingContext->scaler_ctl.vscalefactor > 0x400)
|
||||
scale_y *= std::round(renderingContext->scaler_ctl.vscalefactor / 1024.f);
|
||||
if (renderingContext->scaler_ctl.hscale)
|
||||
scale_x *= 2.f;
|
||||
}
|
||||
else if (config::EmulateFramebuffer)
|
||||
{
|
||||
if (SCALER_CTL.hscale)
|
||||
if (renderingContext->scaler_ctl.hscale)
|
||||
scale_x *= 2.f;
|
||||
if (SCALER_CTL.vscalefactor > 0x401 || SCALER_CTL.vscalefactor < 0x400)
|
||||
scale_y *= SCALER_CTL.vscalefactor / 1024.f;
|
||||
if (renderingContext->scaler_ctl.vscalefactor > 0x401 || renderingContext->scaler_ctl.vscalefactor < 0x400)
|
||||
scale_y *= renderingContext->scaler_ctl.vscalefactor / 1024.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,9 +241,9 @@ private:
|
|||
float sidebarWidth = 0;
|
||||
};
|
||||
|
||||
inline static void getScaledFramebufferSize(int& width, int& height)
|
||||
inline static void getScaledFramebufferSize(const rend_context& rendCtx, int& width, int& height)
|
||||
{
|
||||
getPvrFramebufferSize(width, height);
|
||||
getPvrFramebufferSize(rendCtx, width, height);
|
||||
if (!config::EmulateFramebuffer)
|
||||
{
|
||||
float upscaling = config::RenderResolution / 480.f;
|
||||
|
@ -264,25 +264,25 @@ inline static void getScaledFramebufferSize(int& width, int& height)
|
|||
}
|
||||
}
|
||||
|
||||
inline static float getOutputFramebufferAspectRatio()
|
||||
inline static float getOutputFramebufferAspectRatio(const rend_context& rendCtx)
|
||||
{
|
||||
int w,h;
|
||||
getPvrFramebufferSize(w, h);
|
||||
getPvrFramebufferSize(rendCtx, w, h);
|
||||
|
||||
float width = w;
|
||||
float height = h;
|
||||
width *= 1 + VO_CONTROL.pixel_double;
|
||||
width /= 1 + SCALER_CTL.hscale;
|
||||
width /= 1 + rendCtx.scaler_ctl.hscale;
|
||||
height *= 1 + (FB_R_CTRL.vclk_div == 0 && SPG_CONTROL.interlace == 0);
|
||||
height *= 1 + (FB_R_CTRL.fb_line_double);
|
||||
if (SCALER_CTL.vscalefactor != 0
|
||||
&& (SCALER_CTL.vscalefactor > 1025 || SCALER_CTL.vscalefactor < 1024)
|
||||
if (rendCtx.scaler_ctl.vscalefactor != 0
|
||||
&& (rendCtx.scaler_ctl.vscalefactor > 1025 || rendCtx.scaler_ctl.vscalefactor < 1024)
|
||||
&& SPG_CONTROL.interlace == 0)
|
||||
{
|
||||
if (config::EmulateFramebuffer)
|
||||
height *= 1024.f / SCALER_CTL.vscalefactor;
|
||||
else if (SCALER_CTL.vscalefactor > 1025)
|
||||
height *= std::round(1024.f / SCALER_CTL.vscalefactor);
|
||||
height *= 1024.f / rendCtx.scaler_ctl.vscalefactor;
|
||||
else if (rendCtx.scaler_ctl.vscalefactor > 1025)
|
||||
height *= std::round(1024.f / rendCtx.scaler_ctl.vscalefactor);
|
||||
|
||||
}
|
||||
|
||||
|
@ -304,10 +304,10 @@ inline static float getOutputFramebufferAspectRatio()
|
|||
return renderAR * config::ScreenStretching / 100.f;
|
||||
}
|
||||
|
||||
inline static float getDCFramebufferAspectRatio()
|
||||
inline static void getDCFramebufferReadSize(int& width, int& height)
|
||||
{
|
||||
int width = FB_R_SIZE.fb_x_size + 1; // in 32-bit words
|
||||
int height = FB_R_SIZE.fb_y_size + 1;
|
||||
width = FB_R_SIZE.fb_x_size + 1; // in 32-bit words
|
||||
height = FB_R_SIZE.fb_y_size + 1;
|
||||
|
||||
switch (FB_R_CTRL.fb_depth)
|
||||
{
|
||||
|
@ -322,6 +322,14 @@ inline static float getDCFramebufferAspectRatio()
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline static float getDCFramebufferAspectRatio()
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
getDCFramebufferReadSize(width, height);
|
||||
|
||||
width *= 1 + VO_CONTROL.pixel_double;
|
||||
height *= 1 + (FB_R_CTRL.vclk_div == 0 && SPG_CONTROL.interlace == 0);
|
||||
height *= 1 + (FB_R_CTRL.fb_line_double);
|
||||
|
|
|
@ -744,6 +744,7 @@ void ScreenDrawer::EndRenderPass()
|
|||
{
|
||||
currentCommandBuffer.end();
|
||||
commandPool->EndFrame();
|
||||
aspectRatio = getOutputFramebufferAspectRatio(_pvrrc->rend);
|
||||
}
|
||||
currentCommandBuffer = nullptr;
|
||||
Drawer::EndRenderPass();
|
||||
|
|
|
@ -287,7 +287,7 @@ public:
|
|||
return false;
|
||||
frameRendered = false;
|
||||
GetContext()->PresentFrame(colorAttachments[GetCurrentImage()]->GetImage(),
|
||||
colorAttachments[GetCurrentImage()]->GetImageView(), viewport);
|
||||
colorAttachments[GetCurrentImage()]->GetImageView(), viewport, aspectRatio);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -309,6 +309,7 @@ private:
|
|||
std::vector<bool> transitionNeeded;
|
||||
std::vector<bool> clearNeeded;
|
||||
bool frameRendered = false;
|
||||
float aspectRatio = 0.f;
|
||||
};
|
||||
|
||||
class TextureDrawer : public Drawer
|
||||
|
|
|
@ -167,7 +167,7 @@ public:
|
|||
OITDrawer::Init(samplerManager, screenPipelineManager.get(), oitBuffers);
|
||||
|
||||
MakeFramebuffers(viewport);
|
||||
GetContext()->PresentFrame(vk::Image(), vk::ImageView(), viewport);
|
||||
GetContext()->PresentFrame(vk::Image(), vk::ImageView(), viewport, 0);
|
||||
}
|
||||
void Term()
|
||||
{
|
||||
|
@ -190,6 +190,7 @@ public:
|
|||
{
|
||||
currentCommandBuffer.end();
|
||||
commandPool->EndFrame();
|
||||
aspectRatio = getOutputFramebufferAspectRatio(_pvrrc->rend);
|
||||
}
|
||||
currentCommandBuffer = nullptr;
|
||||
OITDrawer::EndFrame();
|
||||
|
@ -202,7 +203,7 @@ public:
|
|||
return false;
|
||||
frameRendered = false;
|
||||
GetContext()->PresentFrame(finalColorAttachments[GetCurrentImage()]->GetImage(),
|
||||
finalColorAttachments[GetCurrentImage()]->GetImageView(), viewport.extent);
|
||||
finalColorAttachments[GetCurrentImage()]->GetImageView(), viewport.extent, aspectRatio);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -220,6 +221,7 @@ private:
|
|||
std::unique_ptr<OITPipelineManager> screenPipelineManager;
|
||||
std::vector<bool> transitionNeeded;
|
||||
bool frameRendered = false;
|
||||
float aspectRatio = 0.f;
|
||||
};
|
||||
|
||||
class OITTextureDrawer : public OITDrawer
|
||||
|
|
|
@ -290,7 +290,7 @@ bool VulkanContext::init(retro_hw_render_interface_vulkan *retro_render_if)
|
|||
return true;
|
||||
}
|
||||
|
||||
void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent)
|
||||
void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio)
|
||||
{
|
||||
retro_image.image_view = (VkImageView)imageView;
|
||||
retro_image.create_info.image = (VkImage)image;
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
void term() override;
|
||||
|
||||
u32 GetGraphicsQueueFamilyIndex() const { return retro_render_if->queue_index; }
|
||||
void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent);
|
||||
void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio);
|
||||
|
||||
vk::PhysicalDevice GetPhysicalDevice() const { return physicalDevice; }
|
||||
vk::Device GetDevice() const { return device; }
|
||||
|
|
|
@ -823,7 +823,7 @@ void VulkanContext::Present() noexcept
|
|||
if (lastFrameView && IsValid() && !gui_is_open())
|
||||
for (int i = 1; i < swapInterval; i++)
|
||||
{
|
||||
PresentFrame(vk::Image(), lastFrameView, lastFrameExtent);
|
||||
PresentFrame(vk::Image(), lastFrameView, lastFrameExtent, lastFrameAR);
|
||||
presentQueue.presentKHR(vk::PresentInfoKHR(1, &(*renderCompleteSemaphores[currentSemaphore]), 1, &(*swapChain), ¤tImage));
|
||||
currentSemaphore = (currentSemaphore + 1) % imageViews.size();
|
||||
}
|
||||
|
@ -847,7 +847,7 @@ void VulkanContext::Present() noexcept
|
|||
}
|
||||
}
|
||||
|
||||
void VulkanContext::DrawFrame(vk::ImageView imageView, const vk::Extent2D& extent)
|
||||
void VulkanContext::DrawFrame(vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio)
|
||||
{
|
||||
QuadVertex vtx[] = {
|
||||
{ { -1, -1, 0 }, { 0, 0 } },
|
||||
|
@ -862,14 +862,13 @@ void VulkanContext::DrawFrame(vk::ImageView imageView, const vk::Extent2D& exten
|
|||
else
|
||||
quadPipeline->BindPipeline(commandBuffer);
|
||||
|
||||
float renderAR = getOutputFramebufferAspectRatio();
|
||||
float screenAR = (float)width / height;
|
||||
float dx = 0;
|
||||
float dy = 0;
|
||||
if (renderAR > screenAR)
|
||||
dy = height * (1 - screenAR / renderAR) / 2;
|
||||
if (aspectRatio > screenAR)
|
||||
dy = height * (1 - screenAR / aspectRatio) / 2;
|
||||
else
|
||||
dx = width * (1 - renderAR / screenAR) / 2;
|
||||
dx = width * (1 - aspectRatio / screenAR) / 2;
|
||||
|
||||
vk::Viewport viewport(dx, dy, width - dx * 2, height - dy * 2);
|
||||
commandBuffer.setViewport(0, 1, &viewport);
|
||||
|
@ -928,10 +927,11 @@ vk::CommandBuffer VulkanContext::PrepareOverlay(bool vmu, bool crosshair)
|
|||
|
||||
extern Renderer *renderer;
|
||||
|
||||
void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent) noexcept
|
||||
void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio) noexcept
|
||||
{
|
||||
lastFrameView = imageView;
|
||||
lastFrameExtent = extent;
|
||||
lastFrameAR = aspectRatio;
|
||||
|
||||
if (imageView && IsValid())
|
||||
{
|
||||
|
@ -942,7 +942,7 @@ void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const
|
|||
BeginRenderPass();
|
||||
|
||||
if (lastFrameView) // Might have been nullified if swap chain recreated
|
||||
DrawFrame(imageView, extent);
|
||||
DrawFrame(imageView, extent, aspectRatio);
|
||||
|
||||
DrawOverlay(settings.display.uiScale, config::FloatVMUs, true);
|
||||
renderer->DrawOSD(false);
|
||||
|
@ -955,7 +955,7 @@ void VulkanContext::PresentFrame(vk::Image image, vk::ImageView imageView, const
|
|||
void VulkanContext::PresentLastFrame()
|
||||
{
|
||||
if (lastFrameView && IsValid())
|
||||
DrawFrame(lastFrameView, lastFrameExtent);
|
||||
DrawFrame(lastFrameView, lastFrameExtent, lastFrameAR);
|
||||
}
|
||||
|
||||
void VulkanContext::term()
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
void BeginRenderPass();
|
||||
void EndFrame(vk::CommandBuffer cmdBuffer = vk::CommandBuffer());
|
||||
void Present() noexcept;
|
||||
void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent) noexcept;
|
||||
void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio) noexcept;
|
||||
void PresentLastFrame();
|
||||
|
||||
vk::PhysicalDevice GetPhysicalDevice() const { return physicalDevice; }
|
||||
|
@ -136,7 +136,7 @@ private:
|
|||
bool InitInstance(const char** extensions, uint32_t extensions_count);
|
||||
void InitImgui();
|
||||
void DoSwapAutomation();
|
||||
void DrawFrame(vk::ImageView imageView, const vk::Extent2D& extent);
|
||||
void DrawFrame(vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio);
|
||||
vk::SurfaceKHR GetSurface() const { return *surface; }
|
||||
|
||||
bool HasSurfaceDimensionChanged() const;
|
||||
|
@ -206,6 +206,7 @@ private:
|
|||
|
||||
vk::ImageView lastFrameView;
|
||||
vk::Extent2D lastFrameExtent;
|
||||
float lastFrameAR = 0.f;
|
||||
|
||||
std::unique_ptr<VulkanOverlay> overlay;
|
||||
// only used to delay the destruction of overlay textures
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "pipeline.h"
|
||||
#include "rend/osd.h"
|
||||
#include "overlay.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
#ifndef LIBRETRO
|
||||
#include "rend/gui.h"
|
||||
#endif
|
||||
|
@ -77,7 +78,7 @@ public:
|
|||
void Term() override
|
||||
{
|
||||
GetContext()->WaitIdle();
|
||||
GetContext()->PresentFrame(nullptr, nullptr, vk::Extent2D());
|
||||
GetContext()->PresentFrame(nullptr, nullptr, vk::Extent2D(), 0);
|
||||
#ifdef LIBRETRO
|
||||
overlay->Term();
|
||||
overlay.reset();
|
||||
|
@ -304,7 +305,8 @@ protected:
|
|||
Texture *fbTexture = framebufferTextures[GetContext()->GetCurrentImageIndex()].get();
|
||||
if (fbTexture == nullptr)
|
||||
return false;
|
||||
GetContext()->PresentFrame(fbTexture->GetImage(), fbTexture->GetImageView(), fbTexture->getSize());
|
||||
GetContext()->PresentFrame(fbTexture->GetImage(), fbTexture->GetImageView(), fbTexture->getSize(),
|
||||
getDCFramebufferAspectRatio());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,7 @@ static int framebufferWidth;
|
|||
static int framebufferHeight;
|
||||
static int maxFramebufferWidth;
|
||||
static int maxFramebufferHeight;
|
||||
static float framebufferAspectRatio = 4.f / 3.f;
|
||||
|
||||
float libretro_expected_audio_samples_per_run;
|
||||
unsigned libretro_vsync_swap_interval = 1;
|
||||
|
@ -600,7 +601,7 @@ static bool set_variable_visibility(void)
|
|||
|
||||
static void setGameGeometry(retro_game_geometry& geometry)
|
||||
{
|
||||
geometry.aspect_ratio = getOutputFramebufferAspectRatio();
|
||||
geometry.aspect_ratio = framebufferAspectRatio;
|
||||
if (rotate_screen)
|
||||
geometry.aspect_ratio = 1 / geometry.aspect_ratio;
|
||||
geometry.max_width = std::max(framebufferHeight * 16 / 9, framebufferWidth);
|
||||
|
@ -622,12 +623,13 @@ void setAVInfo(retro_system_av_info& avinfo)
|
|||
libretro_expected_audio_samples_per_run = sample_rate / fps;
|
||||
}
|
||||
|
||||
void retro_resize_renderer(int w, int h)
|
||||
void retro_resize_renderer(int w, int h, float aspectRatio)
|
||||
{
|
||||
if (w == framebufferWidth && h == framebufferHeight)
|
||||
return;
|
||||
framebufferWidth = w;
|
||||
framebufferHeight = h;
|
||||
framebufferAspectRatio = aspectRatio;
|
||||
bool avinfoNeeded = framebufferHeight > maxFramebufferHeight || framebufferWidth > maxFramebufferWidth;
|
||||
maxFramebufferHeight = std::max(maxFramebufferHeight, framebufferHeight);
|
||||
maxFramebufferWidth = std::max(maxFramebufferWidth, framebufferWidth);
|
||||
|
|
Loading…
Reference in New Issue