Make zfreeze use screenspace coordinates independant of IR.

OpenGL requires the y coordinates to be flipped.

Also refactored PixelGen code to remove duplicate code.
This commit is contained in:
Scott Mansell 2015-01-03 06:06:56 +13:00
parent 418296961c
commit 88c7afd315
8 changed files with 57 additions and 17 deletions

View File

@ -33,6 +33,7 @@
#include "VideoCommon/ImageWrite.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/PixelEngine.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/Statistics.h"
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/VideoConfig.h"
@ -231,6 +232,7 @@ Renderer::Renderer(void *&window_handle)
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
PixelShaderManager::SetEfbScaleChanged();
SetupDeviceObjects();
@ -946,6 +948,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
PixelShaderManager::SetEfbScaleChanged();
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr);
delete g_framebuffer_manager;

View File

@ -43,6 +43,7 @@
#include "VideoCommon/ImageWrite.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/PixelEngine.h"
#include "VideoCommon/PixelShaderManager.h"
#include "VideoCommon/Statistics.h"
#include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexShaderGen.h"
@ -618,6 +619,8 @@ Renderer::Renderer()
s_last_efb_scale = g_ActiveConfig.iEFBScale;
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
PixelShaderManager::SetEfbScaleChanged();
// Because of the fixed framebuffer size we need to disable the resolution
// options while running
g_Config.bRunning = true;
@ -1681,6 +1684,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
delete g_framebuffer_manager;
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
s_MSAASamples);
PixelShaderManager::SetEfbScaleChanged();
}
}

View File

@ -24,6 +24,7 @@ struct PixelShaderConstants
int4 fogi;
float4 fogf[2];
float4 zslope;
float4 efbscale;
};
struct VertexShaderConstants

View File

