diff --git a/src/VDFilters/source/VFBlendLayers.cpp b/src/VDFilters/source/VFBlendLayers.cpp index 974aff91..f97c839c 100644 --- a/src/VDFilters/source/VFBlendLayers.cpp +++ b/src/VDFilters/source/VFBlendLayers.cpp @@ -49,7 +49,9 @@ namespace { L"Pin Light", L"Hard Mix", L"Difference", - L"Exclusion" + L"Exclusion", + L"Subtract", + L"Divide }; } @@ -73,6 +75,8 @@ struct VDVFBlendLayersConfig { kMode_HardMix, kMode_Difference, kMode_Exclusion, + kMode_Subtract, + kMode_Divide, kModeCount }; @@ -396,6 +400,17 @@ void VDVFBlendLayers::Run() { case VDVFBlendLayersConfig::kMode_Exclusion: VDDSPProcessPlane3(dstp, dstpitch, srcp1, src1pitch, srcp2, src2pitch, w16, h, VDDSPBlend8_Exclusion); break; + + case VDVFBlendLayersConfig::kMode_Subtract: + if (sse2) + VDDSPProcessPlane3(dstp, dstpitch, srcp1, src1pitch, srcp2, src2pitch, w16, h, VDDSPBlend8_Subtract_SSE2); + else + VDDSPProcessPlane3(dstp, dstpitch, srcp1, src1pitch, srcp2, src2pitch, w16, h, VDDSPBlend8_Subtract); + break; + + case VDVFBlendLayersConfig::kMode_Divide: + VDDSPProcessPlane3(dstp, dstpitch, srcp1, src1pitch, srcp2, src2pitch, w16, h, VDDSPBlend8_Divide); + break; } if (factor8 != 255) @@ -497,6 +512,16 @@ void VDVFBlendLayers::StartAccel(IVDXAContext *vdxa) { bytecode = kVDVFBlendLayersFP_Exclusion; bclen = sizeof kVDVFBlendLayersFP_Exclusion; break; + + case VDVFBlendLayersConfig::kMode_Subtract: + bytecode = kVDVFBlendLayersFP_Subtract; + bclen = sizeof kVDVFBlendLayersFP_Subtract; + break; + + case VDVFBlendLayersConfig::kMode_Divide: + bytecode = kVDVFBlendLayersFP_Divide; + bclen = sizeof kVDVFBlendLayersFP_Divide; + break; } mVDXAShader = vdxa->CreateFragmentProgram(kVDXAPF_D3D9ByteCodePS20, bytecode, bclen); diff --git a/src/VDFilters/source/VFBlendLayers.vdshaders b/src/VDFilters/source/VFBlendLayers.vdshaders index ddeecf8c..a05fb411 100644 --- a/src/VDFilters/source/VFBlendLayers.vdshaders +++ b/src/VDFilters/source/VFBlendLayers.vdshaders @@ -294,3 +294,35 @@ kVDVFBlendLayersFP_Exclusion:: return c0 + (c1 - 2.0h*c0*c1) * (half)opacity; } + +kVDVFBlendLayersFP_Subtract:: + extern sampler2D src0 : register(s0); + extern sampler2D src1 : register(s1); + extern float opacity : register(c0); + + half4 main( + float4 uv0 : TEXCOORD0, + float4 uv1 : TEXCOORD1 + ) : COLOR0 + { + half4 c0 = tex2D(src0, uv0.xy); + half4 c1 = tex2D(src1, uv1.xy); + + return max(0.0h, c0 - c1) * (half)opacity; + } + +kVDVFBlendLayersFP_Divide:: + extern sampler2D src0 : register(s0); + extern sampler2D src1 : register(s1); + extern float opacity : register(c0); + + half4 main( + float4 uv0 : TEXCOORD0, + float4 uv1 : TEXCOORD1 + ) : COLOR0 + { + half4 c0 = tex2D(src0, uv0.xy); + half4 c1 = tex2D(src1, uv1.xy); + + return lerp(c0, min(1.0h, c0 / c1), (half)opacity); + }