1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/d3d11/CompositorD3D11.fx Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,268 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +typedef float4 rect; 1.10 + 1.11 +float4x4 mLayerTransform : register(vs, c0); 1.12 +float4x4 mProjection : register(vs, c4); 1.13 +float4 vRenderTargetOffset : register(vs, c8); 1.14 +rect vTextureCoords : register(vs, c9); 1.15 +rect vLayerQuad : register(vs, c10); 1.16 +rect vMaskQuad : register(vs, c11); 1.17 + 1.18 +float4 fLayerColor : register(ps, c0); 1.19 +float fLayerOpacity : register(ps, c1); 1.20 + 1.21 +sampler sSampler : register(ps, s0); 1.22 + 1.23 +Texture2D tRGB; 1.24 +Texture2D tY; 1.25 +Texture2D tCb; 1.26 +Texture2D tCr; 1.27 +Texture2D tRGBWhite; 1.28 +// Always bind this to slot 3 since this is always available! 1.29 +Texture2D tMask : register(ps, t3); 1.30 + 1.31 +struct VS_INPUT { 1.32 + float2 vPosition : POSITION; 1.33 +}; 1.34 + 1.35 +struct VS_OUTPUT { 1.36 + float4 vPosition : SV_Position; 1.37 + float2 vTexCoords : TEXCOORD0; 1.38 +}; 1.39 + 1.40 +struct VS_MASK_OUTPUT { 1.41 + float4 vPosition : SV_Position; 1.42 + float2 vTexCoords : TEXCOORD0; 1.43 + float2 vMaskCoords : TEXCOORD1; 1.44 +}; 1.45 + 1.46 +struct VS_MASK_3D_OUTPUT { 1.47 + float4 vPosition : SV_Position; 1.48 + float2 vTexCoords : TEXCOORD0; 1.49 + float3 vMaskCoords : TEXCOORD1; 1.50 +}; 1.51 + 1.52 +struct PS_OUTPUT { 1.53 + float4 vSrc; 1.54 + float4 vAlpha; 1.55 +}; 1.56 + 1.57 +float2 TexCoords(const float2 aPosition) 1.58 +{ 1.59 + float2 result; 1.60 + const float2 size = vTextureCoords.zw; 1.61 + result.x = vTextureCoords.x + aPosition.x * size.x; 1.62 + result.y = vTextureCoords.y + aPosition.y * size.y; 1.63 + 1.64 + return result; 1.65 +} 1.66 + 1.67 +SamplerState LayerTextureSamplerLinear 1.68 +{ 1.69 + Filter = MIN_MAG_MIP_LINEAR; 1.70 + AddressU = Clamp; 1.71 + AddressV = Clamp; 1.72 +}; 1.73 + 1.74 +float4 TransformedPosition(float2 aInPosition) 1.75 +{ 1.76 + // the current vertex's position on the quad 1.77 + float4 position = float4(0, 0, 0, 1); 1.78 + 1.79 + // We use 4 component floats to uniquely describe a rectangle, by the structure 1.80 + // of x, y, width, height. This allows us to easily generate the 4 corners 1.81 + // of any rectangle from the 4 corners of the 0,0-1,1 quad that we use as the 1.82 + // stream source for our LayerQuad vertex shader. We do this by doing: 1.83 + // Xout = x + Xin * width 1.84 + // Yout = y + Yin * height 1.85 + float2 size = vLayerQuad.zw; 1.86 + position.x = vLayerQuad.x + aInPosition.x * size.x; 1.87 + position.y = vLayerQuad.y + aInPosition.y * size.y; 1.88 + 1.89 + position = mul(mLayerTransform, position); 1.90 + 1.91 + return position; 1.92 +} 1.93 + 1.94 +float4 VertexPosition(float4 aTransformedPosition) 1.95 +{ 1.96 + float4 result; 1.97 + result.w = aTransformedPosition.w; 1.98 + result.xyz = aTransformedPosition.xyz / aTransformedPosition.w; 1.99 + result -= vRenderTargetOffset; 1.100 + result.xyz *= result.w; 1.101 + 1.102 + result = mul(mProjection, result); 1.103 + 1.104 + return result; 1.105 +} 1.106 + 1.107 +VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex) 1.108 +{ 1.109 + VS_OUTPUT outp; 1.110 + float4 position = TransformedPosition(aVertex.vPosition); 1.111 + 1.112 + outp.vPosition = VertexPosition(position); 1.113 + outp.vTexCoords = TexCoords(aVertex.vPosition.xy); 1.114 + 1.115 + return outp; 1.116 +} 1.117 + 1.118 +VS_MASK_OUTPUT LayerQuadMaskVS(const VS_INPUT aVertex) 1.119 +{ 1.120 + VS_MASK_OUTPUT outp; 1.121 + float4 position = TransformedPosition(aVertex.vPosition); 1.122 + 1.123 + outp.vPosition = VertexPosition(position); 1.124 + 1.125 + // calculate the position on the mask texture 1.126 + outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z; 1.127 + outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w; 1.128 + 1.129 + outp.vTexCoords = TexCoords(aVertex.vPosition.xy); 1.130 + 1.131 + return outp; 1.132 +} 1.133 + 1.134 +VS_MASK_3D_OUTPUT LayerQuadMask3DVS(const VS_INPUT aVertex) 1.135 +{ 1.136 + VS_MASK_3D_OUTPUT outp; 1.137 + float4 position = TransformedPosition(aVertex.vPosition); 1.138 + 1.139 + outp.vPosition = VertexPosition(position); 1.140 + 1.141 + // calculate the position on the mask texture 1.142 + position.xyz /= position.w; 1.143 + outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z; 1.144 + outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w; 1.145 + // We use the w coord to do non-perspective correct interpolation: 1.146 + // the quad might be transformed in 3D, in which case it will have some 1.147 + // perspective. The graphics card will do perspective-correct interpolation 1.148 + // of the texture, but our mask is already transformed and so we require 1.149 + // linear interpolation. Therefore, we must correct the interpolation 1.150 + // ourselves, we do this by multiplying all coords by w here, and dividing by 1.151 + // w in the pixel shader (post-interpolation), we pass w in outp.vMaskCoords.z. 1.152 + // See http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness 1.153 + outp.vMaskCoords.z = 1; 1.154 + outp.vMaskCoords *= position.w; 1.155 + 1.156 + outp.vTexCoords = TexCoords(aVertex.vPosition.xy); 1.157 + 1.158 + return outp; 1.159 +} 1.160 + 1.161 +float4 RGBAShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target 1.162 +{ 1.163 + float2 maskCoords = aVertex.vMaskCoords; 1.164 + float mask = tMask.Sample(sSampler, maskCoords).a; 1.165 + return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask; 1.166 +} 1.167 + 1.168 +float4 RGBAShaderMask3D(const VS_MASK_3D_OUTPUT aVertex) : SV_Target 1.169 +{ 1.170 + float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z; 1.171 + float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a; 1.172 + return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask; 1.173 +} 1.174 + 1.175 +float4 RGBShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target 1.176 +{ 1.177 + float4 result; 1.178 + result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity; 1.179 + result.a = fLayerOpacity; 1.180 + 1.181 + float2 maskCoords = aVertex.vMaskCoords; 1.182 + float mask = tMask.Sample(sSampler, maskCoords).a; 1.183 + return result * mask; 1.184 +} 1.185 + 1.186 +float4 CalculateYCbCrColor(const float2 aTexCoords) 1.187 +{ 1.188 + float4 yuv; 1.189 + float4 color; 1.190 + 1.191 + yuv.r = tCr.Sample(sSampler, aTexCoords).a - 0.5; 1.192 + yuv.g = tY.Sample(sSampler, aTexCoords).a - 0.0625; 1.193 + yuv.b = tCb.Sample(sSampler, aTexCoords).a - 0.5; 1.194 + 1.195 + color.r = yuv.g * 1.164 + yuv.r * 1.596; 1.196 + color.g = yuv.g * 1.164 - 0.813 * yuv.r - 0.391 * yuv.b; 1.197 + color.b = yuv.g * 1.164 + yuv.b * 2.018; 1.198 + color.a = 1.0f; 1.199 + 1.200 + return color; 1.201 +} 1.202 + 1.203 +float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target 1.204 +{ 1.205 + float2 maskCoords = aVertex.vMaskCoords; 1.206 + float mask = tMask.Sample(sSampler, maskCoords).a; 1.207 + 1.208 + return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity * mask; 1.209 +} 1.210 + 1.211 +PS_OUTPUT ComponentAlphaShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target 1.212 +{ 1.213 + PS_OUTPUT result; 1.214 + 1.215 + result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords); 1.216 + result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc; 1.217 + result.vSrc.a = result.vAlpha.g; 1.218 + 1.219 + float2 maskCoords = aVertex.vMaskCoords; 1.220 + float mask = tMask.Sample(sSampler, maskCoords).a; 1.221 + result.vSrc *= fLayerOpacity * mask; 1.222 + result.vAlpha *= fLayerOpacity * mask; 1.223 + 1.224 + return result; 1.225 +} 1.226 + 1.227 +float4 SolidColorShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target 1.228 +{ 1.229 + float2 maskCoords = aVertex.vMaskCoords; 1.230 + float mask = tMask.Sample(sSampler, maskCoords).a; 1.231 + return fLayerColor * mask; 1.232 +} 1.233 + 1.234 +/* 1.235 + * Un-masked versions 1.236 + ************************************************************* 1.237 + */ 1.238 +float4 RGBAShader(const VS_OUTPUT aVertex) : SV_Target 1.239 +{ 1.240 + return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity; 1.241 +} 1.242 + 1.243 +float4 RGBShader(const VS_OUTPUT aVertex) : SV_Target 1.244 +{ 1.245 + float4 result; 1.246 + result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity; 1.247 + result.a = fLayerOpacity; 1.248 + return result; 1.249 +} 1.250 + 1.251 +float4 YCbCrShader(const VS_OUTPUT aVertex) : SV_Target 1.252 +{ 1.253 + return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity; 1.254 +} 1.255 + 1.256 +PS_OUTPUT ComponentAlphaShader(const VS_OUTPUT aVertex) : SV_Target 1.257 +{ 1.258 + PS_OUTPUT result; 1.259 + 1.260 + result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords); 1.261 + result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc; 1.262 + result.vSrc.a = result.vAlpha.g; 1.263 + result.vSrc *= fLayerOpacity; 1.264 + result.vAlpha *= fLayerOpacity; 1.265 + return result; 1.266 +} 1.267 + 1.268 +float4 SolidColorShader(const VS_OUTPUT aVertex) : SV_Target 1.269 +{ 1.270 + return fLayerColor; 1.271 +}