mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 10:40:01 +01:00
add "real-time texture scaling" option.
This commit is contained in:
1 parent
29de4b5a18
commit
45830d7cdc
18 files changed
+412
-54
No files matched your search
@@ -551,6 +551,7 @@ static ConfigSetting graphicsSettings[] = {
|
||||
ReportedConfigSetting("TexScalingLevel", &g_Config.iTexScalingLevel, 1, true, true),
|
||||
ReportedConfigSetting("TexScalingType", &g_Config.iTexScalingType, 0, true, true),
|
||||
ReportedConfigSetting("TexDeposterize", &g_Config.bTexDeposterize, false, true, true),
|
||||
ReportedConfigSetting("TexRealtime", &g_Config.bRealtimeTexScaling, false, true, true),
|
||||
ConfigSetting("VSyncInterval", &g_Config.bVSync, false, true, true),
|
||||
ReportedConfigSetting("DisableStencilTest", &g_Config.bDisableStencilTest, false, true, true),
|
||||
ReportedConfigSetting("BloomHack", &g_Config.iBloomHack, 0, true, true),
|
||||
|
||||
@@ -193,6 +193,7 @@ public:
|
||||
bool bSaveNewTextures;
|
||||
int iTexScalingLevel; // 1 = off, 2 = 2x, ..., 5 = 5x
|
||||
int iTexScalingType; // 0 = xBRZ, 1 = Hybrid
|
||||
bool bRealtimeTexScaling;
|
||||
bool bTexDeposterize;
|
||||
int iFpsLimit;
|
||||
int iForceMaxEmulatedFPS;
|
||||
|
||||
@@ -83,7 +83,9 @@ enum : uint64_t {
|
||||
DIRTY_BEZIERSPLINE = 1ULL << 32,
|
||||
DIRTY_TEXCLAMP = 1ULL << 33,
|
||||
|
||||
// space for 7 more uniforms.
|
||||
DIRTY_TEXSIZE = 1ULL << 33,
|
||||
|
||||
// space for 6 more uniforms.
|
||||
|
||||
DIRTY_ALL_UNIFORMS = 0x3FFFFFFFFULL,
|
||||
DIRTY_ALL_LIGHTS = DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3,
|
||||
|
||||
@@ -203,6 +203,14 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
ub->spline_type_u = gstate_c.spline_type_u;
|
||||
ub->spline_type_v = gstate_c.spline_type_v;
|
||||
}
|
||||
|
||||
if (dirtyUniforms & DIRTY_TEXSIZE) {
|
||||
ub->texSize[0] = (float)gstate_c.curTextureWidth;
|
||||
ub->texSize[1] = (float)gstate_c.curTextureHeight;
|
||||
ub->texSize[2] = 1.0f / (float)gstate_c.curTextureWidth;
|
||||
ub->texSize[3] = 1.0f / (float)gstate_c.curTextureHeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LightUpdateUniforms(UB_VS_Lights *ub, uint64_t dirtyUniforms) {
|
||||
|
||||
@@ -11,7 +11,7 @@ enum : uint64_t {
|
||||
DIRTY_WORLDMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | DIRTY_ALPHACOLORREF |
|
||||
DIRTY_PROJMATRIX | DIRTY_FOGCOLOR | DIRTY_FOGCOEF | DIRTY_TEXENV | DIRTY_STENCILREPLACEVALUE |
|
||||
DIRTY_ALPHACOLORMASK | DIRTY_SHADERBLEND | DIRTY_UVSCALEOFFSET | DIRTY_TEXCLAMP | DIRTY_DEPTHRANGE | DIRTY_MATAMBIENTALPHA |
|
||||
DIRTY_BEZIERSPLINE,
|
||||
DIRTY_BEZIERSPLINE | DIRTY_TEXSIZE,
|
||||
DIRTY_LIGHT_UNIFORMS =
|
||||
DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3 |
|
||||
DIRTY_MATDIFFUSE | DIRTY_MATSPECULAR | DIRTY_MATEMISSIVE | DIRTY_AMBIENT,
|
||||
@@ -40,6 +40,7 @@ struct UB_VS_FS_Base {
|
||||
float blendFixB[4];
|
||||
float texClamp[4];
|
||||
float texClampOffset[4];
|
||||
float texSize[4];
|
||||
};
|
||||
|
||||
static const char *ub_baseStr =
|
||||
@@ -65,6 +66,7 @@ R"( mat4 proj_mtx;
|
||||
vec3 blendFixB;
|
||||
vec4 texclamp;
|
||||
vec2 texclampoff;
|
||||
vec4 texsize;
|
||||
)";
|
||||
|
||||
// HLSL code is shared so these names are changed to match those in DX9.
|
||||
@@ -91,6 +93,7 @@ R"( float4x4 u_proj;
|
||||
float3 u_blendFixB;
|
||||
float4 u_texclamp;
|
||||
float2 u_texclampoff;
|
||||
float4 u_texSize;
|
||||
)";
|
||||
|
||||
// 512 bytes. Would like to shrink more. Some colors only have 8-bit precision and we expand
|
||||
|
||||
@@ -423,6 +423,7 @@ void TextureCacheCommon::SetTexture(bool force) {
|
||||
//got one!
|
||||
gstate_c.curTextureWidth = w;
|
||||
gstate_c.curTextureHeight = h;
|
||||
gstate_c.Dirty(DIRTY_TEXSIZE);
|
||||
if (rehash) {
|
||||
// Update in case any of these changed.
|
||||
entry->sizeInRAM = (textureBitsPerPixel[format] * bufw * h / 2) / 8;
|
||||
@@ -842,6 +843,7 @@ void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram
|
||||
// We need to force it, since we may have set it on a texture before attaching.
|
||||
gstate_c.curTextureWidth = framebuffer->bufferWidth;
|
||||
gstate_c.curTextureHeight = framebuffer->bufferHeight;
|
||||
gstate_c.Dirty(DIRTY_TEXSIZE);
|
||||
if (gstate_c.bgraTexture) {
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
} else if ((gstate_c.curTextureXOffset == 0) != (fbInfo.xOffset == 0) || (gstate_c.curTextureYOffset == 0) != (fbInfo.yOffset == 0)) {
|
||||
@@ -909,35 +911,39 @@ bool TextureCacheCommon::SetOffsetTexture(u32 offset) {
|
||||
void TextureCacheCommon::NotifyConfigChanged() {
|
||||
int scaleFactor;
|
||||
|
||||
// 0 means automatic texture scaling, up to 5x, based on resolution.
|
||||
if (g_Config.iTexScalingLevel == 0) {
|
||||
scaleFactor = g_Config.iInternalResolution;
|
||||
// Automatic resolution too? Okay.
|
||||
if (scaleFactor == 0) {
|
||||
if (!g_Config.IsPortrait()) {
|
||||
scaleFactor = (PSP_CoreParameter().pixelWidth + 479) / 480;
|
||||
} else {
|
||||
scaleFactor = (PSP_CoreParameter().pixelHeight + 479) / 480;
|
||||
if (g_Config.bRealtimeTexScaling) {
|
||||
scaleFactor = 1;
|
||||
} else {
|
||||
// 0 means automatic texture scaling, up to 5x, based on resolution.
|
||||
if (g_Config.iTexScalingLevel == 0) {
|
||||
scaleFactor = g_Config.iInternalResolution;
|
||||
// Automatic resolution too? Okay.
|
||||
if (scaleFactor == 0) {
|
||||
if (!g_Config.IsPortrait()) {
|
||||
scaleFactor = (PSP_CoreParameter().pixelWidth + 479) / 480;
|
||||
} else {
|
||||
scaleFactor = (PSP_CoreParameter().pixelHeight + 479) / 480;
|
||||
}
|
||||
}
|
||||
|
||||
scaleFactor = std::min(5, scaleFactor);
|
||||
} else {
|
||||
scaleFactor = g_Config.iTexScalingLevel;
|
||||
}
|
||||
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_OES_TEXTURE_NPOT)) {
|
||||
// Reduce the scale factor to a power of two (e.g. 2 or 4) if textures must be a power of two.
|
||||
while ((scaleFactor & (scaleFactor - 1)) != 0) {
|
||||
--scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
scaleFactor = std::min(5, scaleFactor);
|
||||
} else {
|
||||
scaleFactor = g_Config.iTexScalingLevel;
|
||||
}
|
||||
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_OES_TEXTURE_NPOT)) {
|
||||
// Reduce the scale factor to a power of two (e.g. 2 or 4) if textures must be a power of two.
|
||||
while ((scaleFactor & (scaleFactor - 1)) != 0) {
|
||||
--scaleFactor;
|
||||
// Just in case, small display with auto resolution or something.
|
||||
if (scaleFactor <= 0) {
|
||||
scaleFactor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Just in case, small display with auto resolution or something.
|
||||
if (scaleFactor <= 0) {
|
||||
scaleFactor = 1;
|
||||
}
|
||||
|
||||
standardScaleFactor_ = scaleFactor;
|
||||
|
||||
replacer_.NotifyConfigChanged();
|
||||
|
||||
@@ -561,6 +561,9 @@ bool TextureScalerCommon::ScaleInto(u32 *outputBuf, u32 *src, u32 &dstFmt, int &
|
||||
case HYBRID:
|
||||
ScaleHybrid(factor, inputBuf, outputBuf, width, height);
|
||||
break;
|
||||
case GAUSSIAN:
|
||||
case COSINE:
|
||||
// no cpu implementation for those, so fall back to bicubic
|
||||
case BICUBIC:
|
||||
ScaleBicubicMitchell(factor, inputBuf, outputBuf, width, height);
|
||||
break;
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
bool Scale(u32 *&data, u32 &dstfmt, int &width, int &height, int factor);
|
||||
bool ScaleInto(u32 *out, u32 *src, u32 &dstfmt, int &width, int &height, int factor);
|
||||
|
||||
enum { XBRZ = 0, HYBRID = 1, BICUBIC = 2, HYBRID_BICUBIC = 3 };
|
||||
enum { XBRZ = 0, HYBRID = 1, BICUBIC = 2, HYBRID_BICUBIC = 3, GAUSSIAN = 4, COSINE = 5 };
|
||||
|
||||
protected:
|
||||
virtual void ConvertTo8888(u32 format, u32 *source, u32 *&dest, int width, int height) = 0;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "GPU/Common/GPUStateUtils.h"
|
||||
#include "GPU/Common/TextureScalerCommon.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/Common/ShaderUniforms.h"
|
||||
|
||||
@@ -31,6 +32,249 @@
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
static const char* sampler_default =
|
||||
"float4 tex_sample(float2 coord) {\n"
|
||||
" return tex_sample_direct(coord);\n"
|
||||
"};\n";
|
||||
|
||||
static const char* sampler_hybrid = sampler_default;
|
||||
static const char* sampler_bicubic = sampler_default;
|
||||
static const char* sampler_hybrid_bicubic = sampler_default;
|
||||
static const char* sampler_gaussian =
|
||||
"#define sharpness 1.0\n"
|
||||
"#define pi 3.14159265358\n"
|
||||
"#define normalGauss(x) ((exp(-(x)*(x)*0.5))/sqrt(2.0*pi))\n"
|
||||
"float normalGaussIntegral(float x)\n"
|
||||
"{\n"
|
||||
" float a1 = 0.4361836;\n"
|
||||
" float a2 = -0.1201676;\n"
|
||||
" float a3 = 0.9372980;\n"
|
||||
" float p = 0.3326700;\n"
|
||||
" float t = 1.0 / (1.0 + p*abs(x));\n"
|
||||
"\n"
|
||||
" return (0.5-normalGauss(x) * (t*(a1 + t*(a2 + a3*t))))*sign(x);\n"
|
||||
"}\n"
|
||||
"#define KERNEL(x,b) (normalGaussIntegral(sqrt(2*pi)*b*(x - 0.5)) - normalGaussIntegral(sqrt(2*pi)*b*(x + 0.5)))\n"
|
||||
"\n"
|
||||
"float4 tex_sample(float2 coord) {\n"
|
||||
" float2 offset = frac(coord * u_texSize.xy) - 0.5;\n"
|
||||
" float4 tempColor = 0.0;\n"
|
||||
" float4 c;\n"
|
||||
" float range = 2.0f;\n"
|
||||
" float i,j;\n"
|
||||
" float2 pos;\n"
|
||||
" for (i = -range; i < range + 2.0; i++){\n"
|
||||
" pos.x = offset.x - i;\n"
|
||||
" for (j = -range; j<range+2.0 ;j++){\n"
|
||||
" pos.y = offset.y - j;\n"
|
||||
" c=tex_sample_direct(coord - pos * u_texSize.zw).rgba;\n"
|
||||
" tempColor+=c*KERNEL(pos.x,sharpness)*KERNEL(pos.y,sharpness);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" tempColor=clamp(tempColor,0.0,1.0);\n"
|
||||
" return tempColor;\n"
|
||||
"};\n";
|
||||
static const char* sampler_cosine =
|
||||
"#define sharpness 1.0\n"
|
||||
"#define pi 3.14159265358\n"
|
||||
"#define a(x) abs(x)\n"
|
||||
"#define d(x,b) (pi*b*min(a(x)+0.5,1.0/b))\n"
|
||||
"#define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b))\n"
|
||||
"#define KERNEL(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi))\n"
|
||||
"\n"
|
||||
"float4 tex_sample(float2 coord) {\n"
|
||||
" float2 offset = frac(coord * u_texSize.xy) - 0.5;\n"
|
||||
" float4 tempColor = 0.0;\n"
|
||||
" float4 c;\n"
|
||||
" float range = 2.0f;\n"
|
||||
" float i,j;\n"
|
||||
" float2 pos;\n"
|
||||
" for (i = -range; i < range + 2.0; i++){\n"
|
||||
" pos.x = offset.x - i;\n"
|
||||
" for (j = -range; j<range+2.0 ;j++){\n"
|
||||
" pos.y = offset.y - j;\n"
|
||||
" c=tex_sample_direct(coord - pos * u_texSize.zw).rgba;\n"
|
||||
" tempColor+=c*KERNEL(pos.x,sharpness)*KERNEL(pos.y,sharpness);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" tempColor=clamp(tempColor,0.0,1.0);\n"
|
||||
" return tempColor;\n"
|
||||
"};\n";
|
||||
static const char* sampler_xbrz =
|
||||
"float c_df(float4 c1, float4 c2) {\n"
|
||||
" float4 df = abs(c1 - c2);\n"
|
||||
" return df.r + df.g + df.b + df.a;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"static const float coef = 2.0;\n"
|
||||
"\n"
|
||||
"static const float4 rgbw = float4(14.352, 28.176, 5.472, 15.0);\n"
|
||||
"static const float4 eq_threshold = float4(15.0, 15.0, 15.0, 15.0);\n"
|
||||
"\n"
|
||||
"static const float4 delta = float4(1.0/4., 1.0/4., 1.0/4., 1.0/4.);\n"
|
||||
"static const float4 delta_l = float4(0.5/4., 1.0/4., 0.5/4., 1.0/4.);\n"
|
||||
"static const float4 delta_u = delta_l.yxwz;\n"
|
||||
"\n"
|
||||
"static const float4 Ao = float4( 1.0, -1.0, -1.0, 1.0 );\n"
|
||||
"static const float4 Bo = float4( 1.0, 1.0, -1.0,-1.0 );\n"
|
||||
"static const float4 Co = float4( 1.5, 0.5, -0.5, 0.5 );\n"
|
||||
"static const float4 Ax = float4( 1.0, -1.0, -1.0, 1.0 );\n"
|
||||
"static const float4 Bx = float4( 0.5, 2.0, -0.5,-2.0 );\n"
|
||||
"static const float4 Cx = float4( 1.0, 1.0, -0.5, 0.0 );\n"
|
||||
"static const float4 Ay = float4( 1.0, -1.0, -1.0, 1.0 );\n"
|
||||
"static const float4 By = float4( 2.0, 0.5, -2.0,-0.5 );\n"
|
||||
"static const float4 Cy = float4( 2.0, 0.0, -1.0, 0.5 );\n"
|
||||
"static const float4 Ci = float4(0.25, 0.25, 0.25, 0.25);\n"
|
||||
"\n"
|
||||
"// Difference between vector components.\n"
|
||||
"float4 df(float4 A, float4 B)\n"
|
||||
"{\n"
|
||||
" return float4(abs(A-B));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"// Compare two vectors and return their components are different.\n"
|
||||
"float4 diff(float4 A, float4 B)\n"
|
||||
"{\n"
|
||||
" return step(0.001, df(A, B));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"// Determine if two vector components are equal based on a threshold.\n"
|
||||
"float4 eq(float4 A, float4 B)\n"
|
||||
"{\n"
|
||||
" return step(df(A, B), 15.);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"// Determine if two vector components are NOT equal based on a threshold.\n"
|
||||
"float4 neq(float4 A, float4 B)\n"
|
||||
"{\n"
|
||||
" return (float4(1.0, 1.0, 1.0, 1.0) - eq(A, B));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"// Weighted distance.\n"
|
||||
"float4 wd(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h)\n"
|
||||
"{\n"
|
||||
" return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float4 tex_sample(float2 coord)\n"
|
||||
"{\n"
|
||||
" float2 tc = coord * u_texSize.xy;\n"
|
||||
" float2 fp = frac(tc);\n"
|
||||
" tc = floor(tc) + 0.5;\n"
|
||||
"\n"
|
||||
" float4 xyp_1_2_3 = tc.xxxy + float4(-1., 0., 1., -2.);\n"
|
||||
" float4 xyp_6_7_8 = tc.xxxy + float4(-1., 0., 1., -1.);\n"
|
||||
" float4 xyp_11_12_13 = tc.xxxy + float4(-1., 0., 1., 0.);\n"
|
||||
" float4 xyp_16_17_18 = tc.xxxy + float4(-1., 0., 1., 1.);\n"
|
||||
" float4 xyp_21_22_23 = tc.xxxy + float4(-1., 0., 1., 2.);\n"
|
||||
" float4 xyp_5_10_15 = tc.xyyy + float4(-2., -1., 0., 1.);\n"
|
||||
" float4 xyp_9_14_9 = tc.xyyy + float4( 2., -1., 0., 1.);\n"
|
||||
"\n"
|
||||
" float4 edri;\n"
|
||||
" float4 edr;\n"
|
||||
" float4 edr_l;\n"
|
||||
" float4 edr_u;\n"
|
||||
" float4 px; // px = pixel, edr = edge detection rule\n"
|
||||
" float4 irlv0;\n"
|
||||
" float4 irlv1;\n"
|
||||
" float4 irlv2l;\n"
|
||||
" float4 irlv2u;\n"
|
||||
" float4 block_3d;\n"
|
||||
" float4 fx;\n"
|
||||
" float4 fx_l;\n"
|
||||
" float4 fx_u; // inequations of straight lines.\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" float4 A1 = tex_sample_direct(u_texSize.zw * xyp_1_2_3.xw );\n"
|
||||
" float4 B1 = tex_sample_direct(u_texSize.zw * xyp_1_2_3.yw );\n"
|
||||
" float4 C1 = tex_sample_direct(u_texSize.zw * xyp_1_2_3.zw );\n"
|
||||
" float4 A = tex_sample_direct(u_texSize.zw * xyp_6_7_8.xw );\n"
|
||||
" float4 B = tex_sample_direct(u_texSize.zw * xyp_6_7_8.yw );\n"
|
||||
" float4 C = tex_sample_direct(u_texSize.zw * xyp_6_7_8.zw );\n"
|
||||
" float4 D = tex_sample_direct(u_texSize.zw * xyp_11_12_13.xw );\n"
|
||||
" float4 E = tex_sample_direct(u_texSize.zw * xyp_11_12_13.yw );\n"
|
||||
" float4 F = tex_sample_direct(u_texSize.zw * xyp_11_12_13.zw );\n"
|
||||
" float4 G = tex_sample_direct(u_texSize.zw * xyp_16_17_18.xw );\n"
|
||||
" float4 H = tex_sample_direct(u_texSize.zw * xyp_16_17_18.yw );\n"
|
||||
" float4 I = tex_sample_direct(u_texSize.zw * xyp_16_17_18.zw );\n"
|
||||
" float4 G5 = tex_sample_direct(u_texSize.zw * xyp_21_22_23.xw );\n"
|
||||
" float4 H5 = tex_sample_direct(u_texSize.zw * xyp_21_22_23.yw );\n"
|
||||
" float4 I5 = tex_sample_direct(u_texSize.zw * xyp_21_22_23.zw );\n"
|
||||
" float4 A0 = tex_sample_direct(u_texSize.zw * xyp_5_10_15.xy );\n"
|
||||
" float4 D0 = tex_sample_direct(u_texSize.zw * xyp_5_10_15.xz );\n"
|
||||
" float4 G0 = tex_sample_direct(u_texSize.zw * xyp_5_10_15.xw );\n"
|
||||
" float4 C4 = tex_sample_direct(u_texSize.zw * xyp_9_14_9.xy );\n"
|
||||
" float4 F4 = tex_sample_direct(u_texSize.zw * xyp_9_14_9.xz );\n"
|
||||
" float4 I4 = tex_sample_direct(u_texSize.zw * xyp_9_14_9.xw );\n"
|
||||
"\n"
|
||||
" float4 b = float4(dot(B ,rgbw), dot(D ,rgbw), dot(H ,rgbw), dot(F ,rgbw));\n"
|
||||
" float4 c = float4(dot(C ,rgbw), dot(A ,rgbw), dot(G ,rgbw), dot(I ,rgbw));\n"
|
||||
" float4 d = b.yzwx;\n"
|
||||
" float4 e = dot(E,rgbw).xxxx;\n"
|
||||
" float4 f = b.wxyz;\n"
|
||||
" float4 g = c.zwxy;\n"
|
||||
" float4 h = b.zwxy;\n"
|
||||
" float4 i = c.wxyz;\n"
|
||||
" float4 i4 = float4(dot(I4,rgbw), dot(C1,rgbw), dot(A0,rgbw), dot(G5,rgbw));\n"
|
||||
" float4 i5 = float4(dot(I5,rgbw), dot(C4,rgbw), dot(A1,rgbw), dot(G0,rgbw));\n"
|
||||
" float4 h5 = float4(dot(H5,rgbw), dot(F4,rgbw), dot(B1,rgbw), dot(D0,rgbw));\n"
|
||||
" float4 f4 = h5.yzwx;\n"
|
||||
"\n"
|
||||
" // These inequations define the line below which interpolation occurs.\n"
|
||||
" fx = (Ao*fp.y+Bo*fp.x);\n"
|
||||
" fx_l = (Ax*fp.y+Bx*fp.x);\n"
|
||||
" fx_u = (Ay*fp.y+By*fp.x);\n"
|
||||
"\n"
|
||||
" irlv1 = irlv0 = diff(e,f) * diff(e,h);\n"
|
||||
"\n"
|
||||
" irlv1 = (irlv0 * ( neq(f,b) * neq(f,c) + neq(h,d) * neq(h,g) + eq(e,i) * (neq(f,f4) * neq(f,i4) + neq(h,h5) * neq(h,i5)) + eq(e,g) + eq(e,c)) );\n"
|
||||
"\n"
|
||||
" irlv2l = diff(e,g) * diff(d,g);\n"
|
||||
" irlv2u = diff(e,c) * diff(b,c);\n"
|
||||
"\n"
|
||||
" float4 fx45i = clamp((fx + delta -Co - Ci)/(2.0*delta ), 0.0, 1.0);\n"
|
||||
" float4 fx45 = clamp((fx + delta -Co )/(2.0*delta ), 0.0, 1.0);\n"
|
||||
" float4 fx30 = clamp((fx_l + delta_l -Cx )/(2.0*delta_l), 0.0, 1.0);\n"
|
||||
" float4 fx60 = clamp((fx_u + delta_u -Cy )/(2.0*delta_u), 0.0, 1.0);\n"
|
||||
"\n"
|
||||
" float4 wd1 = wd( e, c, g, i, h5, f4, h, f);\n"
|
||||
" float4 wd2 = wd( h, d, i5, f, i4, b, e, i);\n"
|
||||
"\n"
|
||||
" edri = step(wd1, wd2) * irlv0;\n"
|
||||
" edr = step(wd1 + float4(0.1, 0.1, 0.1, 0.1), wd2) * step(float4(0.5, 0.5, 0.5, 0.5), irlv1);\n"
|
||||
" edr_l = step( 2.*df(f,g), df(h,c) ) * irlv2l * edr;\n"
|
||||
" edr_u = step( 2.*df(h,c), df(f,g) ) * irlv2u * edr;\n"
|
||||
"\n"
|
||||
" fx45 = edr * fx45;\n"
|
||||
" fx30 = edr_l * fx30;\n"
|
||||
" fx60 = edr_u * fx60;\n"
|
||||
" fx45i = edri * fx45i;\n"
|
||||
"\n"
|
||||
" px = step(df(e,f), df(e,h));\n"
|
||||
"\n"
|
||||
" float4 maximos = max(max(fx30, fx60), max(fx45, fx45i));\n"
|
||||
"\n"
|
||||
" float4 res1 = E;\n"
|
||||
" res1 = lerp(res1, lerp(H, F, px.x), maximos.x);\n"
|
||||
" res1 = lerp(res1, lerp(B, D, px.z), maximos.z);\n"
|
||||
"\n"
|
||||
" float4 res2 = E;\n"
|
||||
" res2 = lerp(res2, lerp(F, B, px.y), maximos.y);\n"
|
||||
" res2 = lerp(res2, lerp(D, H, px.w), maximos.w);\n"
|
||||
"\n"
|
||||
" float4 res = lerp(res1, res2, step(c_df(E, res1), c_df(E, res2)));\n"
|
||||
" return res;\n"
|
||||
// " float texel_alpha = tex_sample_direct(tc * u_texSize.zw).a;\n"
|
||||
// "\n"
|
||||
// " return float4(E, texel_alpha);\n"
|
||||
// " return tex_sample_direct(coord);\n"
|
||||
// " return tex_sample_direct(coord * u_texSize.xy * u_texSize.zw);\n"
|
||||
// " return float4(res2, texel_alpha);\n"
|
||||
// " return float4(res.r, 0.0f, 0.0f, texel_alpha);\n"
|
||||
// " return float4(res, texel_alpha);\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
// Missing: Z depth range
|
||||
// Also, logic ops etc, of course, as they are not supported in DX9.
|
||||
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang) {
|
||||
@@ -69,8 +313,10 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
StencilValueType replaceAlphaWithStencilType = (StencilValueType)id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4);
|
||||
|
||||
if (lang == HLSL_DX9) {
|
||||
if (doTexture)
|
||||
if (doTexture) {
|
||||
WRITE(p, "sampler tex : register(s0);\n");
|
||||
WRITE(p, "float4 u_texSize : register(c%i);\n", CONST_PS_TEXSIZE);
|
||||
}
|
||||
if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
if (replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
WRITE(p, "float2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE);
|
||||
@@ -147,6 +393,45 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
}
|
||||
WRITE(p, "};\n");
|
||||
|
||||
if (doTexture) {
|
||||
WRITE(p, "float4 tex_sample_direct(float2 coord) {\n");
|
||||
|
||||
if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) {
|
||||
WRITE(p, " return tex.Sample(samp, coord)%s;\n", bgraTexture ? ".bgra" : "");
|
||||
} else {
|
||||
WRITE(p, " return tex2D(tex, coord)%s;\n", bgraTexture ? ".bgra" : "");
|
||||
}
|
||||
WRITE(p, "};\n");
|
||||
|
||||
if(g_Config.bRealtimeTexScaling && g_Config.iTexScalingLevel != 1) {
|
||||
switch (g_Config.iTexScalingType) {
|
||||
case TextureScalerCommon::XBRZ:
|
||||
WRITE(p, sampler_xbrz);
|
||||
break;
|
||||
case TextureScalerCommon::HYBRID:
|
||||
WRITE(p, sampler_hybrid);
|
||||
break;
|
||||
case TextureScalerCommon::BICUBIC:
|
||||
WRITE(p, sampler_bicubic);
|
||||
break;
|
||||
case TextureScalerCommon::HYBRID_BICUBIC:
|
||||
WRITE(p, sampler_hybrid_bicubic);
|
||||
break;
|
||||
case TextureScalerCommon::GAUSSIAN:
|
||||
WRITE(p, sampler_gaussian);
|
||||
break;
|
||||
case TextureScalerCommon::COSINE:
|
||||
WRITE(p, sampler_cosine);
|
||||
break;
|
||||
default:
|
||||
ERROR_LOG(G3D, "Unknown scaling type: %d", g_Config.iTexScalingType);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
WRITE(p, sampler_default);
|
||||
}
|
||||
}
|
||||
|
||||
if (lang == HLSL_DX9) {
|
||||
WRITE(p, "float4 main( PS_IN In ) : COLOR {\n");
|
||||
} else {
|
||||
@@ -180,7 +465,10 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
}
|
||||
|
||||
if (doTexture) {
|
||||
const char *texcoord = "In.v_texcoord";
|
||||
const char *texcoord = "In.v_texcoord.xy";
|
||||
if (doTextureProjection) {
|
||||
texcoord = "In.v_texcoord.xy / In.v_texcoord.z";
|
||||
}
|
||||
// TODO: Not sure the right way to do this for projection.
|
||||
if (needShaderTexClamp) {
|
||||
// We may be clamping inside a larger surface (tex = 64x64, buffer=480x272).
|
||||
@@ -210,23 +498,9 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
|
||||
WRITE(p, " float2 fixedcoord = float2(%s, %s);\n", ucoord.c_str(), vcoord.c_str());
|
||||
texcoord = "fixedcoord";
|
||||
// We already projected it.
|
||||
doTextureProjection = false;
|
||||
}
|
||||
|
||||
if (lang == HLSL_D3D11 || lang == HLSL_D3D11_LEVEL9) {
|
||||
if (doTextureProjection) {
|
||||
WRITE(p, " float4 t = tex.Sample(samp, In.v_texcoord.xy / In.v_texcoord.z)%s;\n", bgraTexture ? ".bgra" : "");
|
||||
} else {
|
||||
WRITE(p, " float4 t = tex.Sample(samp, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : "");
|
||||
}
|
||||
} else {
|
||||
if (doTextureProjection) {
|
||||
WRITE(p, " float4 t = tex2Dproj(tex, float4(In.v_texcoord.x, In.v_texcoord.y, 0, In.v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : "");
|
||||
} else {
|
||||
WRITE(p, " float4 t = tex2D(tex, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : "");
|
||||
}
|
||||
}
|
||||
WRITE(p, " float4 t = tex_sample(%s);\n", texcoord);
|
||||
WRITE(p, " float4 p = In.v_color0;\n");
|
||||
|
||||
if (doTextureAlpha) { // texfmt == RGBA
|
||||
|
||||
@@ -38,4 +38,6 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguag
|
||||
// For stencil upload
|
||||
#define CONST_PS_STENCILVALUE 10
|
||||
|
||||
// For scaling filters
|
||||
#define CONST_PS_TEXSIZE 11
|
||||
};
|
||||
@@ -258,7 +258,7 @@ static void ConvertProjMatrixToD3DThrough(Matrix4x4 &in) {
|
||||
in.translateAndScale(Vec3(xoff, yoff, 0.5f), Vec3(1.0f, 1.0f, 0.5f));
|
||||
}
|
||||
|
||||
const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP;
|
||||
const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP | DIRTY_TEXSIZE;
|
||||
|
||||
void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) {
|
||||
if (dirtyUniforms & DIRTY_TEXENV) {
|
||||
@@ -310,6 +310,16 @@ void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) {
|
||||
PSSetFloatArray(CONST_PS_TEXCLAMP, texclamp, 4);
|
||||
PSSetFloatArray(CONST_PS_TEXCLAMPOFF, texclampoff, 2);
|
||||
}
|
||||
|
||||
if (dirtyUniforms & DIRTY_TEXSIZE) {
|
||||
const float texSize[4] = {
|
||||
(float)gstate_c.curTextureWidth,
|
||||
(float)gstate_c.curTextureHeight,
|
||||
1.0f / (float)gstate_c.curTextureWidth,
|
||||
1.0f / (float)gstate_c.curTextureHeight,
|
||||
};
|
||||
PSSetFloatArray(CONST_PS_TEXSIZE, texSize, 4);
|
||||
}
|
||||
}
|
||||
|
||||
const uint64_t vsUniforms = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX |
|
||||
|
||||
+2
-1
@@ -1407,10 +1407,11 @@ void GPUCommon::Execute_TexSize0(u32 op, u32 diff) {
|
||||
// Don't reset it unless the size is different / the texture has changed.
|
||||
if (diff || gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS)) {
|
||||
gstate_c.curTextureWidth = gstate.getTextureWidth(0);
|
||||
gstate_c.curTextureHeight = gstate.getTextureHeight(0);
|
||||
gstate_c.curTextureHeight = gstate.getTextureHeight(0);
|
||||
gstate_c.Dirty(DIRTY_UVSCALEOFFSET);
|
||||
// We will need to reset the texture now.
|
||||
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
|
||||
gstate_c.Dirty(DIRTY_TEXSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ void GameSettingsScreen::CreateViews() {
|
||||
});
|
||||
texScalingChoice->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
|
||||
static const char *texScaleAlgos[] = { "xBRZ", "Hybrid", "Bicubic", "Hybrid + Bicubic", };
|
||||
static const char *texScaleAlgos[] = { "xBRZ", "Hybrid", "Bicubic", "Hybrid + Bicubic", "Gaussian", "Cosine"};
|
||||
PopupMultiChoice *texScalingType = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iTexScalingType, gr->T("Upscale Type"), texScaleAlgos, 0, ARRAY_SIZE(texScaleAlgos), gr->GetName(), screenManager()));
|
||||
texScalingType->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
|
||||
@@ -391,6 +391,15 @@ void GameSettingsScreen::CreateViews() {
|
||||
});
|
||||
deposterize->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
|
||||
CheckBox *realtimeScaling = graphicsSettings->Add(new CheckBox(&g_Config.bRealtimeTexScaling, gr->T("Realtime Scaling")));
|
||||
realtimeScaling->OnClick.Add([=](EventParams &e) {
|
||||
if (g_Config.bRealtimeTexScaling == true) {
|
||||
settingInfo_->Show(gr->T("Realtime Scaling Tip", "GPU heavy - apply texture scaling filters with shaders during rendering"), e.v);
|
||||
}
|
||||
return UI::EVENT_CONTINUE;
|
||||
});
|
||||
realtimeScaling->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
|
||||
graphicsSettings->Add(new ItemHeader(gr->T("Texture Filtering")));
|
||||
static const char *anisoLevels[] = { "Off", "2x", "4x", "8x", "16x" };
|
||||
PopupMultiChoice *anisoFiltering = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iAnisotropyLevel, gr->T("Anisotropic Filtering"), anisoLevels, 0, ARRAY_SIZE(anisoLevels), gr->GetName(), screenManager()));
|
||||
|
||||
@@ -927,6 +927,12 @@ void HandleGlobalMessage(const std::string &msg, const std::string &value) {
|
||||
}
|
||||
Reporting::UpdateConfig();
|
||||
}
|
||||
if (msg == "gpu_clearShaderCache") {
|
||||
if (gpu) {
|
||||
gpu->ClearShaderCache();
|
||||
}
|
||||
Reporting::UpdateConfig();
|
||||
}
|
||||
if (msg == "core_powerSaving") {
|
||||
if (value != "false") {
|
||||
I18NCategory *sy = GetI18NCategory("System");
|
||||
|
||||
@@ -346,7 +346,10 @@ namespace MainWindow {
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID);
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_BICUBIC);
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID_BICUBIC);
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_GAUSSIAN);
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_COSINE);
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_DEPOSTERIZE);
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_REALTIME);
|
||||
TranslateMenuItem(menu, ID_OPTIONS_HARDWARETRANSFORM);
|
||||
TranslateMenuItem(menu, ID_OPTIONS_VERTEXCACHE);
|
||||
TranslateMenuItem(menu, ID_OPTIONS_SHOWFPS);
|
||||
@@ -481,6 +484,10 @@ namespace MainWindow {
|
||||
void setTexScalingMultiplier(int level) {
|
||||
g_Config.iTexScalingLevel = level;
|
||||
NativeMessageReceived("gpu_clearCache", "");
|
||||
|
||||
if(g_Config.bRealtimeTexScaling) {
|
||||
NativeMessageReceived("gpu_clearShaderCache", "");
|
||||
}
|
||||
}
|
||||
|
||||
static void setTexFiltering(int type) {
|
||||
@@ -494,6 +501,10 @@ namespace MainWindow {
|
||||
static void setTexScalingType(int type) {
|
||||
g_Config.iTexScalingType = type;
|
||||
NativeMessageReceived("gpu_clearCache", "");
|
||||
|
||||
if(g_Config.bRealtimeTexScaling) {
|
||||
NativeMessageReceived("gpu_clearShaderCache", "");
|
||||
}
|
||||
}
|
||||
|
||||
static void setRenderingMode(int mode) {
|
||||
@@ -759,6 +770,14 @@ namespace MainWindow {
|
||||
case ID_TEXTURESCALING_HYBRID: setTexScalingType(TextureScalerCommon::HYBRID); break;
|
||||
case ID_TEXTURESCALING_BICUBIC: setTexScalingType(TextureScalerCommon::BICUBIC); break;
|
||||
case ID_TEXTURESCALING_HYBRID_BICUBIC: setTexScalingType(TextureScalerCommon::HYBRID_BICUBIC); break;
|
||||
case ID_TEXTURESCALING_GAUSSIAN: setTexScalingType(TextureScalerCommon::GAUSSIAN); break;
|
||||
case ID_TEXTURESCALING_COSINE: setTexScalingType(TextureScalerCommon::COSINE); break;
|
||||
|
||||
case ID_TEXTURESCALING_REALTIME:
|
||||
g_Config.bRealtimeTexScaling = !g_Config.bRealtimeTexScaling;
|
||||
NativeMessageReceived("gpu_clearShaderCache", "");
|
||||
NativeMessageReceived("gpu_clearCache", "");
|
||||
break;
|
||||
|
||||
case ID_TEXTURESCALING_DEPOSTERIZE:
|
||||
g_Config.bTexDeposterize = !g_Config.bTexDeposterize;
|
||||
@@ -1065,6 +1084,7 @@ namespace MainWindow {
|
||||
CHECKITEM(ID_OPTIONS_PAUSE_FOCUS, g_Config.bPauseOnLostFocus);
|
||||
CHECKITEM(ID_EMULATION_SOUND, g_Config.bEnableSound);
|
||||
CHECKITEM(ID_TEXTURESCALING_DEPOSTERIZE, g_Config.bTexDeposterize);
|
||||
CHECKITEM(ID_TEXTURESCALING_REALTIME, g_Config.bRealtimeTexScaling);
|
||||
CHECKITEM(ID_EMULATION_CHEATS, g_Config.bEnableCheats);
|
||||
CHECKITEM(ID_OPTIONS_IGNOREWINKEY, g_Config.bIgnoreWindowsKey);
|
||||
CHECKITEM(ID_FILE_DUMPFRAMES, g_Config.bDumpFrames);
|
||||
@@ -1172,12 +1192,14 @@ namespace MainWindow {
|
||||
ID_TEXTURESCALING_HYBRID,
|
||||
ID_TEXTURESCALING_BICUBIC,
|
||||
ID_TEXTURESCALING_HYBRID_BICUBIC,
|
||||
ID_TEXTURESCALING_GAUSSIAN,
|
||||
ID_TEXTURESCALING_COSINE,
|
||||
};
|
||||
if (g_Config.iTexScalingType < TextureScalerCommon::XBRZ)
|
||||
g_Config.iTexScalingType = TextureScalerCommon::XBRZ;
|
||||
|
||||
else if (g_Config.iTexScalingType > TextureScalerCommon::HYBRID_BICUBIC)
|
||||
g_Config.iTexScalingType = TextureScalerCommon::HYBRID_BICUBIC;
|
||||
else if (g_Config.iTexScalingType > TextureScalerCommon::COSINE)
|
||||
g_Config.iTexScalingType = TextureScalerCommon::COSINE;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(texscalingtypeitems); i++) {
|
||||
CheckMenuItem(menu, texscalingtypeitems[i], MF_BYCOMMAND | ((i == g_Config.iTexScalingType) ? MF_CHECKED : MF_UNCHECKED));
|
||||
|
||||
@@ -612,8 +612,11 @@ BEGIN
|
||||
MENUITEM "Hybrid", ID_TEXTURESCALING_HYBRID
|
||||
MENUITEM "Bicubic", ID_TEXTURESCALING_BICUBIC
|
||||
MENUITEM "Hybrid + Bicubic", ID_TEXTURESCALING_HYBRID_BICUBIC
|
||||
MENUITEM "Gaussian", ID_TEXTURESCALING_GAUSSIAN
|
||||
MENUITEM "Cosine", ID_TEXTURESCALING_COSINE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Deposterize", ID_TEXTURESCALING_DEPOSTERIZE
|
||||
MENUITEM "Realtime Scaling", ID_TEXTURESCALING_REALTIME
|
||||
END
|
||||
MENUITEM "Hardware Transform", ID_OPTIONS_HARDWARETRANSFORM
|
||||
MENUITEM "Vertex Cache", ID_OPTIONS_VERTEXCACHE
|
||||
|
||||
@@ -340,6 +340,10 @@
|
||||
#define ID_OPTIONS_WINDOW9X 40175
|
||||
#define ID_OPTIONS_WINDOW10X 40176
|
||||
|
||||
#define ID_TEXTURESCALING_REALTIME 40177
|
||||
#define ID_TEXTURESCALING_GAUSSIAN 40178
|
||||
#define ID_TEXTURESCALING_COSINE 40179
|
||||
|
||||
// Dummy option to let the buffered rendering hotkey cycle through all the options.
|
||||
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
|
||||
#define IDC_STEPOUT 40501
|
||||
|
||||
@@ -175,7 +175,8 @@ static RetroOption<int> ppsspp_button_preference("ppsspp_button_preference", "Co
|
||||
static RetroOption<bool> ppsspp_fast_memory("ppsspp_fast_memory", "Fast Memory (Speedhack)", true);
|
||||
static RetroOption<bool> ppsspp_block_transfer_gpu("ppsspp_block_transfer_gpu", "Block Transfer GPU", true);
|
||||
static RetroOption<int> ppsspp_texture_scaling_level("ppsspp_texture_scaling_level", "Texture Scaling Level", { { "1", 1 }, { "2", 2 }, { "3", 3 }, { "4", 4 }, { "5", 5 }, { "0", 0 } });
|
||||
static RetroOption<int> ppsspp_texture_scaling_type("ppsspp_texture_scaling_type", "Texture Scaling Type", { { "xbrz", TextureScalerCommon::XBRZ }, { "hybrid", TextureScalerCommon::HYBRID }, { "bicubic", TextureScalerCommon::BICUBIC }, { "hybrid_bicubic", TextureScalerCommon::HYBRID_BICUBIC } });
|
||||
static RetroOption<int> ppsspp_texture_scaling_type("ppsspp_texture_scaling_type", "Texture Scaling Type", { { "xbrz", TextureScalerCommon::XBRZ }, { "hybrid", TextureScalerCommon::HYBRID }, { "bicubic", TextureScalerCommon::BICUBIC }, { "hybrid_bicubic", TextureScalerCommon::HYBRID_BICUBIC }, { "gaussian", TextureScalerCommon::GAUSSIAN }, { "cosine", TextureScalerCommon::COSINE } });
|
||||
static RetroOption<bool> ppsspp_texture_scaling_realtime("ppsspp_texture_scaling_realtime", "Realtime Texture Scaling", false);
|
||||
static RetroOption<int> ppsspp_texture_anisotropic_filtering("ppsspp_texture_anisotropic_filtering", "Anisotropic Filtering", { "off", "1x", "2x", "4x", "8x", "16x" });
|
||||
static RetroOption<bool> ppsspp_texture_deposterize("ppsspp_texture_deposterize", "Texture Deposterize", false);
|
||||
static RetroOption<bool> ppsspp_gpu_hardware_transform("ppsspp_gpu_hardware_transform", "GPU Hardware T&L", true);
|
||||
@@ -204,6 +205,7 @@ void retro_set_environment(retro_environment_t cb) {
|
||||
vars.push_back(ppsspp_texture_scaling_type.GetOptions());
|
||||
vars.push_back(ppsspp_texture_anisotropic_filtering.GetOptions());
|
||||
vars.push_back(ppsspp_texture_deposterize.GetOptions());
|
||||
vars.push_back(ppsspp_texture_scaling_realtime.GetOptions());
|
||||
vars.push_back(ppsspp_gpu_hardware_transform.GetOptions());
|
||||
vars.push_back(ppsspp_vertex_cache.GetOptions());
|
||||
vars.push_back(ppsspp_separate_io_thread.GetOptions());
|
||||
@@ -293,12 +295,13 @@ static void check_variables(CoreParameter &coreParam) {
|
||||
}
|
||||
}
|
||||
|
||||
if (ppsspp_texture_scaling_type.Update(&g_Config.iTexScalingType) && gpu) {
|
||||
gpu->ClearCacheNextFrame();
|
||||
}
|
||||
|
||||
if (ppsspp_texture_scaling_level.Update(&g_Config.iTexScalingLevel) && gpu) {
|
||||
bool clear_cache = ppsspp_texture_scaling_type.Update(&g_Config.iTexScalingType);
|
||||
clear_cache |= ppsspp_texture_scaling_level.Update(&g_Config.iTexScalingLevel);
|
||||
clear_cache |= ppsspp_texture_scaling_realtime.Update(&g_Config.bRealtimeTexScaling);
|
||||
if (clear_cache && gpu) {
|
||||
gpu->ClearCacheNextFrame();
|
||||
gpu->ClearShaderCache();
|
||||
gpu->Resized();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user