@ -144,6 +144,7 @@ template<class T> static inline void WriteTevRegular(T& out, const char* compone
template<class T> static inline void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
template<class T> static inline void WriteAlphaTest(T& out, pixel_shader_uid_data* uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth);
template<class T> static inline void WriteFog(T& out, pixel_shader_uid_data* uid_data);
template<class T> static inline void WritePerPixelDepth(T& out, pixel_shader_uid_data* uid_data, API_TYPE ApiType);
template<class T>
static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components)
@ -229,6 +230,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
"\tint4 " I_FOGI";\n"
"\tfloat4 " I_FOGF"[2];\n"
"\tfloat4 " I_ZSLOPE";\n"
"\tfloat4 " I_EFBSCALE";\n"
"};\n");
if (g_ActiveConfig.bEnablePixelLighting)
@ -544,14 +546,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
// Note: z-textures are not written to depth buffer if early depth test is used
if (per_pixel_depth && bpmem.UseEarlyDepthTest())
{
if (bpmem.genMode.zfreeze)
{
out.Write("\tdepth = float(" I_ZSLOPE".z + " I_ZSLOPE".x * rawpos.x + " I_ZSLOPE".y * rawpos.y) / float(0xffffff);\n");
}
else
{
out.Write("\tdepth = float(zCoord) / float(0xFFFFFF);\n");
}
WritePerPixelDepth<T>(out, uid_data, ApiType);
}
// Note: depth texture output is only written to depth buffer if late depth test is used
@ -567,14 +562,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
if (per_pixel_depth && bpmem.UseLateDepthTest())
{
if (bpmem.genMode.zfreeze)
{
out.Write("\tdepth = float(" I_ZSLOPE".z + " I_ZSLOPE".x * rawpos.x + " I_ZSLOPE".y * rawpos.y) / float(0xffffff);\n");
}
else
{
out.Write("\tdepth = float(zCoord) / float(0xFFFFFF);\n");
}
WritePerPixelDepth<T>(out, uid_data, ApiType);
}
if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
@ -1115,6 +1103,29 @@ static inline void WriteFog(T& out, pixel_shader_uid_data* uid_data)
out.Write("\tprev.rgb = (prev.rgb * (256 - ifog) + " I_FOGCOLOR".rgb * ifog) >> 8;\n");
}
template<class T>
static inline void WritePerPixelDepth(T& out, pixel_shader_uid_data* uid_data, API_TYPE ApiType)
{
if (bpmem.genMode.zfreeze)
{
out.SetConstantsUsed(C_ZSLOPE, C_ZSLOPE);
out.SetConstantsUsed(C_EFBSCALE, C_EFBSCALE);
out.Write("\tfloat2 screenpos = rawpos.xy * " I_EFBSCALE".xy;\n");
// Opengl has reversed vertical screenspace coordiantes
if(ApiType == API_OPENGL)
out.Write("\tscreenpos.y = %i - screenpos.y - 1;\n", EFB_HEIGHT);
out.Write("\tdepth = float(" I_ZSLOPE".z + " I_ZSLOPE".x * screenpos.x + " I_ZSLOPE".y * screenpos.y) / float(0xffffff);\n");
}
else
{
out.Write("\tdepth = float(zCoord) / float(0xFFFFFF);\n");
}
}
void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components)
{
GeneratePixelShader<PixelShaderUid>(object, dstAlphaMode, ApiType, components);

View File

@ -22,8 +22,9 @@
#define C_FOGI (C_FOGCOLOR + 1) //28
#define C_FOGF (C_FOGI + 2) //29
#define C_ZSLOPE (C_FOGF + 1) //31
#define C_EFBSCALE (C_ZSLOPE + 1) //32
#define C_PENVCONST_END (C_ZSLOPE + 2)
#define C_PENVCONST_END (C_EFBSCALE + 1)
// Different ways to achieve rendering with destination alpha
enum DSTALPHA_MODE

View File

@ -14,6 +14,7 @@
bool PixelShaderManager::s_bFogRangeAdjustChanged;
bool PixelShaderManager::s_bViewPortChanged;
bool PixelShaderManager::s_bEFBScaleChanged;
std::array<int4,4> PixelShaderManager::s_tev_color;
std::array<int4,4> PixelShaderManager::s_tev_konst_color;
@ -48,6 +49,7 @@ void PixelShaderManager::Dirty()
SetDestAlpha();
SetZTextureBias();
SetViewportChanged();
SetEfbScaleChanged();
SetZSlope(0, 0, 1);
SetIndTexScaleChanged(false);
SetIndTexScaleChanged(true);
@ -113,6 +115,13 @@ void PixelShaderManager::SetConstants()
dirty = true;
s_bViewPortChanged = false;
}
if (s_bEFBScaleChanged) {
constants.efbscale[0] = 1.0f / float(Renderer::EFBToScaledXf(1));
constants.efbscale[1] = 1.0f / float(Renderer::EFBToScaledYf(1));
dirty = true;
s_bEFBScaleChanged = false;
}
}
void PixelShaderManager::SetTevColor(int index, int component, s32 value)
@ -169,6 +178,12 @@ void PixelShaderManager::SetViewportChanged()
s_bFogRangeAdjustChanged = true; // TODO: Shouldn't be necessary with an accurate fog range adjust implementation
}
void PixelShaderManager::SetEfbScaleChanged()
{
s_bEFBScaleChanged = true;
s_bViewPortChanged = true;
}
void PixelShaderManager::SetZSlope(float dfdx, float dfdy, float f0)
{
constants.zslope[0] = dfdx;

View File

@ -36,6 +36,7 @@ public:
static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
static void SetZTextureBias();
static void SetViewportChanged();
static void SetEfbScaleChanged();
static void SetZSlope(float dfdx, float dfdy, float f0);
static void SetIndMatrixChanged(int matrixidx);
static void SetTevKSelChanged(int id);
@ -51,6 +52,7 @@ public:
static bool s_bFogRangeAdjustChanged;
static bool s_bViewPortChanged;
static bool s_bEFBScaleChanged;
// These colors aren't available from global BP state,
// hence we keep a copy of them around.

View File

@ -292,6 +292,7 @@ static inline void AssignVSOutputMembers(T& object, const char* a, const char* b
#define I_FOGI "cfogi"
#define I_FOGF "cfogf"
#define I_ZSLOPE "czslope"
#define I_EFBSCALE "cefbscale"
#define I_POSNORMALMATRIX "cpnmtx"
#define I_PROJECTION "cproj"