Remove Realtime scaling (d3d11)

This commit is contained in:
LunaMoo committed 2020-04-05 23:58:38 +02:00
1 parent 4debff114c
commit 9c6f78c21f
40 files changed
+121 -1374

No files matched your search

-1
View File
@@ -1938,7 +1938,6 @@ set(NativeAssets
android/assets/ui_atlas_luna.meta
assets/lang
assets/shaders
assets/scalers
assets/Roboto-Condensed.ttf
assets/7z.png
assets/compat.ini
+5 -10
View File
@@ -506,7 +506,6 @@ static ConfigSetting cpuSettings[] = {
ConfigSetting("VulkanMultithreading", &g_Config.bVulkanMultithreading, false, true, true),
ReportedConfigSetting("SeparateSASThread", &g_Config.bSeparateSASThread, &DefaultSasThread, true, true),
ReportedConfigSetting("IOTimingMethod", &g_Config.iIOTimingMethod, IOTIMING_REALISTIC, true, true),
ConfigSetting("IOManualDelay", &g_Config.iIOManualDelay, 1, true, true),
ConfigSetting("FastMemoryAccess", &g_Config.bFastMemory, false, true, true),
ReportedConfigSetting("FuncReplacements", &g_Config.bFuncReplacements, true, true, true),
ConfigSetting("HideSlowWarnings", &g_Config.bHideSlowWarnings, true, true, false),
@@ -599,12 +598,12 @@ int Config::NextValidBackend() {
}
// Count these as "failed" too so we don't pick them.
/*SplitString(sDisabledGPUBackends, ',', split);
SplitString(sDisabledGPUBackends, ',', split);
for (const auto &str : split) {
if (!str.empty()) {
failed.insert(GPUBackendFromString(str));
}
}*/
}
if (failed.count((GPUBackend)iGPUBackend)) {
ERROR_LOG(LOADER, "Graphics backend failed for %d, trying another", iGPUBackend);
@@ -646,17 +645,14 @@ int Config::NextValidBackend() {
bool Config::IsBackendEnabled(GPUBackend backend, bool validate) {
std::vector<std::string> split;
// Disabled due to some xstring std::basic_string exception affecting only d3d11 in this branch.
// No idea why, maybe cause realtime texture scaling as that's the primary difference with d3d11,
// however just adding any new std::string to config seems to be enough to cause the failure
/*SplitString(sDisabledGPUBackends, ',', split);
SplitString(sDisabledGPUBackends, ',', split);
for (const auto &str : split) {
if (str.empty())
continue;
auto match = GPUBackendFromString(str);
if (match == backend)
return false;
}*/
}
#if PPSSPP_PLATFORM(IOS)
if (backend != GPUBackend::OPENGL)
@@ -717,7 +713,7 @@ static ConfigSetting graphicsSettings[] = {
ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0, true, true),
ReportedConfigSetting("GraphicsBackend", &g_Config.iGPUBackend, &DefaultGPUBackend, &GPUBackendTranslator::To, &GPUBackendTranslator::From, true, false),
ConfigSetting("FailedGraphicsBackends", &g_Config.sFailedGPUBackends, ""),
//ConfigSetting("DisabledGraphicsBackends", &g_Config.sDisabledGPUBackends, ""),
ConfigSetting("DisabledGraphicsBackends", &g_Config.sDisabledGPUBackends, ""),
ConfigSetting("VulkanDevice", &g_Config.sVulkanDevice, "", true, false),
#ifdef _WIN32
ConfigSetting("D3D11Device", &g_Config.sD3D11Device, "", true, false),
@@ -771,7 +767,6 @@ 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),
ReportedConfigSetting("TexHardwareScaling", &g_Config.bTexHardwareScaling, false, true, true),
ConfigSetting("UnlockCachedScaling", &g_Config.bUnlockCachedScaling, false, true, true),
ConfigSetting("VSyncInterval", &g_Config.bVSync, true, true, true),
+1 -2
View File
@@ -141,7 +141,7 @@ public:
// GFX
int iGPUBackend;
std::string sFailedGPUBackends;
//std::string sDisabledGPUBackends;
std::string sDisabledGPUBackends;
// We have separate device parameters for each backend so it doesn't get erased if you switch backends.
// If not set, will use the "best" device.
std::string sVulkanDevice;
@@ -193,7 +193,6 @@ public:
bool bIgnoreTextureFilenames;
int iTexScalingLevel; // 0 = auto, 1 = off, 2 = 2x, ..., 5 = 5x
int iTexScalingType; // 0 = xBRZ, 1 = Hybrid
bool bRealtimeTexScaling;
bool bTexDeposterize;
bool bUnlockCachedScaling;
bool bTexHardwareScaling;
+1 -1
View File
@@ -82,7 +82,7 @@ struct ThreadQueueList {
cur = cur->next;
}
//_dbg_assert_msg_(SCEKERNEL, false, "ThreadQueueList should not be empty.");
_dbg_assert_msg_(SCEKERNEL, false, "ThreadQueueList should not be empty.");
return 0;
}
+1 -1
View File
@@ -413,7 +413,7 @@ static void __IoAsyncNotify(u64 userdata, int cyclesLate) {
u64 finishTicks = __IoCompleteAsyncIO(f);
if (finishTicks > CoreTiming::GetTicks()) {
// Reschedule for later, since we now know how long it ought to take.
CoreTiming::ScheduleEvent((finishTicks - CoreTiming::GetTicks()) * g_Config.iIOManualDelay, asyncNotifyEvent, userdata);
CoreTiming::ScheduleEvent((finishTicks - CoreTiming::GetTicks()), asyncNotifyEvent, userdata);
return;
}
} else {
+22 -19
View File
@@ -34,29 +34,32 @@
alignas(16) static s16 volumeValues[4] = {};
void AdjustVolumeBlockNEON(s16 *out, s16 *in, size_t size, int leftVol, int rightVol) {
volumeValues[0] = leftVol >> 1;
volumeValues[1] = rightVol >> 1;
volumeValues[2] = leftVol >> 1;
volumeValues[3] = rightVol >> 1;
if (leftVol <= 0xFFFF && -leftVol <= 0x10000 && rightVol <= 0xFFFF && -rightVol <= 0x10000) {
// Note: vqshrn_n_s32 takes a const argument, so we always go with 1 here, 15 there.
volumeValues[0] = leftVol >> 1;
volumeValues[1] = rightVol >> 1;
volumeValues[2] = leftVol >> 1;
volumeValues[3] = rightVol >> 1;
const int16x4_t vol = vld1_s16(volumeValues);
const int16x4_t vol = vld1_s16(volumeValues);
while (size >= 16) {
int16x8_t indata1 = vld1q_s16(in);
int16x8_t indata2 = vld1q_s16(in + 8);
while (size >= 16) {
int16x8_t indata1 = vld1q_s16(in);
int16x8_t indata2 = vld1q_s16(in + 8);
int32x4_t outh1 = vmull_s16(vget_high_s16(indata1), vol);
int32x4_t outh2 = vmull_s16(vget_high_s16(indata2), vol);
int32x4_t outl1 = vmull_s16(vget_low_s16(indata1), vol);
int32x4_t outl2 = vmull_s16(vget_low_s16(indata2), vol);
int32x4_t outh1 = vmull_s16(vget_high_s16(indata1), vol);
int32x4_t outh2 = vmull_s16(vget_high_s16(indata2), vol);
int32x4_t outl1 = vmull_s16(vget_low_s16(indata1), vol);
int32x4_t outl2 = vmull_s16(vget_low_s16(indata2), vol);
int16x8_t outdata1 = vcombine_s16(vqshrn_n_s32(outl1, 15), vqshrn_n_s32(outh1, 15));
int16x8_t outdata2 = vcombine_s16(vqshrn_n_s32(outl2, 15), vqshrn_n_s32(outh2, 15));
vst1q_s16(out, outdata1);
vst1q_s16(out + 8, outdata2);
in += 16;
out += 16;
size -= 16;
int16x8_t outdata1 = vcombine_s16(vqshrn_n_s32(outl1, 15), vqshrn_n_s32(outh1, 15));
int16x8_t outdata2 = vcombine_s16(vqshrn_n_s32(outl2, 15), vqshrn_n_s32(outh2, 15));
vst1q_s16(out, outdata1);
vst1q_s16(out + 8, outdata2);
in += 16;
out += 16;
size -= 16;
}
}
if (leftVol <= 0x7fff && -leftVol <= 0x8000 && rightVol <= 0x7fff && -rightVol <= 0x8000) {
-1
View File
@@ -135,7 +135,6 @@ bool IsColorTestTriviallyTrue() {
}
}
// TODO: Pack into 16-bit integer.
const bool nonAlphaSrcFactors[16] = {
true, // GE_SRCBLEND_DSTCOLOR,
true, // GE_SRCBLEND_INVDSTCOLOR,
+2 -3
View File
@@ -92,11 +92,10 @@ enum : uint64_t {
DIRTY_BEZIERSPLINE = 1ULL << 32,
DIRTY_TEXCLAMP = 1ULL << 33,
DIRTY_CULLRANGE = 1ULL << 34,
DIRTY_TEXSIZE = 1ULL << 35,
DIRTY_DEPAL = 1ULL << 36,
DIRTY_DEPAL = 1ULL << 35,
// space for 4 more uniform dirty flags. Remember to update DIRTY_ALL_UNIFORMS.
// space for 5 more uniform dirty flags. Remember to update DIRTY_ALL_UNIFORMS.
DIRTY_BONE_UNIFORMS = 0xFF000000ULL,
-9
View File
@@ -163,7 +163,6 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
if (!useBufferedRendering && g_display_rotation != DisplayRotation::ROTATE_0) {
proj_through = proj_through * g_display_rot_matrix;
}
// proj_through.translateAndScale(Vec3(0, 0, 0), Vec3(1.0f / debugscale, 1.0f / debugscale, 0));
CopyMatrix4x4(ub->proj_through, proj_through.getReadPtr());
}
@@ -273,14 +272,6 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
val |= gstate.isMagnifyFilteringEnabled() << 31;
ub->depal_mask_shift_off_fmt = val;
}
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) {
+1 -4
View File
@@ -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_TEXSIZE | DIRTY_DEPAL,
DIRTY_BEZIERSPLINE | DIRTY_DEPAL,
DIRTY_LIGHT_UNIFORMS =
DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3 |
DIRTY_MATDIFFUSE | DIRTY_MATSPECULAR | DIRTY_MATEMISSIVE | DIRTY_AMBIENT,
@@ -43,7 +43,6 @@ struct UB_VS_FS_Base {
float blendFixB[4];
float texClamp[4];
float texClampOffset[4];
float texSize[4];
};
static const char *ub_baseStr =
@@ -71,7 +70,6 @@ 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.
@@ -100,7 +98,6 @@ 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
+1 -12
View File
@@ -200,10 +200,6 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl
forceNearest = true;
}
}
// addr is set to nullptr for framebuffers
if (addr && (g_Config.bRealtimeTexScaling && g_Config.iGPUBackend == (int)GPUBackend::DIRECT3D11) && g_Config.iTexScalingLevel != 1) {
forceNearest = true;
}
if (forceNearest) {
magFilt &= ~1;
minFilt &= ~1;
@@ -456,7 +452,6 @@ 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;
@@ -529,7 +524,6 @@ void TextureCacheCommon::SetTexture(bool force) {
gstate_c.curTextureWidth = w;
gstate_c.curTextureHeight = h;
gstate_c.Dirty(DIRTY_TEXSIZE);
// Before we go reading the texture from memory, let's check for render-to-texture.
// We must do this early so we have the right w/h.
@@ -885,7 +879,6 @@ 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)) {
@@ -953,9 +946,7 @@ bool TextureCacheCommon::SetOffsetTexture(u32 offset) {
void TextureCacheCommon::NotifyConfigChanged() {
int scaleFactor;
if (g_Config.bRealtimeTexScaling && g_Config.iGPUBackend == (int)GPUBackend::DIRECT3D11) {
scaleFactor = 1;
} else if (g_Config.bTexHardwareScaling && g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
if (g_Config.bTexHardwareScaling && g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
scaleFactor = 4;
} else {
// 0 means automatic texture scaling, up to 5x, based on resolution.
@@ -1573,10 +1564,8 @@ void TextureCacheCommon::ApplyTexture() {
entry->lastFrame = gpuStats.numFlips;
if (entry->framebuffer) {
gstate_c.curTextureIsRT = true;
ApplyTextureFramebuffer(entry, entry->framebuffer);
} else {
gstate_c.curTextureIsRT = false;
BindTexture(entry);
gstate_c.SetTextureFullAlpha(entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL);
}
-7
View File
@@ -569,19 +569,12 @@ bool TextureScalerCommon::ScaleInto(u32 *outputBuf, u32 *src, u32 &dstFmt, int &
// scale
switch (g_Config.iTexScalingType) {
case XBR:
case SABR:
// no cpu implementation, fall back to xbrz
case _4XBRZ:
case XBRZ:
ScaleXBRZ(factor, inputBuf, outputBuf, width, height);
break;
case HYBRID:
ScaleHybrid(factor, inputBuf, outputBuf, width, height);
break;
case GAUSSIAN:
case COSINE:
// no cpu implementation, fall back to bicubic
case BICUBIC:
ScaleBicubicMitchell(factor, inputBuf, outputBuf, width, height);
break;
+1 -1
View File
@@ -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, _4XBRZ = 4, XBR = 5, SABR = 6, GAUSSIAN = 7, COSINE = 8 };
enum { XBRZ = 0, HYBRID = 1, BICUBIC = 2, HYBRID_BICUBIC = 3 };
protected:
virtual void ConvertTo8888(u32 format, u32 *source, u32 *&dest, int width, int height) = 0;
+2 -2
View File
@@ -19,6 +19,6 @@
#include "GPU/D3D11/FragmentShaderGeneratorD3D11.h"
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
void GenerateFragmentShaderD3D11(const FShaderID &id, char *buffer, char* scalerCode, ShaderLanguage lang) {
DX9::GenerateFragmentShaderHLSL(id, buffer, scalerCode, lang);
void GenerateFragmentShaderD3D11(const FShaderID &id, char *buffer, ShaderLanguage lang) {
DX9::GenerateFragmentShaderHLSL(id, buffer, lang);
}
+1 -1
View File
@@ -19,4 +19,4 @@
#include "GPU/Common/ShaderId.h"
void GenerateFragmentShaderD3D11(const FShaderID &id, char *buffer, char *scalerCode, ShaderLanguage lang);
void GenerateFragmentShaderD3D11(const FShaderID &id, char *buffer, ShaderLanguage lang);
+4 -31
View File
@@ -26,7 +26,6 @@
#include "math/lin/matrix4x4.h"
#include "math/math_util.h"
#include "math/dataconv.h"
#include "file/vfs.h"
#include "thin3d/thin3d.h"
#include "util/text/utf8.h"
#include "Common/Common.h"
@@ -91,13 +90,13 @@ std::string D3D11VertexShader::GetShaderString(DebugShaderStringType type) const
}
ShaderManagerD3D11::ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel)
: ShaderManagerCommon(draw), device_(device), context_(context), featureLevel_(featureLevel), lastVShader_(nullptr), lastFShader_(nullptr), scalerCode_(nullptr) {
codeBuffer_ = new char[16384 * 2];
: ShaderManagerCommon(draw), device_(device), context_(context), featureLevel_(featureLevel), lastVShader_(nullptr), lastFShader_(nullptr) {
codeBuffer_ = new char[16384];
memset(&ub_base, 0, sizeof(ub_base));
memset(&ub_lights, 0, sizeof(ub_lights));
memset(&ub_bones, 0, sizeof(ub_bones));
static_assert(sizeof(ub_base) <= 512 + 16, "ub_base grew too big");
static_assert(sizeof(ub_base) <= 512, "ub_base grew too big");
static_assert(sizeof(ub_lights) <= 512, "ub_lights grew too big");
static_assert(sizeof(ub_bones) <= 384, "ub_bones grew too big");
@@ -105,7 +104,6 @@ ShaderManagerD3D11::ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *de
ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_base));
desc.ByteWidth = sizeof(ub_lights);
ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_lights));
needScalerCode = g_Config.bRealtimeTexScaling && g_Config.iTexScalingLevel != 1;
desc.ByteWidth = sizeof(ub_bones);
ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_bones));
}
@@ -136,9 +134,6 @@ void ShaderManagerD3D11::ClearShaders() {
Clear();
DirtyLastShader();
gstate_c.Dirty(DIRTY_ALL_UNIFORMS);
free(scalerCode_);
scalerCode_ = nullptr;
needScalerCode = g_Config.bRealtimeTexScaling && g_Config.iTexScalingLevel != 1;
}
void ShaderManagerD3D11::DirtyLastShader() {
@@ -225,29 +220,7 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **
D3D11FragmentShader *fs;
if (fsIter == fsCache_.end()) {
// Fragment shader not in cache. Let's compile it.
if(needScalerCode && !scalerCode_) {
static const char* filenames[] = {
"scalers/xbrz.hlsl",
"scalers/hybrid.hlsl",
"scalers/bicubic.hlsl",
"scalers/hybrid_bicubic.hlsl",
"scalers/4xbrz.hlsl",
"scalers/xbr.hlsl",
"scalers/sabr.hlsl",
"scalers/gaussian.hlsl",
"scalers/cosine.hlsl",
};
if ((g_Config.iTexScalingType < 0) || (g_Config.iTexScalingType >= sizeof(filenames) / sizeof(*filenames))) {
ERROR_LOG(G3D, "Unknown scaling type: %i", g_Config.iTexScalingType);
} else {
size_t sz;
scalerCode_ = (char *)VFSReadFile(filenames[g_Config.iTexScalingType], &sz);
if(!scalerCode_)
ERROR_LOG(G3D, "Scaler not found: %s", filenames[g_Config.iTexScalingType]);
}
needScalerCode = false;
}
GenerateFragmentShaderD3D11(FSID, codeBuffer_, scalerCode_, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11);
GenerateFragmentShaderD3D11(FSID, codeBuffer_, featureLevel_ <= D3D_FEATURE_LEVEL_9_3 ? HLSL_D3D11_LEVEL9 : HLSL_D3D11);
fs = new D3D11FragmentShader(device_, featureLevel_, FSID, codeBuffer_, useHWTransform);
fsCache_[FSID] = fs;
} else {
-2
View File
@@ -117,8 +117,6 @@ private:
VSCache vsCache_;
char *codeBuffer_;
char *scalerCode_;
bool needScalerCode;
// Uniform block scratchpad. These (the relevant ones) are copied to the current pushbuffer at draw time.
UB_VS_FS_Base ub_base;
+18 -30
View File
@@ -23,7 +23,6 @@
#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"
@@ -35,7 +34,7 @@ namespace DX9 {
// Missing: Z depth range
// Also, logic ops etc, of course, as they are not supported in DX9.
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, char* scalerCode, ShaderLanguage lang) {
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang) {
char *p = buffer;
bool lmode = id.Bit(FS_BIT_LMODE);
@@ -71,10 +70,8 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, char* scalerC
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);
@@ -152,26 +149,6 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, char* scalerC
}
WRITE(p, "};\n");
if (!isModeClear && doTexture) {
if (doTextureAlpha) {
WRITE(p, "#define BLEND_ALPHA\n");
}
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 (scalerCode && !gstate_c.curTextureIsRT) {
WRITE(p, scalerCode);
} else {
WRITE(p, "#define tex_sample(x) tex_sample_direct(x)\n");
}
}
if (lang == HLSL_DX9) {
WRITE(p, "float4 main( PS_IN In ) : COLOR {\n");
} else {
@@ -205,10 +182,7 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, char* scalerC
}
if (doTexture) {
const char *texcoord = "In.v_texcoord.xy";
if (doTextureProjection) {
texcoord = "In.v_texcoord.xy / In.v_texcoord.z";
}
const char *texcoord = "In.v_texcoord";
// 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).
@@ -238,9 +212,23 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, char* scalerC
WRITE(p, " float2 fixedcoord = float2(%s, %s);\n", ucoord.c_str(), vcoord.c_str());
texcoord = "fixedcoord";
// We already projected it.
doTextureProjection = false;
}
WRITE(p, " float4 t = tex_sample(%s);\n", texcoord);
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 p = In.v_color0;\n");
if (doTextureAlpha) { // texfmt == RGBA
+1 -3
View File
@@ -22,7 +22,7 @@
namespace DX9 {
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, char *scalerCode = nullptr, ShaderLanguage lang = HLSL_DX9);
bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang = HLSL_DX9);
#define CONST_PS_TEXENV 0
#define CONST_PS_ALPHACOLORREF 1
@@ -38,6 +38,4 @@ bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, char *scalerC
// For stencil upload
#define CONST_PS_STENCILVALUE 10
// For scaling filters
#define CONST_PS_TEXSIZE 11
};
+2 -12
View File
@@ -267,7 +267,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 | DIRTY_TEXSIZE;
const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP;
void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) {
if (dirtyUniforms & DIRTY_TEXENV) {
@@ -319,16 +319,6 @@ 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 |
@@ -519,7 +509,7 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) {
ShaderManagerDX9::ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device)
: ShaderManagerCommon(draw), device_(device), lastVShader_(nullptr), lastPShader_(nullptr) {
codeBuffer_ = new char[16384 * 2];
codeBuffer_ = new char[16384];
}
ShaderManagerDX9::~ShaderManagerDX9() {
-1
View File
@@ -1490,7 +1490,6 @@ void GPUCommon::Execute_TexSize0(u32 op, u32 diff) {
gstate_c.Dirty(DIRTY_UVSCALEOFFSET);
// We will need to reset the texture now.
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
gstate_c.Dirty(DIRTY_TEXSIZE);
}
}
-1
View File
@@ -578,7 +578,6 @@ struct GPUStateCache {
// Only applied when needShaderTexClamp = true.
u32 curTextureXOffset;
u32 curTextureYOffset;
bool curTextureIsRT;
float vpWidth;
float vpHeight;
+2 -2
View File
@@ -159,13 +159,13 @@ std::string VulkanVertexShader::GetShaderString(DebugShaderStringType type) cons
ShaderManagerVulkan::ShaderManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan)
: ShaderManagerCommon(draw), vulkan_(vulkan), lastVShader_(nullptr), lastFShader_(nullptr), fsCache_(16), vsCache_(16) {
codeBuffer_ = new char[16384 * 2];
codeBuffer_ = new char[16384];
uboAlignment_ = vulkan_->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment;
memset(&ub_base, 0, sizeof(ub_base));
memset(&ub_lights, 0, sizeof(ub_lights));
memset(&ub_bones, 0, sizeof(ub_bones));
static_assert(sizeof(ub_base) <= 512 + 16, "ub_base grew too big");
static_assert(sizeof(ub_base) <= 512, "ub_base grew too big");
static_assert(sizeof(ub_lights) <= 512, "ub_lights grew too big");
static_assert(sizeof(ub_bones) <= 384, "ub_bones grew too big");
}
@@ -28,7 +28,6 @@
#include "base/stringutil.h"
#include "Common/Vulkan/VulkanLoader.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "GPU/ge_constants.h"
#include "GPU/GPUState.h"
#include "GPU/Common/ShaderId.h"
@@ -335,7 +334,6 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
WRITE(p, " vec4 outPos = base.proj_mtx * vec4(position.xyz, 1.0);\n");
}
}
WRITE(p, " gl_Position = outPos;\n");
} else {
// Step 1: World Transform / Skinning
if (!enableBones) {
@@ -396,7 +394,6 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) {
} else {
WRITE(p, " vec4 outPos = base.proj_mtx * viewPos;\n");
}
WRITE(p, " gl_Position = outPos;\n");
// TODO: Declare variables for dots for shade mapping if needed.
+15 -31
View File
@@ -92,14 +92,10 @@ bool CheckSupportShaderTessellationGLES() {
int maxVertexTextureImageUnits = gl_extensions.maxVertexTextureUnits;
bool vertexTexture = maxVertexTextureImageUnits >= 3; // At least 3 for hardware tessellation
bool canUseInstanceID = gl_extensions.EXT_draw_instanced || gl_extensions.ARB_draw_instanced;
bool canDefInstanceID = gl_extensions.IsGLES || gl_extensions.EXT_gpu_shader4 || gl_extensions.VersionGEThan(3, 1);
bool instanceRendering = gl_extensions.GLES3 || (canUseInstanceID && canDefInstanceID);
bool textureFloat = gl_extensions.ARB_texture_float || gl_extensions.OES_texture_float;
bool hasTexelFetch = gl_extensions.GLES3 || (!gl_extensions.IsGLES && gl_extensions.VersionGEThan(3, 3, 0)) || gl_extensions.EXT_gpu_shader4;
return instanceRendering && vertexTexture && textureFloat && hasTexelFetch;
return vertexTexture && textureFloat && hasTexelFetch;
#endif
}
@@ -451,18 +447,16 @@ void GameSettingsScreen::CreateViews() {
}
return UI::EVENT_CONTINUE;
});
texScalingChoice->SetDisabledPtr(&g_Config.bSoftwareRendering);
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
texScalingChoice->SetDisabledPtr(&g_Config.bTexHardwareScaling);
}
texScalingChoice->SetEnabledFunc([] {
return !g_Config.bSoftwareRendering && (!g_Config.iGPUBackend == (int)GPUBackend::VULKAN || !g_Config.bTexHardwareScaling);
});
if (!g_Config.bSimpleUI) {
static const char *texScaleAlgos[] = { "xBRZ", "Hybrid", "Bicubic", "Hybrid + Bicubic", "4xBRZ (Realtime Scaling)", "xBR (Realtime Scaling)", "SABR (Realtime Scaling)", "Gaussian (Realtime Scaling)", "Cosine (Realtime Scaling)" };
static const char *texScaleAlgos[] = { "xBRZ", "Hybrid", "Bicubic", "Hybrid + Bicubic" };
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);
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
texScalingType->SetDisabledPtr(&g_Config.bTexHardwareScaling);
}
texScalingType->SetEnabledFunc([] {
return !g_Config.bSoftwareRendering && (!g_Config.iGPUBackend == (int)GPUBackend::VULKAN || !g_Config.bTexHardwareScaling);
});
CheckBox *deposterize = graphicsSettings->Add(new CheckBox(&g_Config.bTexDeposterize, gr->T("Deposterize")));
deposterize->OnClick.Add([=](EventParams &e) {
@@ -473,19 +467,6 @@ void GameSettingsScreen::CreateViews() {
});
deposterize->SetDisabledPtr(&g_Config.bSoftwareRendering);
if (g_Config.iGPUBackend == (int)GPUBackend::DIRECT3D11) {
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);
} else {
Choice *realtimeScaling = graphicsSettings->Add(new Choice(gr->T("Realtime Scaling requires D3D11 backend!")));
realtimeScaling->SetEnabled(false);
}
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
CheckBox* hardware4xBRZScaling = graphicsSettings->Add(new CheckBox(&g_Config.bTexHardwareScaling, gr->T("Hardware 4xBRZ Scaling(experimental)")));
hardware4xBRZScaling->OnClick.Add([=](EventParams& e) {
@@ -493,11 +474,15 @@ void GameSettingsScreen::CreateViews() {
settingInfo_->Show(gr->T("Hardware 4xBRZ Scaling Tip", "Apply 4xBRZ texture scaling filter with compute shader"), e.v);
}
return UI::EVENT_CONTINUE;
});
hardware4xBRZScaling->SetDisabledPtr(&g_Config.bSoftwareRendering);
});
hardware4xBRZScaling->SetEnabledFunc([] {
return !g_Config.bSoftwareRendering;
});
} else {
Choice* hardware4xBRZScaling = graphicsSettings->Add(new Choice(gr->T("Hardware 4xBRZ Scaling(experimental) requires Vulkan backend!")));
hardware4xBRZScaling->SetEnabled(false);
hardware4xBRZScaling->SetEnabledFunc([] {
return false;
});
}
graphicsSettings->Add(new ItemHeader(gr->T("Texture Filtering")));
static const char *anisoLevels[] = { "Off", "2x", "4x", "8x", "16x" };
@@ -1251,7 +1236,6 @@ void GameSettingsScreen::onFinish(DialogResult result) {
// Wipe some caches after potentially changing settings.
NativeMessageReceived("gpu_resized", "");
NativeMessageReceived("gpu_clearCache", "");
NativeMessageReceived("gpu_clearShaderCache", "");
}
#if PPSSPP_PLATFORM(ANDROID)
-6
View File
@@ -1119,12 +1119,6 @@ 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") {
auto sy = GetI18NCategory("System");
+2 -53
View File
@@ -337,13 +337,7 @@ namespace MainWindow {
TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID);
TranslateMenuItem(menu, ID_TEXTURESCALING_BICUBIC);
TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID_BICUBIC);
TranslateMenuItem(menu, ID_TEXTURESCALING_4XBRZ);
TranslateMenuItem(menu, ID_TEXTURESCALING_XBR);
TranslateMenuItem(menu, ID_TEXTURESCALING_SABR);
TranslateMenuItem(menu, ID_TEXTURESCALING_GAUSSIAN);
TranslateMenuItem(menu, ID_TEXTURESCALING_COSINE);
TranslateMenuItem(menu, ID_TEXTURESCALING_DEPOSTERIZE);
TranslateMenuItem(menu, ID_TEXTURESCALING_REALTIME, L"\tF5");
TranslateMenuItem(menu, ID_OPTIONS_HARDWARETRANSFORM);
TranslateMenuItem(menu, ID_OPTIONS_VERTEXCACHE);
TranslateMenuItem(menu, ID_OPTIONS_SHOWFPS);
@@ -480,10 +474,6 @@ 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) {
@@ -497,26 +487,6 @@ namespace MainWindow {
static void setTexScalingType(int type) {
g_Config.iTexScalingType = type;
NativeMessageReceived("gpu_clearCache", "");
if(g_Config.bRealtimeTexScaling) {
NativeMessageReceived("gpu_clearShaderCache", "");
}
}
static void setTexScalingMode(bool realtime) {
g_Config.bRealtimeTexScaling = realtime;
NativeMessageReceived("gpu_clearShaderCache", "");
NativeMessageReceived("gpu_clearCache", "");
std::ostringstream messageStream;
auto gr = GetI18NCategory("Graphics");
messageStream << gr->T("Texture Scaling") << ":" << " ";
if (realtime) {
messageStream << gr->T("Realtime");
} else {
messageStream << gr->T("Cached");
}
osm.Show(messageStream.str(), 3.0f);
}
static void setRenderingMode(int mode) {
@@ -810,21 +780,6 @@ 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_4XBRZ: setTexScalingType(TextureScalerCommon::_4XBRZ); break;
case ID_TEXTURESCALING_XBR: setTexScalingType(TextureScalerCommon::XBR); break;
case ID_TEXTURESCALING_SABR: setTexScalingType(TextureScalerCommon::SABR); break;
case ID_TEXTURESCALING_GAUSSIAN: setTexScalingType(TextureScalerCommon::GAUSSIAN); break;
case ID_TEXTURESCALING_COSINE: setTexScalingType(TextureScalerCommon::COSINE); break;
case ID_TEXTURESCALING_REALTIME:
setTexScalingMode(!g_Config.bRealtimeTexScaling);
break;
case ID_TEXTURESCALING_REALTIME_HC:
if (KeyMap::g_controllerMap[VIRTKEY_LOAD_STATE].empty()) {
setTexScalingMode(!g_Config.bRealtimeTexScaling);
}
break;
case ID_TEXTURESCALING_DEPOSTERIZE:
g_Config.bTexDeposterize = !g_Config.bTexDeposterize;
@@ -1152,7 +1107,6 @@ 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);
@@ -1264,17 +1218,12 @@ namespace MainWindow {
ID_TEXTURESCALING_HYBRID,
ID_TEXTURESCALING_BICUBIC,
ID_TEXTURESCALING_HYBRID_BICUBIC,
ID_TEXTURESCALING_4XBRZ,
ID_TEXTURESCALING_XBR,
ID_TEXTURESCALING_SABR,
ID_TEXTURESCALING_GAUSSIAN,
ID_TEXTURESCALING_COSINE,
};
if (g_Config.iTexScalingType < TextureScalerCommon::XBRZ)
g_Config.iTexScalingType = TextureScalerCommon::XBRZ;
else if (g_Config.iTexScalingType > TextureScalerCommon::COSINE)
g_Config.iTexScalingType = TextureScalerCommon::COSINE;
else if (g_Config.iTexScalingType > TextureScalerCommon::HYBRID_BICUBIC)
g_Config.iTexScalingType = TextureScalerCommon::HYBRID_BICUBIC;
for (int i = 0; i < ARRAY_SIZE(texscalingtypeitems); i++) {
CheckMenuItem(menu, texscalingtypeitems[i], MF_BYCOMMAND | ((i == g_Config.iTexScalingType) ? MF_CHECKED : MF_UNCHECKED));
-7
View File
@@ -77,7 +77,6 @@ BEGIN
VK_F3, ID_FILE_SAVESTATE_NEXT_SLOT_HC, VIRTKEY, NOINVERT
VK_F2, ID_FILE_QUICKSAVESTATE_HC, VIRTKEY, NOINVERT
VK_F4, ID_FILE_QUICKLOADSTATE_HC, VIRTKEY, NOINVERT
VK_F5, ID_TEXTURESCALING_REALTIME_HC, VIRTKEY, NOINVERT
"1", ID_OPTIONS_RESOLUTIONDUMMY, VIRTKEY, CONTROL, NOINVERT
VK_F7, ID_OPTIONS_FRAMESKIPDUMMY, VIRTKEY, NOINVERT
VK_F12, ID_DEBUG_TAKESCREENSHOT, VIRTKEY, NOINVERT
@@ -637,14 +636,8 @@ BEGIN
MENUITEM "Hybrid", ID_TEXTURESCALING_HYBRID
MENUITEM "Bicubic", ID_TEXTURESCALING_BICUBIC
MENUITEM "Hybrid + Bicubic", ID_TEXTURESCALING_HYBRID_BICUBIC
MENUITEM "4xBRZ(RS)", ID_TEXTURESCALING_4XBRZ
MENUITEM "xBR(RS)", ID_TEXTURESCALING_XBR
MENUITEM "SABR(RS)", ID_TEXTURESCALING_SABR
MENUITEM "Gaussian(RS)", ID_TEXTURESCALING_GAUSSIAN
MENUITEM "Cosine(RS)", ID_TEXTURESCALING_COSINE
MENUITEM "", 0, MFT_SEPARATOR
MENUITEM "Deposterize", ID_TEXTURESCALING_DEPOSTERIZE
MENUITEM "Realtime Scaling(D3D11)", ID_TEXTURESCALING_REALTIME
END
MENUITEM "Hardware Transform", ID_OPTIONS_HARDWARETRANSFORM
MENUITEM "Vertex Cache", ID_OPTIONS_VERTEXCACHE
+33 -40
View File
@@ -343,49 +343,42 @@
#define ID_OPTIONS_WINDOW9X 40175
#define ID_OPTIONS_WINDOW10X 40176
#define ID_EMULATION_PAUSE 40177
#define ID_TEXTURESCALING_REALTIME 40178
#define ID_TEXTURESCALING_REALTIME_HC 40179
#define ID_TEXTURESCALING_4XBRZ 40180
#define ID_TEXTURESCALING_XBR 40181
#define ID_TEXTURESCALING_SABR 40182
#define ID_TEXTURESCALING_GAUSSIAN 40183
#define ID_TEXTURESCALING_COSINE 40184
#define IDC_GEDBG_STEPCURVE 40185
#define ID_OPTIONS_FRAMESKIPTYPE_COUNT 40186
#define ID_OPTIONS_FRAMESKIPTYPE_PRCNT 40187
#define ID_FILE_MENU 40188
#define ID_EMULATION_MENU 40189
#define ID_DEBUG_MENU 40190
#define ID_OPTIONS_MENU 40191
#define ID_HELP_MENU 40192
#define ID_SIMPLEUI_MENU 40193
#define ID_GEDBG_REPLACEMENT_FILENAME 40194
#define ID_SIMPLEUI_TOGGLE 40195
#define ID_SIMPLEUI_HIDE 40196
#define ID_FILE_SAVESTATE_SLOT_MENU 40197
#define ID_FILE_RECORD_MENU 40198
#define ID_EMULATION_ROTATION_MENU 40199
#define ID_OPTIONS_SCREEN_MENU 40200
#define ID_OPTIONS_WINDOW_MENU 40201
#define ID_OPTIONS_BACKEND_MENU 40202
#define ID_OPTIONS_RENDERMODE_MENU 40203
#define ID_OPTIONS_FRAMESKIP_MENU 40204
#define ID_OPTIONS_FRAMESKIPTYPE_MENU 40205
#define ID_OPTIONS_TEXTUREFILTERING_MENU 40206
#define ID_OPTIONS_SCREENFILTER_MENU 40207
#define ID_OPTIONS_TEXTURESCALING_MENU 40208
#define IDC_GEDBG_STEPCOUNT 40209
#define IDC_GEDBG_STEPCOUNT_DEC 40210
#define IDC_GEDBG_STEPCOUNT_INC 40211
#define IDC_GEDBG_STEPCOUNT_JUMP 40212
#define IDC_GEDBG_STEPCOUNT_COMBO 40213
#define ID_FILE_DUMP_VIDEO_OUTPUT 40214
#define ID_EMULATION_CHAT 40215
#define ID_GEDBG_REPLACEMENT_FILENAME 40178
#define IDC_GEDBG_STEPCURVE 40179
#define ID_OPTIONS_FRAMESKIPTYPE_COUNT 40180
#define ID_OPTIONS_FRAMESKIPTYPE_PRCNT 40181
#define ID_FILE_MENU 40182
#define ID_EMULATION_MENU 40183
#define ID_DEBUG_MENU 40184
#define ID_OPTIONS_MENU 40185
#define ID_HELP_MENU 40186
#define ID_FILE_SAVESTATE_SLOT_MENU 40187
#define ID_FILE_RECORD_MENU 40188
#define ID_EMULATION_ROTATION_MENU 40189
#define ID_OPTIONS_SCREEN_MENU 40190
#define ID_OPTIONS_WINDOW_MENU 40191
#define ID_OPTIONS_BACKEND_MENU 40192
#define ID_OPTIONS_RENDERMODE_MENU 40193
#define ID_OPTIONS_FRAMESKIP_MENU 40194
#define ID_OPTIONS_FRAMESKIPTYPE_MENU 40195
#define ID_OPTIONS_TEXTUREFILTERING_MENU 40196
#define ID_OPTIONS_SCREENFILTER_MENU 40197
#define ID_OPTIONS_TEXTURESCALING_MENU 40198
#define IDC_GEDBG_STEPCOUNT 40199
#define IDC_GEDBG_STEPCOUNT_DEC 40200
#define IDC_GEDBG_STEPCOUNT_INC 40201
#define IDC_GEDBG_STEPCOUNT_JUMP 40202
#define IDC_GEDBG_STEPCOUNT_COMBO 40203
#define ID_FILE_DUMP_VIDEO_OUTPUT 40204
#define ID_EMULATION_CHAT 40205
// Dummy option to let the buffered rendering hotkey cycle through all the options.
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
#define ID_TEXTURESCALING_6X 40400
#define IDC_STEPOUT 40501
#define ID_TEXTURESCALING_6X 40502
#define ID_SIMPLEUI_MENU 40503
#define ID_SIMPLEUI_TOGGLE 40504
#define ID_SIMPLEUI_HIDE 40505
#define IDC_STATIC -1
@@ -393,7 +386,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 256
#define _APS_NEXT_COMMAND_VALUE 40216
#define _APS_NEXT_COMMAND_VALUE 40206
#define _APS_NEXT_CONTROL_VALUE 1202
#define _APS_NEXT_SYMED_VALUE 101
#endif
-343
View File
@@ -1,343 +0,0 @@
// 4xBRZ shader - Copyright (C) 2014-2016 DeSmuME team
//
// This file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the this software. If not, see <http://www.gnu.org/licenses/>.
/*
Hyllian's xBR-vertex code and texel mapping
Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifdef BLEND_ALPHA
float4 premultiply_alpha(float4 c) { float a = clamp(c.a, 0.0, 1.0); return float4(c.rgb * a, a); }
float4 postdivide_alpha(float4 c) { return c.a < 0.001f? float4(0.0f,0.0f,0.0f,0.0f) : float4(c.rgb / c.a, c.a); }
#else
#define premultiply_alpha(c) (c)
#define postdivide_alpha(c) (c)
#endif
#define BLEND_NONE 0
#define BLEND_NORMAL 1
#define BLEND_DOMINANT 2
#define LUMINANCE_WEIGHT 1.0
#define EQUAL_COLOR_TOLERANCE 30.0/255.0
#define STEEP_DIRECTION_THRESHOLD 2.2
#define DOMINANT_DIRECTION_THRESHOLD 3.6
float reduce(float4 color)
{
return dot(color.rgb, float3(65536.0, 256.0, 1.0));
}
float DistYCbCr(float4 pixA, float4 pixB)
{
const float3 w = float3(0.2627, 0.6780, 0.0593);
const float scaleB = 0.5 / (1.0 - w.b);
const float scaleR = 0.5 / (1.0 - w.r);
float4 diff = pixA - pixB;
float Y = dot(diff.rgb, w);
float Cb = scaleB * (diff.b - Y);
float Cr = scaleR * (diff.r - Y);
return sqrt( ((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr) + (diff.a * diff.a));
}
bool IsPixEqual(const float4 pixA, const float4 pixB)
{
return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE);
}
bool IsBlendingNeeded(const int4 blend)
{
return any(blend - BLEND_NONE);
}
//---------------------------------------
// Input Pixel Mapping: --|21|22|23|--
// 19|06|07|08|09
// 18|05|00|01|10
// 17|04|03|02|11
// --|15|14|13|--
//
// Output Pixel Mapping: 20|21|22|23|24|25
// 19|06|07|08|09|26
// 18|05|00|01|10|27
// 17|04|03|02|11|28
// 16|15|14|13|12|29
// 35|34|33|32|31|30
float4 tex_sample(float2 coord)
{
float dx = u_texSize.z;
float dy = u_texSize.w;
// A1 B1 C1
// A0 A B C C4
// D0 D E F F4
// G0 G H I I4
// G5 H5 I5
float4 t1 = coord.xxxy + float4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1
float4 t2 = coord.xxxy + float4( -dx, 0.0, dx, -dy); // A B C
float4 t3 = coord.xxxy + float4( -dx, 0.0, dx, 0.0); // D E F
float4 t4 = coord.xxxy + float4( -dx, 0.0, dx, dy); // G H I
float4 t5 = coord.xxxy + float4( -dx, 0.0, dx, 2.0*dy); // G5 H5 I5
float4 t6 = coord.xyyy + float4(-2.0*dx,-dy, 0.0, dy); // A0 D0 G0
float4 t7 = coord.xyyy + float4( 2.0*dx,-dy, 0.0, dy); // C4 F4 I4
float2 f = frac(coord.xy * u_texSize.xy);
//---------------------------------------
// Input Pixel Mapping: |21|22|23|
// 19|06|07|08|09
// 18|05|00|01|10
// 17|04|03|02|11
// |15|14|13|
float4 src[25];
src[21] = premultiply_alpha(tex_sample_direct(t1.xw));
src[22] = premultiply_alpha(tex_sample_direct(t1.yw));
src[23] = premultiply_alpha(tex_sample_direct(t1.zw));
src[ 6] = premultiply_alpha(tex_sample_direct(t2.xw));
src[ 7] = premultiply_alpha(tex_sample_direct(t2.yw));
src[ 8] = premultiply_alpha(tex_sample_direct(t2.zw));
src[ 5] = premultiply_alpha(tex_sample_direct(t3.xw));
src[ 0] = premultiply_alpha(tex_sample_direct(t3.yw));
src[ 1] = premultiply_alpha(tex_sample_direct(t3.zw));
src[ 4] = premultiply_alpha(tex_sample_direct(t4.xw));
src[ 3] = premultiply_alpha(tex_sample_direct(t4.yw));
src[ 2] = premultiply_alpha(tex_sample_direct(t4.zw));
src[15] = premultiply_alpha(tex_sample_direct(t5.xw));
src[14] = premultiply_alpha(tex_sample_direct(t5.yw));
src[13] = premultiply_alpha(tex_sample_direct(t5.zw));
src[19] = premultiply_alpha(tex_sample_direct(t6.xy));
src[18] = premultiply_alpha(tex_sample_direct(t6.xz));
src[17] = premultiply_alpha(tex_sample_direct(t6.xw));
src[ 9] = premultiply_alpha(tex_sample_direct(t7.xy));
src[10] = premultiply_alpha(tex_sample_direct(t7.xz));
src[11] = premultiply_alpha(tex_sample_direct(t7.xw));
float v[9];
v[0] = reduce(src[0]);
v[1] = reduce(src[1]);
v[2] = reduce(src[2]);
v[3] = reduce(src[3]);
v[4] = reduce(src[4]);
v[5] = reduce(src[5]);
v[6] = reduce(src[6]);
v[7] = reduce(src[7]);
v[8] = reduce(src[8]);
int4 blendResult = BLEND_NONE;
// Preprocess corners
// Pixel Tap Mapping: --|--|--|--|--
// --|--|07|08|--
// --|05|00|01|10
// --|04|03|02|11
// --|--|14|13|--
// Corner (1, 1)
if ( ((v[0] == v[1] && v[3] == v[2]) || (v[0] == v[3] && v[1] == v[2])) == false)
{
float dist_03_01 = DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + DistYCbCr(src[14], src[ 2]) + DistYCbCr(src[ 2], src[10]) + (4.0 * DistYCbCr(src[ 3], src[ 1]));
float dist_00_02 = DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[ 3], src[13]) + DistYCbCr(src[ 7], src[ 1]) + DistYCbCr(src[ 1], src[11]) + (4.0 * DistYCbCr(src[ 0], src[ 2]));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_03_01) < dist_00_02;
blendResult[2] = ((dist_03_01 < dist_00_02) && (v[0] != v[1]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
// Pixel Tap Mapping: --|--|--|--|--
// --|06|07|--|--
// 18|05|00|01|--
// 17|04|03|02|--
// --|15|14|--|--
// Corner (0, 1)
if ( ((v[5] == v[0] && v[4] == v[3]) || (v[5] == v[4] && v[0] == v[3])) == false)
{
float dist_04_00 = DistYCbCr(src[17], src[ 5]) + DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[15], src[ 3]) + DistYCbCr(src[ 3], src[ 1]) + (4.0 * DistYCbCr(src[ 4], src[ 0]));
float dist_05_03 = DistYCbCr(src[18], src[ 4]) + DistYCbCr(src[ 4], src[14]) + DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + (4.0 * DistYCbCr(src[ 5], src[ 3]));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_03) < dist_04_00;
blendResult[3] = ((dist_04_00 > dist_05_03) && (v[0] != v[5]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
// Pixel Tap Mapping: --|--|22|23|--
// --|06|07|08|09
// --|05|00|01|10
// --|--|03|02|--
// --|--|--|--|--
// Corner (1, 0)
if ( ((v[7] == v[8] && v[0] == v[1]) || (v[7] == v[0] && v[8] == v[1])) == false)
{
float dist_00_08 = DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[ 7], src[23]) + DistYCbCr(src[ 3], src[ 1]) + DistYCbCr(src[ 1], src[ 9]) + (4.0 * DistYCbCr(src[ 0], src[ 8]));
float dist_07_01 = DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + DistYCbCr(src[22], src[ 8]) + DistYCbCr(src[ 8], src[10]) + (4.0 * DistYCbCr(src[ 7], src[ 1]));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_07_01) < dist_00_08;
blendResult[1] = ((dist_00_08 > dist_07_01) && (v[0] != v[7]) && (v[0] != v[1])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
// Pixel Tap Mapping: --|21|22|--|--
// 19|06|07|08|--
// 18|05|00|01|--
// --|04|03|--|--
// --|--|--|--|--
// Corner (0, 0)
if ( ((v[6] == v[7] && v[5] == v[0]) || (v[6] == v[5] && v[7] == v[0])) == false)
{
float dist_05_07 = DistYCbCr(src[18], src[ 6]) + DistYCbCr(src[ 6], src[22]) + DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + (4.0 * DistYCbCr(src[ 5], src[ 7]));
float dist_06_00 = DistYCbCr(src[19], src[ 5]) + DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[21], src[ 7]) + DistYCbCr(src[ 7], src[ 1]) + (4.0 * DistYCbCr(src[ 6], src[ 0]));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_07) < dist_06_00;
blendResult[0] = ((dist_05_07 < dist_06_00) && (v[0] != v[5]) && (v[0] != v[7])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
float4 dst[16];
dst[ 0] = src[0];
dst[ 1] = src[0];
dst[ 2] = src[0];
dst[ 3] = src[0];
dst[ 4] = src[0];
dst[ 5] = src[0];
dst[ 6] = src[0];
dst[ 7] = src[0];
dst[ 8] = src[0];
dst[ 9] = src[0];
dst[10] = src[0];
dst[11] = src[0];
dst[12] = src[0];
dst[13] = src[0];
dst[14] = src[0];
dst[15] = src[0];
// Scale pixel
if (IsBlendingNeeded(blendResult) == true)
{
float dist_01_04 = DistYCbCr(src[1], src[4]);
float dist_03_08 = DistYCbCr(src[3], src[8]);
bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[4]) && (v[5] != v[4]);
bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[8]) && (v[7] != v[8]);
bool needBlend = (blendResult[2] != BLEND_NONE);
bool doLineBlend = ( blendResult[2] >= BLEND_DOMINANT ||
((blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) ||
(blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) ||
(IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[0], src[2]) == false) ) == false );
float4 blendPix = ( DistYCbCr(src[0], src[1]) <= DistYCbCr(src[0], src[3]) ) ? src[1] : src[3];
dst[ 2] = lerp(dst[ 2], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00);
dst[ 9] = lerp(dst[ 9], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00);
dst[10] = lerp(dst[10], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00);
dst[11] = lerp(dst[11], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[12] = lerp(dst[12], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00);
dst[13] = lerp(dst[13], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[14] = lerp(dst[14], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00);
dst[15] = lerp(dst[15], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00);
dist_01_04 = DistYCbCr(src[7], src[2]);
dist_03_08 = DistYCbCr(src[1], src[6]);
haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[2]) && (v[3] != v[2]);
haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[6]) && (v[5] != v[6]);
needBlend = (blendResult[1] != BLEND_NONE);
doLineBlend = ( blendResult[1] >= BLEND_DOMINANT ||
!((blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) ||
(blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) ||
(IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && !IsPixEqual(src[0], src[8])) ) );
blendPix = ( DistYCbCr(src[0], src[7]) <= DistYCbCr(src[0], src[1]) ) ? src[7] : src[1];
dst[ 1] = lerp(dst[ 1], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00);
dst[ 6] = lerp(dst[ 6], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00);
dst[ 7] = lerp(dst[ 7], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00);
dst[ 8] = lerp(dst[ 8], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[ 9] = lerp(dst[ 9], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00);
dst[10] = lerp(dst[10], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[11] = lerp(dst[11], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00);
dst[12] = lerp(dst[12], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00);
dist_01_04 = DistYCbCr(src[5], src[8]);
dist_03_08 = DistYCbCr(src[7], src[4]);
haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[8]) && (v[1] != v[8]);
haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[4]) && (v[3] != v[4]);
needBlend = (blendResult[0] != BLEND_NONE);
doLineBlend = ( blendResult[0] >= BLEND_DOMINANT ||
!((blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) ||
(blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) ||
(IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && !IsPixEqual(src[0], src[6])) ) );
blendPix = ( DistYCbCr(src[0], src[5]) <= DistYCbCr(src[0], src[7]) ) ? src[5] : src[7];
dst[ 0] = lerp(dst[ 0], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00);
dst[15] = lerp(dst[15], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00);
dst[ 4] = lerp(dst[ 4], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00);
dst[ 5] = lerp(dst[ 5], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[ 6] = lerp(dst[ 6], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00);
dst[ 7] = lerp(dst[ 7], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[ 8] = lerp(dst[ 8], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00);
dst[ 9] = lerp(dst[ 9], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00);
dist_01_04 = DistYCbCr(src[3], src[6]);
dist_03_08 = DistYCbCr(src[5], src[2]);
haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[6]) && (v[7] != v[6]);
haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[2]) && (v[1] != v[2]);
needBlend = (blendResult[3] != BLEND_NONE);
doLineBlend = ( blendResult[3] >= BLEND_DOMINANT ||
!((blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) ||
(blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) ||
(IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && !IsPixEqual(src[0], src[4])) ) );
blendPix = ( DistYCbCr(src[0], src[3]) <= DistYCbCr(src[0], src[5]) ) ? src[3] : src[5];
dst[ 3] = lerp(dst[ 3], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00);
dst[12] = lerp(dst[12], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00);
dst[13] = lerp(dst[13], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00);
dst[14] = lerp(dst[14], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[15] = lerp(dst[15], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00);
dst[ 4] = lerp(dst[ 4], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00);
dst[ 5] = lerp(dst[ 5], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00);
dst[ 6] = lerp(dst[ 6], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00);
}
// select output pixel
float4 res = lerp(lerp(lerp(lerp(dst[ 6], dst[ 7], step(0.25, f.x)),
lerp(dst[ 8], dst[ 9], step(0.75, f.x)),
step(0.50, f.x)),
lerp(lerp(dst[ 5], dst[ 0], step(0.25, f.x)),
lerp(dst[ 1], dst[10], step(0.75, f.x)),
step(0.50, f.x)),
step(0.25, f.y)),
lerp(lerp(lerp(dst[ 4], dst[ 3], step(0.25, f.x)),
lerp(dst[ 2], dst[11], step(0.75, f.x)),
step(0.50, f.x)),
lerp(lerp(dst[15], dst[14], step(0.25, f.x)),
lerp(dst[13], dst[12], step(0.75, f.x)),
step(0.50, f.x)),
step(0.75, f.y)),
step(0.50, f.y));
return postdivide_alpha(res);
};
-57
View File
@@ -1,57 +0,0 @@
#ifdef BLEND_ALPHA
float4 premultiply_alpha(float4 c) { float a = clamp(c.a, 0.0, 1.0); return float4(c.rgb * a, a); }
float4 postdivide_alpha(float4 c) { return c.a < 0.001f? float4(0.0f,0.0f,0.0f,0.0f) : float4(c.rgb / c.a, c.a); }
#else
#define premultiply_alpha(c) (c)
#define postdivide_alpha(c) (c)
#endif
// generate the value of a Mitchell-Netravali scaling spline at distance d, with parameters A and B
// B=1 C=0 : cubic B spline (very smooth)
// B=C=1/3 : recommended for general upscaling
// B=0 C=1/2 : Catmull-Rom spline (sharp, ringing)
// see Mitchell & Netravali, \Reconstruction Filters in Computer Graphics\
//#define BSPLINE
#ifdef BSPLINE
static const float B = 1.0f;
static const float C = 0.0f;
#else
static const float B = 1.0f / 3.0f;
static const float C = 1.0f / 3.0f;
#endif
float mitchell_0_1(float x) {
return ((12 - 9 * B - 6 * C)*(x*x*x) + (-18 + 12 * B + 6 * C)*(x*x) + (6 - 2 * B)) / 6.0f;
}
float mitchell_1_2(float x) {
return ((-B - 6 * C)*(x*x*x) + (6 * B + 30 * C)*(x*x) + (-12 * B - 48 * C)*x + (8 * B + 24 * C)) / 6.0f;
}
float mitchell(float2 pos) {
float x = sqrt(dot(pos, pos));
// return lerp(mitchell_0_1(x), mitchell_1_2(x), step(1.0,x)) * step(x, 2.0);
if (x < 1.0)
return mitchell_0_1(x);
if (x < 2.0)
return mitchell_1_2(x);
return 0.0;
}
float4 tex_sample(float2 coord) {
float2 offset = frac(coord * u_texSize.xy) - 0.5;
float4 tempColor = 0.0;
float4 c;
float i,j;
float2 pos;
for (i = -2.0; i < 3.0; i++){
pos.x = offset.x - i;
for (j = -2.0; j < 3.0 ;j++){
pos.y = offset.y - j;
c=premultiply_alpha(tex_sample_direct(coord - pos * u_texSize.zw));
tempColor+=c*mitchell(pos);
}
}
return postdivide_alpha(tempColor);
}
-31
View File
@@ -1,31 +0,0 @@
#ifdef BLEND_ALPHA
float4 premultiply_alpha(float4 c) { float a = clamp(c.a, 0.0, 1.0); return float4(c.rgb * a, a); }
float4 postdivide_alpha(float4 c) { return c.a < 0.001f? float4(0.0f,0.0f,0.0f,0.0f) : float4(c.rgb / c.a, c.a); }
#else
#define premultiply_alpha(c) (c)
#define postdivide_alpha(c) (c)
#endif
#define sharpness 1.0
#define pi 3.14159265358
#define a(x) abs(x)
#define d(x,b) (pi*b*min(a(x)+0.5,1.0/b))
#define e(x,b) (pi*b*min(max(a(x)-0.5,-1.0/b),1.0/b))
#define KERNEL(x,b) ((d(x,b)+sin(d(x,b))-e(x,b)-sin(e(x,b)))/(2.0*pi))
float4 tex_sample(float2 coord) {
float2 offset = frac(coord * u_texSize.xy) - 0.5;
float4 tempColor = 0.0;
float4 c;
float i,j;
float2 pos;
for (i = -2.0; i < 2.0; i++){
pos.x = offset.x - i;
for (j = -2.0; j< 2.0 ;j++){
pos.y = offset.y - j;
c=premultiply_alpha(tex_sample_direct(coord - pos * u_texSize.zw));
tempColor+=c*KERNEL(pos.x,sharpness)*KERNEL(pos.y,sharpness);
}
}
return postdivide_alpha(tempColor);
}
-40
View File
@@ -1,40 +0,0 @@
#ifdef BLEND_ALPHA
float4 premultiply_alpha(float4 c) { float a = clamp(c.a, 0.0, 1.0); return float4(c.rgb * a, a); }
float4 postdivide_alpha(float4 c) { return c.a < 0.001f? float4(0.0f,0.0f,0.0f,0.0f) : float4(c.rgb / c.a, c.a); }
#else
#define premultiply_alpha(c) (c)
#define postdivide_alpha(c) (c)
#endif
#define sharpness 1.0
#define pi 3.14159265358
#define normalGauss(x) ((exp(-(x)*(x)*0.5))/sqrt(2.0*pi))
#define normalGauss2(x) (normalGauss(x - 0.5) - 0.5)
float normalGaussIntegral(float x)
{
float a1 = 0.4361836;
float a2 = -0.1201676;
float a3 = 0.9372980;
float p = 0.3326700;
float t = 1.0 / (1.0 + p*abs(x));
return (0.5-normalGauss(x) * (t*(a1 + t*(a2 + a3*t))))*sign(x);
}
#define KERNEL(x,b) (normalGaussIntegral(sqrt(2*pi)*b*(x - 0.5)) - normalGaussIntegral(sqrt(2*pi)*b*(x + 0.5)))
float4 tex_sample(float2 coord) {
float2 offset = frac(coord * u_texSize.xy) - 0.5;
float4 tempColor = 0.0;
float4 c;
float i,j;
float2 pos;
for (i = -2.0; i < 2.0; i++){
pos.x = offset.x - i;
for (j = -2.0; j< 2.0 ;j++){
pos.y = offset.y - j;
c=premultiply_alpha(tex_sample_direct(coord - pos * u_texSize.zw));
tempColor+=c*KERNEL(pos.x,sharpness)*KERNEL(pos.y,sharpness);
}
}
return postdivide_alpha(tempColor);
}
-4
View File
@@ -1,4 +0,0 @@
float4 tex_sample(float2 coord) {
return tex_sample_direct(coord);
};
-4
View File
@@ -1,4 +0,0 @@
float4 tex_sample(float2 coord) {
return tex_sample_direct(coord);
};
-71
View File
@@ -1,71 +0,0 @@
#ifdef BLEND_ALPHA
float4 premultiply_alpha(float4 c) { float a = clamp(c.a, 0.0, 1.0); return float4(c.rgb * a, a); }
float4 postdivide_alpha(float4 c) { return c.a < 0.001f? float4(0.0f,0.0f,0.0f,0.0f) : float4(c.rgb / c.a, c.a); }
#else
#define premultiply_alpha(c) (c)
#define postdivide_alpha(c) (c)
#endif
float c_df(float4 c1, float4 c2) {
float3 df = abs(c1.rgb - c2.rgb);
return df.r + df.g + df.b;
}
static const float4 Ai = float4( 1.0, -1.0, -1.0, 1.0);
static const float4 B45 = float4( 1.0, 1.0, -1.0, -1.0);
static const float4 C45 = float4( 1.5, 0.5, -0.5, 0.5);
static const float4 M45 = float4(0.4, 0.4, 0.4, 0.4);
static const float4 M30 = float4(0.2, 0.4, 0.2, 0.4);
static const float3 lum = float3(0.21, 0.72, 0.07);
float lum_to(float4 v) {
return dot(lum, v.rgb);
}
float4 lum_to(float4 v0, float4 v1, float4 v2, float4 v3) {
return float4(lum_to(v0), lum_to(v1), lum_to(v2), lum_to(v3));
}
float4 tex_sample(float2 coord)
{
/*
Mask for algorithm
+-----+-----+-----+
| | 7 | |
+-----+-----+-----+
| 11 | 12 | 13 |
+-----+-----+-----+
| | 17 | |
+-----+-----+-----+
*/
// Store mask values
float4 P07 = premultiply_alpha(tex_sample_direct(coord + u_texSize.zw * float2( 0.0, -1.0)));
float4 P11 = premultiply_alpha(tex_sample_direct(coord + u_texSize.zw * float2(-1.0, 0.0)));
float4 P12 = premultiply_alpha(tex_sample_direct(coord + u_texSize.zw * float2( 0.0, 0.0)));
float4 P13 = premultiply_alpha(tex_sample_direct(coord + u_texSize.zw * float2( 1.0, 0.0)));
float4 P17 = premultiply_alpha(tex_sample_direct(coord + u_texSize.zw * float2( 0.0, 1.0)));
// Store luminance values of each point
float4 p7 = lum_to(P07, P11, P17, P13);
float4 p12 = lum_to(P12);
float4 p13 = p7.wxyz; // P13, P7, P11, P17
float4 p17 = p7.zwxy; // P11, P17, P13, P7
float2 fp = frac(coord * u_texSize.xy);
float4 ma45 = smoothstep(C45 - M45, C45 + M45, Ai * fp.y + B45 * fp.x);
float4 px = step(abs(p12 - p17), abs(p12 - p13));
float4 res1 = P12;
res1 = lerp(res1, lerp(P13, P17, px.x), ma45.x);
res1 = lerp(res1, lerp(P07, P13, px.y), ma45.y);
res1 = lerp(res1, lerp(P11, P07, px.z), ma45.z);
res1 = lerp(res1, lerp(P17, P11, px.w), ma45.w);
float4 res2 = P12;
res2 = lerp(res2, lerp(P17, P11, px.w), ma45.w);
res2 = lerp(res2, lerp(P11, P07, px.z), ma45.z);
res2 = lerp(res2, lerp(P07, P13, px.y), ma45.y);
res2 = lerp(res2, lerp(P13, P17, px.x), ma45.x);
float4 res = lerp(res1, res2, step(c_df(P12, res1), c_df(P12, res2)));
return postdivide_alpha(res);
}
-218
View File
@@ -1,218 +0,0 @@
/*
Hyllian's xBR-lv2 Shader
Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Incorporates some of the ideas from SABR shader. Thanks to Joshua Street.
*/
#ifdef BLEND_ALPHA
float4 premultiply_alpha(float4 c) { float a = clamp(c.a, 0.0, 1.0); return float4(c.rgb * a, a); }
float4 postdivide_alpha(float4 c) { return c.a < 0.001f? float4(0.0f,0.0f,0.0f,0.0f) : float4(c.rgb / c.a, c.a); }
#else
#define premultiply_alpha(c) (c)
#define postdivide_alpha(c) (c)
#endif
#define XBR_Y_WEIGHT 48.0 // 0.0 .. 100.0
#define XBR_EQ_THRESHOLD 15.0 // 0.0 .. 50.0
#define XBR_LV1_COEFFICIENT 0.5 // 0.0 .. 30.0
#define XBR_LV2_COEFFICIENT 2.0 // 1.0 .. 3.0
//#define SMALL_DETAILS
#define CORNER_TYPE 3 // 1 .. 4
#define XBR_SCALE 4.0
static const float coef = 2.0;
static const float4 rgbw = float4(14.352, 28.176, 5.472, 50);
static const float4 eq_threshold = float4(15.0, 15.0, 15.0, 15.0);
static const float4 delta = float4(1.0/XBR_SCALE, 1.0/XBR_SCALE, 1.0/XBR_SCALE, 1.0/XBR_SCALE);
static const float4 delta_l = float4(0.5/XBR_SCALE, 1.0/XBR_SCALE, 0.5/XBR_SCALE, 1.0/XBR_SCALE);
static const float4 delta_u = delta_l.yxwz;
static const float4 Ao = float4( 1.0, -1.0, -1.0, 1.0 );
static const float4 Bo = float4( 1.0, 1.0, -1.0,-1.0 );
static const float4 Co = float4( 1.5, 0.5, -0.5, 0.5 );
static const float4 Ax = float4( 1.0, -1.0, -1.0, 1.0 );
static const float4 Bx = float4( 0.5, 2.0, -0.5,-2.0 );
static const float4 Cx = float4( 1.0, 1.0, -0.5, 0.0 );
static const float4 Ay = float4( 1.0, -1.0, -1.0, 1.0 );
static const float4 By = float4( 2.0, 0.5, -2.0,-0.5 );
static const float4 Cy = float4( 2.0, 0.0, -1.0, 0.5 );
static const float4 Ci = float4(0.25, 0.25, 0.25, 0.25);
static const float4 Y = float4(0.2126, 0.7152, 0.0722, 1.0);
// Difference between vector components.
float4 df(float4 A, float4 B) { return abs(A-B); }
// Compare two vectors and return their components are different.
float4 diff(float4 A, float4 B) { return step(0.001, df(A, B)); }
// Determine if two vector components are equal based on a threshold.
float4 eq(float4 A, float4 B) { return (step(df(A, B), XBR_EQ_THRESHOLD)); }
// Determine if two vector components are NOT equal based on a threshold.
float4 neq(float4 A, float4 B) { return (1.0 - eq(A, B)); }
// Weighted distance.
float4 wd(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h) {
return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
}
float4 weighted_distance(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h, float4 i, float4 j, float4 k, float4 l) {
return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + df(i,j) + df(k,l) + 2.0*df(g,h));
}
float c_df(float4 c1, float4 c2) {
float4 df = abs(c1 - c2);
return df.r + df.g + df.b + df.a;
}
float4 tex_sample(float2 coord) {
float dx = u_texSize.z;
float dy = u_texSize.w;
float4 t1 = coord.xxxy + float4( -dx, 0, dx,-2.0*dy); // A1 B1 C1
float4 t2 = coord.xxxy + float4( -dx, 0, dx, -dy); // A B C
float4 t3 = coord.xxxy + float4( -dx, 0, dx, 0); // D E F
float4 t4 = coord.xxxy + float4( -dx, 0, dx, dy); // G H I
float4 t5 = coord.xxxy + float4( -dx, 0, dx, 2.0*dy); // G5 H5 I5
float4 t6 = coord.xyyy + float4(-2.0*dx,-dy, 0, dy); // A0 D0 G0
float4 t7 = coord.xyyy + float4( 2.0*dx,-dy, 0, dy); // C4 F4 I4
float4 edri, edr, edr_l, edr_u, px; // px = pixel, edr = edge detection rule
float4 irlv0, irlv1, irlv2l, irlv2u, block_3d;
float4 fx, fx_l, fx_u; // inequations of straight lines.
float2 fp = frac(coord*u_texSize.xy);
float4 A1 = tex_sample_direct(t1.xw);
float4 B1 = tex_sample_direct(t1.yw);
float4 C1 = tex_sample_direct(t1.zw);
float4 A = tex_sample_direct(t2.xw);
float4 B = tex_sample_direct(t2.yw);
float4 C = tex_sample_direct(t2.zw);
float4 D = tex_sample_direct(t3.xw);
float4 E = tex_sample_direct(t3.yw);
float4 F = tex_sample_direct(t3.zw);
float4 G = tex_sample_direct(t4.xw);
float4 H = tex_sample_direct(t4.yw);
float4 I = tex_sample_direct(t4.zw);
float4 G5 = tex_sample_direct(t5.xw);
float4 H5 = tex_sample_direct(t5.yw);
float4 I5 = tex_sample_direct(t5.zw);
float4 A0 = tex_sample_direct(t6.xy);
float4 D0 = tex_sample_direct(t6.xz);
float4 G0 = tex_sample_direct(t6.xw);
float4 C4 = tex_sample_direct(t7.xy);
float4 F4 = tex_sample_direct(t7.xz);
float4 I4 = tex_sample_direct(t7.xw);
float4 b = float4(dot(B, rgbw), dot(D, rgbw), dot(H, rgbw), dot(F, rgbw));
float4 c = float4(dot(C, rgbw), dot(A, rgbw), dot(G, rgbw), dot(I, rgbw));
float4 d = b.yzwx;
float4 e = dot(E, rgbw);
float4 f = b.wxyz;
float4 g = c.zwxy;
float4 h = b.zwxy;
float4 i = c.wxyz;
float4 i4, i5, h5, f4;
float y_weight = XBR_Y_WEIGHT;
#ifdef SMALL_DETAILS
i4 = mul(float4x4(I4, C1, A0, G5), y_weight * Y);
i5 = mul(float4x4(I5, C4, A1, G0), y_weight * Y);
h5 = mul(float4x4(H5, F4, B1, D0), y_weight * Y);
#else
i4 = float4(dot(I4,rgbw), dot(C1,rgbw), dot(A0,rgbw), dot(G5,rgbw));
i5 = float4(dot(I5,rgbw), dot(C4,rgbw), dot(A1,rgbw), dot(G0,rgbw));
h5 = float4(dot(H5,rgbw), dot(F4,rgbw), dot(B1,rgbw), dot(D0,rgbw));
#endif
f4 = h5.yzwx;
// These inequations define the line below which interpolation occurs.
fx = (Ao*fp.y+Bo*fp.x);
fx_l = (Ax*fp.y+Bx*fp.x);
fx_u = (Ay*fp.y+By*fp.x);
irlv1 = irlv0 = diff(e,f) * diff(e,h);
#if CORNER_TYPE == 1
#define SMOOTH_TIPS
#elif CORNER_TYPE == 2
irlv1 = (irlv0 * ( neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c) ) );
#elif CORNER_TYPE == 3
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)) );
#else // CORNER_TYPE == 4
float4 c1 = i4.yzwx;
float4 g0 = i5.wxyz;
irlv1 = (irlv0 * ( neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c) ) * (diff(f,f4) * diff(f,i) + diff(h,h5) * diff(h,i) + diff(h,g) + diff(f,c) + eq(b,c1) * eq(d,g0)));
#endif
irlv2l = diff(e,g) * diff(d,g);
irlv2u = diff(e,c) * diff(b,c);
float4 fx45i = clamp((fx + delta -Co - Ci)/(2.0*delta ), 0.0, 1.0);
float4 fx45 = clamp((fx + delta -Co )/(2.0*delta ), 0.0, 1.0);
float4 fx30 = clamp((fx_l + delta_l -Cx )/(2.0*delta_l), 0.0, 1.0);
float4 fx60 = clamp((fx_u + delta_u -Cy )/(2.0*delta_u), 0.0, 1.0);
float4 wd1, wd2;
#ifdef SMALL_DETAILS
wd1 = weighted_distance( e, c, g, i, f4, h5, h, f, b, d, i4, i5);
wd2 = weighted_distance( h, d, i5, f, b, i4, e, i, g, h5, c, f4);
#else
wd1 = wd( e, c, g, i, h5, f4, h, f);
wd2 = wd( h, d, i5, f, i4, b, e, i);
#endif
edri = step(wd1, wd2) * irlv0;
edr = step(wd1 + float4(0.1, 0.1, 0.1, 0.1), wd2) * step(float4(0.5, 0.5, 0.5, 0.5), irlv1);
edr_l = step( XBR_LV2_COEFFICIENT*df(f,g), df(h,c) ) * irlv2l * edr;
edr_u = step( XBR_LV2_COEFFICIENT*df(h,c), df(f,g) ) * irlv2u * edr;
fx45 = edr * fx45;
fx30 = edr_l * fx30;
fx60 = edr_u * fx60;
fx45i = edri * fx45i;
px = step(df(e,f), df(e,h));
#ifdef SMOOTH_TIPS
float4 maximos = max(max(fx30, fx60), max(fx45, fx45i));
#else
float4 maximos = max(max(fx30, fx60), fx45);
#endif
float4 res1 = premultiply_alpha(E);
res1 = lerp(res1, premultiply_alpha(lerp(H, F, px.x)), maximos.x);
res1 = lerp(res1, premultiply_alpha(lerp(B, D, px.z)), maximos.z);
float4 res2 = premultiply_alpha(E);
res2 = lerp(res2, premultiply_alpha(lerp(F, B, px.y)), maximos.y);
res2 = lerp(res2, premultiply_alpha(lerp(D, H, px.w)), maximos.w);
float4 res = lerp(res1, res2, step(c_df(E, res1), c_df(E, res2)));
return postdivide_alpha(res);
}
-300
View File
@@ -1,300 +0,0 @@
// xBRZ-freescale
// based on :
// 4xBRZ shader - Copyright (C) 2014-2016 DeSmuME team
//
// This file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the this software. If not, see <http://www.gnu.org/licenses/>.
/*
Hyllian's xBR-vertex code and texel mapping
Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#define BLEND_NONE 0
#define BLEND_NORMAL 1
#define BLEND_DOMINANT 2
#define LUMINANCE_WEIGHT 1.0
#define EQUAL_COLOR_TOLERANCE 30.0/255.0
#define STEEP_DIRECTION_THRESHOLD 2.2
#define DOMINANT_DIRECTION_THRESHOLD 3.6
#define BLEND_ALPHA
#ifdef BLEND_ALPHA
// TODO: check why the [0.0,1.0] clamp is necessary here
float4 premultiply_alpha(float4 c) { float a = clamp(c.a, 0.0, 1.0); return float4(c.rgb * a, a); }
float4 postdivide_alpha(float4 c) { return c.a < 0.001f? float4(0.0f,0.0f,0.0f,0.0f) : float4(c.rgb / c.a, c.a); }
#define eq(a,b) all(a == b)
#define neq(a,b) any(a != b)
#else
#define premultiply_alpha(c) (c)
#define postdivide_alpha(c) (c)
#define eq(a,b) all(a.rgb == b.rgb)
#define neq(a,b) any(a.rgb != b.rgb)
#endif
#define P(x,y) tex_sample_direct(coord + u_texSize.zw * float2(x, y))
float DistYCbCr(float4 pixA, float4 pixB)
{
const float3 w = float3(0.2627, 0.6780, 0.0593);
const float scaleB = 0.5 / (1.0 - w.b);
const float scaleR = 0.5 / (1.0 - w.r);
float4 diff = pixA - pixB;
float Y = dot(diff.rgb, w);
float Cb = scaleB * (diff.b - Y);
float Cr = scaleR * (diff.r - Y);
#ifdef BLEND_ALPHA
return sqrt(((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr) + (diff.a * diff.a));
#else
return sqrt(((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr));
#endif
}
bool IsPixEqual(const float4 pixA, const float4 pixB)
{
return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE);
}
float get_left_ratio(float2 center, float2 origin, float2 direction, float2 scale)
{
float2 P0 = center - origin;
float2 proj = direction * (dot(P0, direction) / dot(direction, direction));
float2 distv = P0 - proj;
float2 orth = float2(-direction.y, direction.x);
float side = sign(dot(P0, orth));
float v = side * length(distv * scale);
// return step(0, v);
return smoothstep(-sqrt(2.0)/2.0, sqrt(2.0)/2.0, v);
}
float4 tex_sample(float2 coord) {
//---------------------------------------
// Input Pixel Mapping: -|x|x|x|-
// x|A|B|C|x
// x|D|E|F|x
// x|G|H|I|x
// -|x|x|x|-
float2 scale = u_texSize.zw / float2(ddx(coord.x), ddy(coord.y));
float2 pos = frac(coord * u_texSize.xy) - float2(0.5, 0.5);
float4 A = P(-1,-1);
float4 B = P( 0,-1);
float4 C = P( 1,-1);
float4 D = P(-1, 0);
float4 E = P( 0, 0);
float4 F = P( 1, 0);
float4 G = P(-1, 1);
float4 H = P( 0, 1);
float4 I = P( 1, 1);
// blendResult Mapping: x|y|
// w|z|
int4 blendResult = int4(BLEND_NONE,BLEND_NONE,BLEND_NONE,BLEND_NONE);
// Preprocess corners
// Pixel Tap Mapping: -|-|-|-|-
// -|-|B|C|-
// -|D|E|F|x
// -|G|H|I|x
// -|-|x|x|-
if (!((eq(E,F) && eq(H,I)) || (eq(E,H) && eq(F,I))))
{
float dist_H_F = DistYCbCr(G, E) + DistYCbCr(E, C) + DistYCbCr(P(0,2), I) + DistYCbCr(I, P(2,0)) + (4.0 * DistYCbCr(H, F));
float dist_E_I = DistYCbCr(D, H) + DistYCbCr(H, P(1,2)) + DistYCbCr(B, F) + DistYCbCr(F, P(2,1)) + (4.0 * DistYCbCr(E, I));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_H_F) < dist_E_I;
blendResult.z = ((dist_H_F < dist_E_I) && neq(E,F) && neq(E,H)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
// Pixel Tap Mapping: -|-|-|-|-
// -|A|B|-|-
// x|D|E|F|-
// x|G|H|I|-
// -|x|x|-|-
if (!((eq(D,E) && eq(G,H)) || (eq(D,G) && eq(E,H))))
{
float dist_G_E = DistYCbCr(P(-2,1) , D) + DistYCbCr(D, B) + DistYCbCr(P(-1,2), H) + DistYCbCr(H, F) + (4.0 * DistYCbCr(G, E));
float dist_D_H = DistYCbCr(P(-2,0) , G) + DistYCbCr(G, P(0,2)) + DistYCbCr(A, E) + DistYCbCr(E, I) + (4.0 * DistYCbCr(D, H));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_D_H) < dist_G_E;
blendResult.w = ((dist_G_E > dist_D_H) && neq(E,D) && neq(E,H)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
// Pixel Tap Mapping: -|-|x|x|-
// -|A|B|C|x
// -|D|E|F|x
// -|-|H|I|-
// -|-|-|-|-
if (!((eq(B,C) && eq(E,F)) || (eq(B,E) && eq(C,F))))
{
float dist_E_C = DistYCbCr(D, B) + DistYCbCr(B, P(1,-2)) + DistYCbCr(H, F) + DistYCbCr(F, P(2,-1)) + (4.0 * DistYCbCr(E, C));
float dist_B_F = DistYCbCr(A, E) + DistYCbCr(E, I) + DistYCbCr(P(0,-2), C) + DistYCbCr(C, P(2,0)) + (4.0 * DistYCbCr(B, F));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_B_F) < dist_E_C;
blendResult.y = ((dist_E_C > dist_B_F) && neq(E,B) && neq(E,F)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
// Pixel Tap Mapping: -|x|x|-|-
// x|A|B|C|-
// x|D|E|F|-
// -|G|H|-|-
// -|-|-|-|-
if (!((eq(A,B) && eq(D,E)) || (eq(A,D) && eq(B,E))))
{
float dist_D_B = DistYCbCr(P(-2,0), A) + DistYCbCr(A, P(0,-2)) + DistYCbCr(G, E) + DistYCbCr(E, C) + (4.0 * DistYCbCr(D, B));
float dist_A_E = DistYCbCr(P(-2,-1), D) + DistYCbCr(D, H) + DistYCbCr(P(-1,-2), B) + DistYCbCr(B, F) + (4.0 * DistYCbCr(A, E));
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_D_B) < dist_A_E;
blendResult.x = ((dist_D_B < dist_A_E) && neq(E,D) && neq(E,B)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
}
float4 res = premultiply_alpha(E);
// Pixel Tap Mapping: -|-|-|-|-
// -|-|B|C|-
// -|D|E|F|x
// -|G|H|I|x
// -|-|x|x|-
if(blendResult.z != BLEND_NONE)
{
float dist_F_G = DistYCbCr(F, G);
float dist_H_C = DistYCbCr(H, C);
bool doLineBlend = (blendResult.z == BLEND_DOMINANT ||
!((blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) || (blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) ||
(IsPixEqual(G, H) && IsPixEqual(H, I) && IsPixEqual(I, F) && IsPixEqual(F, C) && !IsPixEqual(E, I))));
float2 origin = float2(0.0, 1.0 / sqrt(2.0));
float2 direction = float2(1.0, -1.0);
if(doLineBlend)
{
bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_F_G <= dist_H_C) && neq(E,G) && neq(D,G);
bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_H_C <= dist_F_G) && neq(E,C) && neq(B,C);
origin = haveShallowLine? float2(0.0, 0.25) : float2(0.0, 0.5);
direction.x += haveShallowLine? 1.0: 0.0;
direction.y -= haveSteepLine? 1.0: 0.0;
}
float4 blendPix = premultiply_alpha(lerp(H,F, step(DistYCbCr(E, F), DistYCbCr(E, H))));
res = lerp(res, blendPix, get_left_ratio(pos, origin, direction, scale));
}
// Pixel Tap Mapping: -|-|-|-|-
// -|A|B|-|-
// x|D|E|F|-
// x|G|H|I|-
// -|x|x|-|-
if(blendResult.w != BLEND_NONE)
{
float dist_H_A = DistYCbCr(H, A);
float dist_D_I = DistYCbCr(D, I);
bool doLineBlend = (blendResult.w == BLEND_DOMINANT ||
!((blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) || (blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) ||
(IsPixEqual(A, D) && IsPixEqual(D, G) && IsPixEqual(G, H) && IsPixEqual(H, I) && !IsPixEqual(E, G))));
float2 origin = float2(-1.0 / sqrt(2.0), 0.0);
float2 direction = float2(1.0, 1.0);
if(doLineBlend)
{
bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_H_A <= dist_D_I) && neq(E,A) && neq(B,A);
bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_D_I <= dist_H_A) && neq(E,I) && neq(F,I);
origin = haveShallowLine? float2(-0.25, 0.0) : float2(-0.5, 0.0);
direction.y += haveShallowLine? 1.0: 0.0;
direction.x += haveSteepLine? 1.0: 0.0;
}
origin = origin;
direction = direction;
float4 blendPix = premultiply_alpha(lerp(H,D, step(DistYCbCr(E, D), DistYCbCr(E, H))));
res = lerp(res, blendPix, get_left_ratio(pos, origin, direction, scale));
}
// Pixel Tap Mapping: -|-|x|x|-
// -|A|B|C|x
// -|D|E|F|x
// -|-|H|I|-
// -|-|-|-|-
if(blendResult.y != BLEND_NONE)
{
float dist_B_I = DistYCbCr(B, I);
float dist_F_A = DistYCbCr(F, A);
bool doLineBlend = (blendResult.y == BLEND_DOMINANT ||
!((blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) || (blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) ||
(IsPixEqual(I, F) && IsPixEqual(F, C) && IsPixEqual(C, B) && IsPixEqual(B, A) && !IsPixEqual(E, C))));
float2 origin = float2(1.0 / sqrt(2.0), 0.0);
float2 direction = float2(-1.0, -1.0);
if(doLineBlend)
{
bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_B_I <= dist_F_A) && neq(E,I) && neq(H,I);
bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_F_A <= dist_B_I) && neq(E,A) && neq(D,A);
origin = haveShallowLine? float2(0.25, 0.0) : float2(0.5, 0.0);
direction.y -= haveShallowLine? 1.0: 0.0;
direction.x -= haveSteepLine? 1.0: 0.0;
}
float4 blendPix = premultiply_alpha(lerp(F,B, step(DistYCbCr(E, B), DistYCbCr(E, F))));
res = lerp(res, blendPix, get_left_ratio(pos, origin, direction, scale));
}
// Pixel Tap Mapping: -|x|x|-|-
// x|A|B|C|-
// x|D|E|F|-
// -|G|H|-|-
// -|-|-|-|-
if(blendResult.x != BLEND_NONE)
{
float dist_D_C = DistYCbCr(D, C);
float dist_B_G = DistYCbCr(B, G);
bool doLineBlend = (blendResult.x == BLEND_DOMINANT ||
!((blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) || (blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) ||
(IsPixEqual(C, B) && IsPixEqual(B, A) && IsPixEqual(A, D) && IsPixEqual(D, G) && !IsPixEqual(E, A))));
float2 origin = float2(0.0, -1.0 / sqrt(2.0));
float2 direction = float2(-1.0, 1.0);
if(doLineBlend)
{
bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_D_C <= dist_B_G) && neq(E,C) && neq(F,C);
bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_B_G <= dist_D_C) && neq(E,G) && neq(H,G);
origin = haveShallowLine? float2(0.0, -0.25) : float2(0.0, -0.5);
direction.x -= haveShallowLine? 1.0: 0.0;
direction.y += haveSteepLine? 1.0: 0.0;
}
float4 blendPix = premultiply_alpha(lerp(D,B, step(DistYCbCr(E, B), DistYCbCr(E, D))));
res = lerp(res, blendPix, get_left_ratio(pos, origin, direction, scale));
}
return postdivide_alpha(res);
}
-1
View File
@@ -1,5 +1,4 @@
These are simple tools to create the ZIM texture format and texture atlases based on it.
You'll need to clone git://git.savannah.gnu.org/freetype/freetype2.git into ext/freetype to build this.
atlastool <configuration_file> <filename_prefix> <format>
+6 -9
View File
@@ -176,8 +176,7 @@ 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 }, { "4xBRZ", TextureScalerCommon::_4XBRZ }, { "XBR", TextureScalerCommon::XBR }, { "SABR", TextureScalerCommon::SABR }, { "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_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_filtering("ppsspp_texture_filtering", "Texture Filtering", { { "auto", 1 }, { "nearest", 2 }, { "linear", 3 }, { "linear(FMV)", 4 } });
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);
@@ -207,7 +206,6 @@ void retro_set_environment(retro_environment_t cb) {
vars.push_back(ppsspp_texture_filtering.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_texture_replacement.GetOptions());
vars.push_back(ppsspp_gpu_hardware_transform.GetOptions());
vars.push_back(ppsspp_vertex_cache.GetOptions());
@@ -297,13 +295,12 @@ static void check_variables(CoreParameter &coreParam) {
}
}
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) {
if (ppsspp_texture_scaling_type.Update(&g_Config.iTexScalingType) && gpu) {
gpu->ClearCacheNextFrame();
}
if (ppsspp_texture_scaling_level.Update(&g_Config.iTexScalingLevel) && gpu) {
gpu->ClearCacheNextFrame();
gpu->ClearShaderCache();
gpu->Resized();
}
}