mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 18:49:51 +01:00
Remove Realtime scaling (d3d11)
This commit is contained in:
1 parent
4debff114c
commit
9c6f78c21f
40 files changed
+121
-1374
No files matched your search
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -135,7 +135,6 @@ bool IsColorTestTriviallyTrue() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Pack into 16-bit integer.
|
||||
const bool nonAlphaSrcFactors[16] = {
|
||||
true, // GE_SRCBLEND_DSTCOLOR,
|
||||
true, // GE_SRCBLEND_INVDSTCOLOR,
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -578,7 +578,6 @@ struct GPUStateCache {
|
||||
// Only applied when needShaderTexClamp = true.
|
||||
u32 curTextureXOffset;
|
||||
u32 curTextureYOffset;
|
||||
bool curTextureIsRT;
|
||||
|
||||
float vpWidth;
|
||||
float vpHeight;
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
float4 tex_sample(float2 coord) {
|
||||
return tex_sample_direct(coord);
|
||||
};
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
float4 tex_sample(float2 coord) {
|
||||
return tex_sample_direct(coord);
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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,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>
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user