Merge branch 'viewportCorrection'
This commit is contained in:
commit
498d491942
|
@ -477,30 +477,9 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Viewport correction:
|
|
||||||
// Say you want a viewport at (ix, iy) with size (iw, ih),
|
|
||||||
// but your viewport must be clamped at (ax, ay) with size (aw, ah).
|
|
||||||
// Just multiply the projection matrix with the following to get the same
|
|
||||||
// effect:
|
|
||||||
// [ (iw/aw) 0 0 ((iw - 2*(ax-ix)) / aw - 1) ]
|
|
||||||
// [ 0 (ih/ah) 0 ((-ih + 2*(ay-iy)) / ah + 1) ]
|
|
||||||
// [ 0 0 1 0 ]
|
|
||||||
// [ 0 0 0 1 ]
|
|
||||||
static void ViewportCorrectionMatrix(Matrix44& result,
|
|
||||||
float ix, float iy, float iw, float ih, // Intended viewport (x, y, width, height)
|
|
||||||
float ax, float ay, float aw, float ah) // Actual viewport (x, y, width, height)
|
|
||||||
{
|
|
||||||
Matrix44::LoadIdentity(result);
|
|
||||||
if (aw == 0.f || ah == 0.f)
|
|
||||||
return;
|
|
||||||
result.data[4*0+0] = iw / aw;
|
|
||||||
result.data[4*0+3] = (iw - 2.f * (ax - ix)) / aw - 1.f;
|
|
||||||
result.data[4*1+1] = ih / ah;
|
|
||||||
result.data[4*1+3] = (-ih + 2.f * (ay - iy)) / ah + 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called from VertexShaderManager
|
// Called from VertexShaderManager
|
||||||
void Renderer::UpdateViewport(Matrix44& vpCorrection)
|
void Renderer::UpdateViewport()
|
||||||
{
|
{
|
||||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||||
// [0] = width/2
|
// [0] = width/2
|
||||||
|
@ -513,34 +492,26 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection)
|
||||||
int scissorXOff = bpmem.scissorOffset.x * 2;
|
int scissorXOff = bpmem.scissorOffset.x * 2;
|
||||||
int scissorYOff = bpmem.scissorOffset.y * 2;
|
int scissorYOff = bpmem.scissorOffset.y * 2;
|
||||||
|
|
||||||
float intendedX = Renderer::EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff);
|
float X = Renderer::EFBToScaledXf(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff);
|
||||||
float intendedY = Renderer::EFBToScaledYf(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff);
|
float Y = Renderer::EFBToScaledYf(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff);
|
||||||
float intendedWd = Renderer::EFBToScaledXf(2.0f * xfregs.viewport.wd);
|
float Wd = Renderer::EFBToScaledXf(2.0f * xfregs.viewport.wd);
|
||||||
float intendedHt = Renderer::EFBToScaledYf(-2.0f * xfregs.viewport.ht);
|
float Ht = Renderer::EFBToScaledYf(-2.0f * xfregs.viewport.ht);
|
||||||
if (intendedWd < 0.f)
|
if (Wd < 0.0f)
|
||||||
{
|
{
|
||||||
intendedX += intendedWd;
|
X += Wd;
|
||||||
intendedWd = -intendedWd;
|
Wd = -Wd;
|
||||||
}
|
}
|
||||||
if (intendedHt < 0.f)
|
if (Ht < 0.0f)
|
||||||
{
|
{
|
||||||
intendedY += intendedHt;
|
Y += Ht;
|
||||||
intendedHt = -intendedHt;
|
Ht = -Ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In D3D, the viewport rectangle must fit within the render target.
|
// In D3D, the viewport rectangle must fit within the render target.
|
||||||
float X = (intendedX >= 0.f) ? intendedX : 0.f;
|
X = (X >= 0.f) ? X : 0.f;
|
||||||
float Y = (intendedY >= 0.f) ? intendedY : 0.f;
|
Y = (Y >= 0.f) ? Y : 0.f;
|
||||||
float Wd = (X + intendedWd <= GetTargetWidth()) ? intendedWd : (GetTargetWidth() - X);
|
Wd = (X + Wd <= GetTargetWidth()) ? Wd : (GetTargetWidth() - X);
|
||||||
float Ht = (Y + intendedHt <= GetTargetHeight()) ? intendedHt : (GetTargetHeight() - Y);
|
Ht = (Y + Ht <= GetTargetHeight()) ? Ht : (GetTargetHeight() - Y);
|
||||||
|
|
||||||
// If GX viewport is off the render target, we must clamp our viewport
|
|
||||||
// within the bounds. Use the correction matrix to compensate.
|
|
||||||
ViewportCorrectionMatrix(vpCorrection,
|
|
||||||
intendedX, intendedY,
|
|
||||||
intendedWd, intendedHt,
|
|
||||||
X, Y,
|
|
||||||
Wd, Ht);
|
|
||||||
|
|
||||||
// Some games set invalid values for z-min and z-max so fix them to the max and min allowed and let the shaders do this work
|
// Some games set invalid values for z-min and z-max so fix them to the max and min allowed and let the shaders do this work
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y,
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y,
|
||||||
|
@ -1055,10 +1026,10 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& r
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin next frame
|
// begin next frame
|
||||||
Renderer::RestoreAPIState();
|
RestoreAPIState();
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
VertexShaderManager::SetViewportChanged();
|
UpdateViewport();
|
||||||
|
|
||||||
Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
|
Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
|
||||||
XFBWrited = false;
|
XFBWrited = false;
|
||||||
|
@ -1078,7 +1049,7 @@ void Renderer::RestoreAPIState()
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
D3D::stateman->PopDepthState();
|
D3D::stateman->PopDepthState();
|
||||||
D3D::stateman->PopRasterizerState();
|
D3D::stateman->PopRasterizerState();
|
||||||
VertexShaderManager::SetViewportChanged();
|
UpdateViewport();
|
||||||
BPFunctions::SetScissor();
|
BPFunctions::SetScissor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
|
|
||||||
void ReinterpretPixelData(unsigned int convtype);
|
void ReinterpretPixelData(unsigned int convtype);
|
||||||
|
|
||||||
void UpdateViewport(Matrix44& vpCorrection);
|
void UpdateViewport();
|
||||||
|
|
||||||
bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc);
|
bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc);
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ void InitBackendInfo()
|
||||||
g_Config.backend_info.bSupportsFormatReinterpretation = true;
|
g_Config.backend_info.bSupportsFormatReinterpretation = true;
|
||||||
g_Config.backend_info.bSupportsPixelLighting = true;
|
g_Config.backend_info.bSupportsPixelLighting = true;
|
||||||
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
||||||
|
g_Config.backend_info.bSupportsOversizedViewports = false;
|
||||||
|
|
||||||
IDXGIFactory* factory;
|
IDXGIFactory* factory;
|
||||||
IDXGIAdapter* ad;
|
IDXGIAdapter* ad;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "ConfigManager.h"
|
#include "ConfigManager.h"
|
||||||
|
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "VertexShaderManager.h"
|
|
||||||
|
|
||||||
#include "GLUtil.h"
|
#include "GLUtil.h"
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include "RasterFont.h"
|
#include "RasterFont.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "DLCache.h"
|
#include "DLCache.h"
|
||||||
#include "PixelShaderManager.h"
|
|
||||||
#include "ProgramShaderCache.h"
|
#include "ProgramShaderCache.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "VertexLoaderManager.h"
|
#include "VertexLoaderManager.h"
|
||||||
|
@ -1093,7 +1092,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from VertexShaderManager
|
// Called from VertexShaderManager
|
||||||
void Renderer::UpdateViewport(Matrix44& vpCorrection)
|
void Renderer::UpdateViewport()
|
||||||
{
|
{
|
||||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||||
// [0] = width/2
|
// [0] = width/2
|
||||||
|
@ -1124,9 +1123,6 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection)
|
||||||
Height *= -1;
|
Height *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenGL does not require any viewport correct
|
|
||||||
Matrix44::LoadIdentity(vpCorrection);
|
|
||||||
|
|
||||||
// Update the view port
|
// Update the view port
|
||||||
if(g_ogl_config.bSupportViewportFloat)
|
if(g_ogl_config.bSupportViewportFloat)
|
||||||
{
|
{
|
||||||
|
@ -1664,7 +1660,7 @@ void Renderer::RestoreAPIState()
|
||||||
SetDepthMode();
|
SetDepthMode();
|
||||||
SetBlendMode(true);
|
SetBlendMode(true);
|
||||||
SetLogicOpMode();
|
SetLogicOpMode();
|
||||||
VertexShaderManager::SetViewportChanged();
|
UpdateViewport();
|
||||||
|
|
||||||
#ifndef USE_GLES3
|
#ifndef USE_GLES3
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL);
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
|
|
||||||
void ReinterpretPixelData(unsigned int convtype);
|
void ReinterpretPixelData(unsigned int convtype);
|
||||||
|
|
||||||
void UpdateViewport(Matrix44& vpCorrection);
|
void UpdateViewport();
|
||||||
|
|
||||||
bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc);
|
bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc);
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,12 @@
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "ProgramShaderCache.h"
|
#include "ProgramShaderCache.h"
|
||||||
#include "PixelShaderManager.h"
|
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "TextureConverter.h"
|
#include "TextureConverter.h"
|
||||||
#include "TextureDecoder.h"
|
#include "TextureDecoder.h"
|
||||||
#include "VertexShaderManager.h"
|
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
|
@ -391,7 +389,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "TextureConversionShader.h"
|
#include "TextureConversionShader.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "ProgramShaderCache.h"
|
#include "ProgramShaderCache.h"
|
||||||
#include "VertexShaderManager.h"
|
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
@ -350,7 +349,6 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* des
|
||||||
|
|
||||||
EncodeToRamUsingShader(srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
EncodeToRamUsingShader(srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
|
||||||
TextureCache::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
@ -426,8 +424,6 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
VertexShaderManager::SetViewportChanged();
|
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
|
|
|
@ -146,6 +146,7 @@ void InitBackendInfo()
|
||||||
g_Config.backend_info.bSupportsFormatReinterpretation = true;
|
g_Config.backend_info.bSupportsFormatReinterpretation = true;
|
||||||
g_Config.backend_info.bSupportsPixelLighting = true;
|
g_Config.backend_info.bSupportsPixelLighting = true;
|
||||||
//g_Config.backend_info.bSupportsEarlyZ = true; // is gpu dependent and must be set in renderer
|
//g_Config.backend_info.bSupportsEarlyZ = true; // is gpu dependent and must be set in renderer
|
||||||
|
g_Config.backend_info.bSupportsOversizedViewports = true;
|
||||||
|
|
||||||
// aamodes
|
// aamodes
|
||||||
const char* caamodes[] = {_trans("None"), "2x", "4x", "8x", "8x CSAA", "8xQ CSAA", "16x CSAA", "16xQ CSAA", "4x SSAA"};
|
const char* caamodes[] = {_trans("None"), "2x", "4x", "8x", "8x CSAA", "8xQ CSAA", "16x CSAA", "16xQ CSAA", "4x SSAA"};
|
||||||
|
|
|
@ -49,8 +49,6 @@ void SetScissor()
|
||||||
|
|
||||||
TargetRectangle trc = g_renderer->ConvertEFBRectangle(rc);
|
TargetRectangle trc = g_renderer->ConvertEFBRectangle(rc);
|
||||||
g_renderer->SetScissorRect(trc);
|
g_renderer->SetScissorRect(trc);
|
||||||
|
|
||||||
UpdateViewportWithCorrection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLineWidth()
|
void SetLineWidth()
|
||||||
|
|
|
@ -185,6 +185,7 @@ void BPWritten(const BPCmd& bp)
|
||||||
case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
|
case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
|
||||||
case BPMEM_SCISSOROFFSET: // Scissor Offset
|
case BPMEM_SCISSOROFFSET: // Scissor Offset
|
||||||
SetScissor();
|
SetScissor();
|
||||||
|
VertexShaderManager::SetViewportChanged();
|
||||||
break;
|
break;
|
||||||
case BPMEM_LINEPTWIDTH: // Line Width
|
case BPMEM_LINEPTWIDTH: // Line Width
|
||||||
SetLineWidth();
|
SetLineWidth();
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
#include "FifoPlayer/FifoRecorder.h"
|
#include "FifoPlayer/FifoRecorder.h"
|
||||||
#include "AVIDump.h"
|
#include "AVIDump.h"
|
||||||
#include "VertexShaderManager.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -231,7 +230,6 @@ bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int
|
||||||
{
|
{
|
||||||
s_target_width = newEFBWidth;
|
s_target_width = newEFBWidth;
|
||||||
s_target_height = newEFBHeight;
|
s_target_height = newEFBHeight;
|
||||||
VertexShaderManager::SetViewportChanged();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -520,8 +518,8 @@ void Renderer::RecordVideoMemory()
|
||||||
FifoRecorder::GetInstance().SetVideoMemory(bpMem, cpMem, xfMem, xfRegs, sizeof(XFRegisters) / 4);
|
FifoRecorder::GetInstance().SetVideoMemory(bpMem, cpMem, xfMem, xfRegs, sizeof(XFRegisters) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateViewport(Matrix44& vpCorrection)
|
void UpdateViewport()
|
||||||
{
|
{
|
||||||
if (xfregs.viewport.wd != 0 && xfregs.viewport.ht != 0)
|
if (xfregs.viewport.wd != 0 && xfregs.viewport.ht != 0)
|
||||||
g_renderer->UpdateViewport(vpCorrection);
|
g_renderer->UpdateViewport();
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ public:
|
||||||
// Finish up the current frame, print some stats
|
// Finish up the current frame, print some stats
|
||||||
virtual void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f) = 0;
|
virtual void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f) = 0;
|
||||||
|
|
||||||
virtual void UpdateViewport(Matrix44& vpCorrection) = 0;
|
virtual void UpdateViewport() = 0;
|
||||||
|
|
||||||
virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0;
|
virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0;
|
||||||
|
|
||||||
|
@ -163,6 +163,6 @@ private:
|
||||||
|
|
||||||
extern Renderer *g_renderer;
|
extern Renderer *g_renderer;
|
||||||
|
|
||||||
void UpdateViewport(Matrix44& vpCorrection);
|
void UpdateViewport();
|
||||||
|
|
||||||
#endif // _COMMON_RENDERBASE_H_
|
#endif // _COMMON_RENDERBASE_H_
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include "TextureConversionShader.h"
|
#include "TextureConversionShader.h"
|
||||||
#include "TextureDecoder.h"
|
#include "TextureDecoder.h"
|
||||||
#include "PixelShaderManager.h"
|
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#define I_TRANSFORMMATRICES "ctrmtx"
|
#define I_TRANSFORMMATRICES "ctrmtx"
|
||||||
#define I_NORMALMATRICES "cnmtx"
|
#define I_NORMALMATRICES "cnmtx"
|
||||||
#define I_POSTTRANSFORMMATRICES "cpostmtx"
|
#define I_POSTTRANSFORMMATRICES "cpostmtx"
|
||||||
#define I_DEPTHPARAMS "cDepth" // farZ, zRange, scaled viewport width, scaled viewport height
|
#define I_DEPTHPARAMS "cDepth" // farZ, zRange
|
||||||
|
|
||||||
//TODO: get rid of them, they aren't used at all
|
//TODO: get rid of them, they aren't used at all
|
||||||
#define C_POSNORMALMATRIX 0
|
#define C_POSNORMALMATRIX 0
|
||||||
|
|
|
@ -39,13 +39,6 @@ static float s_fViewRotation[2];
|
||||||
VertexShaderConstants VertexShaderManager::constants;
|
VertexShaderConstants VertexShaderManager::constants;
|
||||||
bool VertexShaderManager::dirty;
|
bool VertexShaderManager::dirty;
|
||||||
|
|
||||||
void UpdateViewport(Matrix44& vpCorrection);
|
|
||||||
|
|
||||||
void UpdateViewportWithCorrection()
|
|
||||||
{
|
|
||||||
UpdateViewport(s_viewportCorrection);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ProjectionHack
|
struct ProjectionHack
|
||||||
{
|
{
|
||||||
float sign;
|
float sign;
|
||||||
|
@ -130,6 +123,58 @@ void UpdateProjectionHack(int iPhackvalue[], std::string sPhackvalue[])
|
||||||
g_ProjHack3 = bProjHack3;
|
g_ProjHack3 = bProjHack3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Viewport correction:
|
||||||
|
// In D3D, the viewport rectangle must fit within the render target.
|
||||||
|
// Say you want a viewport at (ix, iy) with size (iw, ih),
|
||||||
|
// but your viewport must be clamped at (ax, ay) with size (aw, ah).
|
||||||
|
// Just multiply the projection matrix with the following to get the same
|
||||||
|
// effect:
|
||||||
|
// [ (iw/aw) 0 0 ((iw - 2*(ax-ix)) / aw - 1) ]
|
||||||
|
// [ 0 (ih/ah) 0 ((-ih + 2*(ay-iy)) / ah + 1) ]
|
||||||
|
// [ 0 0 1 0 ]
|
||||||
|
// [ 0 0 0 1 ]
|
||||||
|
static void ViewportCorrectionMatrix(Matrix44& result)
|
||||||
|
{
|
||||||
|
int scissorXOff = bpmem.scissorOffset.x * 2;
|
||||||
|
int scissorYOff = bpmem.scissorOffset.y * 2;
|
||||||
|
|
||||||
|
// TODO: ceil, floor or just cast to int?
|
||||||
|
// TODO: Directly use the floats instead of rounding them?
|
||||||
|
float intendedX = xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff;
|
||||||
|
float intendedY = xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff;
|
||||||
|
float intendedWd = 2.0f * xfregs.viewport.wd;
|
||||||
|
float intendedHt = -2.0f * xfregs.viewport.ht;
|
||||||
|
|
||||||
|
if (intendedWd < 0.f)
|
||||||
|
{
|
||||||
|
intendedX += intendedWd;
|
||||||
|
intendedWd = -intendedWd;
|
||||||
|
}
|
||||||
|
if (intendedHt < 0.f)
|
||||||
|
{
|
||||||
|
intendedY += intendedHt;
|
||||||
|
intendedHt = -intendedHt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fit to EFB size
|
||||||
|
float X = (intendedX >= 0.f) ? intendedX : 0.f;
|
||||||
|
float Y = (intendedY >= 0.f) ? intendedY : 0.f;
|
||||||
|
float Wd = (X + intendedWd <= EFB_WIDTH) ? intendedWd : (EFB_WIDTH - X);
|
||||||
|
float Ht = (Y + intendedHt <= EFB_HEIGHT) ? intendedHt : (EFB_HEIGHT - Y);
|
||||||
|
|
||||||
|
Matrix44::LoadIdentity(result);
|
||||||
|
if (Wd == 0 || Ht == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
result.data[4*0+0] = intendedWd / Wd;
|
||||||
|
result.data[4*0+3] = (intendedWd - 2.f * (X - intendedX)) / Wd - 1.f;
|
||||||
|
result.data[4*1+1] = intendedHt / Ht;
|
||||||
|
result.data[4*1+3] = (-intendedHt + 2.f * (Y - intendedY)) / Ht + 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateViewport();
|
||||||
|
|
||||||
void VertexShaderManager::Init()
|
void VertexShaderManager::Init()
|
||||||
{
|
{
|
||||||
Dirty();
|
Dirty();
|
||||||
|
@ -326,13 +371,17 @@ void VertexShaderManager::SetConstants()
|
||||||
bViewportChanged = false;
|
bViewportChanged = false;
|
||||||
constants.depthparams[0] = xfregs.viewport.farZ / 16777216.0f;
|
constants.depthparams[0] = xfregs.viewport.farZ / 16777216.0f;
|
||||||
constants.depthparams[1] = xfregs.viewport.zRange / 16777216.0f;
|
constants.depthparams[1] = xfregs.viewport.zRange / 16777216.0f;
|
||||||
constants.depthparams[2] = -1.f / g_renderer->EFBToScaledX(ceilf(2.0f * xfregs.viewport.wd));
|
|
||||||
constants.depthparams[3] = 1.f / g_renderer->EFBToScaledY(ceilf(-2.0f * xfregs.viewport.ht));
|
|
||||||
dirty = true;
|
dirty = true;
|
||||||
// This is so implementation-dependent that we can't have it here.
|
// This is so implementation-dependent that we can't have it here.
|
||||||
UpdateViewport(s_viewportCorrection);
|
UpdateViewport();
|
||||||
|
|
||||||
|
// Update projection if the viewport isn't 1:1 useable
|
||||||
|
if(!g_ActiveConfig.backend_info.bSupportsOversizedViewports)
|
||||||
|
{
|
||||||
|
ViewportCorrectionMatrix(s_viewportCorrection);
|
||||||
bProjectionChanged = true;
|
bProjectionChanged = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bProjectionChanged)
|
if (bProjectionChanged)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,8 +12,6 @@ class PointerWrap;
|
||||||
|
|
||||||
void UpdateProjectionHack(int iParams[], std::string sParams[]);
|
void UpdateProjectionHack(int iParams[], std::string sParams[]);
|
||||||
|
|
||||||
void UpdateViewportWithCorrection();
|
|
||||||
|
|
||||||
// The non-API dependent parts.
|
// The non-API dependent parts.
|
||||||
class VertexShaderManager
|
class VertexShaderManager
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,6 +153,7 @@ struct VideoConfig
|
||||||
bool bSupportsPixelLighting;
|
bool bSupportsPixelLighting;
|
||||||
bool bSupportsPrimitiveRestart;
|
bool bSupportsPrimitiveRestart;
|
||||||
bool bSupportsSeparateAlphaFunction;
|
bool bSupportsSeparateAlphaFunction;
|
||||||
|
bool bSupportsOversizedViewports;
|
||||||
bool bSupportsGLSLUBO; // needed by PixelShaderGen, so must stay in VideoCommon
|
bool bSupportsGLSLUBO; // needed by PixelShaderGen, so must stay in VideoCommon
|
||||||
bool bSupportsEarlyZ; // needed by PixelShaderGen, so must stay in VideoCommon
|
bool bSupportsEarlyZ; // needed by PixelShaderGen, so must stay in VideoCommon
|
||||||
} backend_info;
|
} backend_info;
|
||||||
|
|
Loading…
Reference in New Issue