2021-07-11 22:59:29 -05:00
// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.Render.Graphics.Dx9EffectResource
// Assembly: UIX.RenderApi, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: D47658B8-A8EA-43D6-8837-ECE823BFFFC1
// Assembly location: C:\Program Files\Zune\UIX.RenderApi.dll
using Microsoft.Iris.Library ;
using Microsoft.Iris.Render.Common ;
using Microsoft.Iris.Render.Internal ;
using Microsoft.Iris.Render.Protocol ;
using Microsoft.Iris.Render.Protocols.Splash.Rendering ;
using System ;
using System.Collections ;
using System.Runtime.InteropServices ;
namespace Microsoft.Iris.Render.Graphics
{
2021-07-11 23:04:40 -05:00
internal class Dx9EffectResource : SharedRenderObject , IRenderHandleOwner
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
private RenderSession m_session ;
private RemoteDx9EffectResource m_remoteEffect ;
private string m_stName ;
private Dx9EffectManager m_effectManager ;
private DataBufferTracker m_tracker ;
private Size m_sizeGutter ;
private static string k_stVertexShaderName = "ExecuteVertexShader" ;
private static string k_stPixelShaderName = "ExecutePixelShader" ;
2021-07-11 22:59:29 -05:00
2021-07-11 23:04:40 -05:00
internal Dx9EffectResource (
RenderSession session ,
string stName ,
Dx9EffectManager effectManager )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
this . m_session = session ;
this . m_stName = stName ;
this . m_effectManager = effectManager ;
2021-07-11 23:07:04 -05:00
this . m_tracker = MessagingSession . Current . CreateDataBufferTracker ( this );
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
protected override void Dispose ( bool fInDispose )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
try
{
if ( fInDispose )
{
if ( this . m_tracker != null )
MessagingSession . Current . ReturnDataBufferTracker ( this . m_tracker );
if ( this . m_remoteEffect != null )
this . m_remoteEffect . Dispose ();
}
2021-07-11 23:07:04 -05:00
this . m_tracker = null ;
this . m_remoteEffect = null ;
2021-07-11 23:04:40 -05:00
}
finally
{
base . Dispose ( fInDispose );
}
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
public RemoteDx9EffectResource RemoteStub => this . m_remoteEffect ;
2021-07-11 22:59:29 -05:00
2021-07-11 23:04:40 -05:00
private string PixelShaderVersion => this . m_effectManager . Device . PixelShaderProfile ;
private string VertexShaderVersion => this . m_effectManager . Device . VertexShaderProfile ;
internal Size GutterSize => this . m_sizeGutter ;
RENDERHANDLE IRenderHandleOwner . RenderHandle => this . m_remoteEffect . RenderHandle ;
2021-07-11 23:07:04 -05:00
void IRenderHandleOwner . OnDisconnect () => this . m_remoteEffect = null ;
2021-07-11 23:04:40 -05:00
internal bool Create ( EffectInput element )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
Dx9EffectBuilder effectBuilder = this . m_effectManager . EffectBuilder ;
effectBuilder . Clear ();
if (! this . ProcessEffectInput ( element , ref effectBuilder ))
return false ;
this . GenerateEffect ( effectBuilder );
uint nBlobSize = 0 ;
IntPtr pEffectBlob = IntPtr . Zero ;
IntPtr pBlobBuffer = IntPtr . Zero ;
if (! this . CompileEffect ( effectBuilder , out pEffectBlob , out pBlobBuffer , out nBlobSize ))
return false ;
Vector < VariableInfo > propertyVariables = effectBuilder . PropertyVariables ;
if ( propertyVariables != null )
{
int index = 0 ;
while ( index < propertyVariables . Count )
{
if (! propertyVariables [ index ]. IsDynamic )
propertyVariables . RemoveAt ( index );
else
++ index ;
}
}
2021-07-15 22:00:36 -05:00
// TODO: Re-implement
//this.RemoteEffect(effectBuilder, pEffectBlob.ToPointer(), pBlobBuffer, nBlobSize);
2021-07-11 23:04:40 -05:00
return true ;
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
private bool CompileEffect (
Dx9EffectBuilder effectBuilder ,
out IntPtr pEffectBlob ,
out IntPtr pBlobBuffer ,
out uint nBlobSize )
{
bool flag = false ;
IntPtr pErrorString = IntPtr . Zero ;
IntPtr pErrorBuffer = IntPtr . Zero ;
pEffectBlob = IntPtr . Zero ;
pBlobBuffer = IntPtr . Zero ;
nBlobSize = 0 U ;
try
{
2021-07-11 23:07:04 -05:00
EngineApi . IFC ( EngineApi . SpDx9CompileEffect ( effectBuilder . EffectDefinition , null , out pErrorString , out pErrorBuffer , out pEffectBlob , out nBlobSize , out pBlobBuffer ));
2021-07-11 23:04:40 -05:00
flag = true ;
}
catch ( Exception ex )
{
if ( Marshal . PtrToStringAnsi ( pErrorString ) == null )
throw ;
}
finally
{
if ( pErrorBuffer != IntPtr . Zero )
Marshal . Release ( pErrorBuffer );
}
return flag ;
}
2021-07-11 22:59:29 -05:00
2021-07-11 23:04:40 -05:00
private void RemoteEffect (
Dx9EffectBuilder effectBuilder ,
2021-07-15 22:00:36 -05:00
byte [] pEffectBlob ,
2021-07-11 23:04:40 -05:00
IntPtr pBlobBuffer ,
uint nBlobSize )
{
DataBuffer dataBuffer = this . m_session . BuildDataBuffer ( pEffectBlob , nBlobSize );
2021-07-11 23:07:04 -05:00
this . m_tracker . Track ( dataBuffer , new DataBufferTracker . CleanupEventHandler ( OnReleaseLocalData ), pBlobBuffer );
2021-07-11 23:04:40 -05:00
dataBuffer . Commit ();
this . m_remoteEffect = this . m_session . BuildRemoteDx9EffectResource ( this , this . m_effectManager . Device , dataBuffer );
Vector < VariableInfo > propertyVariables = effectBuilder . PropertyVariables ;
if ( propertyVariables != null )
{
foreach ( VariableInfo variableInfo in propertyVariables )
{
switch ( variableInfo . Type )
{
case Dx9VariableType . Integer :
this . m_remoteEffect . SendAddProperty ( variableInfo . Name , ( int ) variableInfo . DefaultValue );
continue ;
case Dx9VariableType . Float :
this . m_remoteEffect . SendAddProperty ( variableInfo . Name , ( float ) variableInfo . DefaultValue );
continue ;
case Dx9VariableType . Vector2 :
this . m_remoteEffect . SendAddProperty ( variableInfo . Name , ( Vector2 ) variableInfo . DefaultValue );
continue ;
case Dx9VariableType . Vector3 :
this . m_remoteEffect . SendAddProperty ( variableInfo . Name , ( Vector3 ) variableInfo . DefaultValue );
continue ;
case Dx9VariableType . Vector4 :
this . m_remoteEffect . SendAddProperty ( variableInfo . Name , ( Vector4 ) variableInfo . DefaultValue );
continue ;
case Dx9VariableType . Texture :
TextureVariableInfo textureVariableInfo = ( TextureVariableInfo ) variableInfo ;
this . m_remoteEffect . SendAddProperty ( variableInfo . Name , textureVariableInfo . CoordinateMapID , textureVariableInfo . ImageIndexID );
continue ;
default :
continue ;
}
}
}
this . m_remoteEffect . SendPostPropertiesAdded ();
this . m_remoteEffect . SendSetGutterSize ( this . m_sizeGutter );
if ( effectBuilder . TextureInfoList == null )
return ;
foreach ( Dx9TextureInfo textureInfo in effectBuilder . TextureInfoList )
{
if ( textureInfo . Requirements != 0 )
this . m_remoteEffect . SendAddTextureRequirements ( textureInfo . ImageIndex , textureInfo . Requirements , textureInfo . TexelSize , textureInfo . TexUVSize , textureInfo . TexUVRefPoint , textureInfo . DownsamplePropertyID );
}
}
2021-07-11 22:59:29 -05:00
2021-07-11 23:04:40 -05:00
private static void OnReleaseLocalData ( object sender , DataBufferTracker . CleanupEventArgs args )
{
IntPtr contextData = ( IntPtr ) args . ContextData ;
if (!( contextData != IntPtr . Zero ))
return ;
Marshal . Release ( contextData );
IntPtr zero = IntPtr . Zero ;
}
private string GenerateFileName () => this . m_stName + ".fx" ;
protected void EmitHeader ( Dx9EffectBuilder effectBuilder )
{
effectBuilder . EmitEffectFragment ( "#include \"Common.fx\"\r\n" );
effectBuilder . EmitEffectFragment ( effectBuilder . IncludesFragment + "\r\n\r\n" );
Vector < VariableInfo >[] vectorArray = new Vector < VariableInfo >[ 2 ]
{
2021-07-11 22:59:29 -05:00
effectBuilder . PropertyVariables ,
effectBuilder . GlobalVariables
2021-07-11 23:04:40 -05:00
};
for ( int index = 0 ; index < vectorArray . Length ; ++ index )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
if ( vectorArray [ index ] != null )
{
foreach ( VariableInfo variableInfo in vectorArray [ index ])
{
if ( variableInfo . Name != null )
{
switch ( variableInfo . Type )
{
case Dx9VariableType . Integer :
if ( variableInfo . IsDynamic )
{
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "{0} {1};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name ));
2021-07-11 23:04:40 -05:00
continue ;
}
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "static const {0} {1} = {2};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name , ( int ) variableInfo . DefaultValue ));
2021-07-11 23:04:40 -05:00
continue ;
case Dx9VariableType . Float :
if ( variableInfo . IsDynamic )
{
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "{0} {1};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name ));
2021-07-11 23:04:40 -05:00
continue ;
}
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "static const {0} {1} = {2};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name , ( float ) variableInfo . DefaultValue ));
2021-07-11 23:04:40 -05:00
continue ;
case Dx9VariableType . Vector2 :
if ( variableInfo . IsDynamic )
{
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "{0} {1};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name ));
2021-07-11 23:04:40 -05:00
continue ;
}
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "static const {0} {1} = {2};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name , (( Vector2 ) variableInfo . DefaultValue ). ToDxShaderString ()));
2021-07-11 23:04:40 -05:00
continue ;
case Dx9VariableType . Vector3 :
if ( variableInfo . IsDynamic )
{
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "{0} {1};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name ));
2021-07-11 23:04:40 -05:00
continue ;
}
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "static const {0} {1} = {2};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name , (( Vector3 ) variableInfo . DefaultValue ). ToDxShaderString ()));
2021-07-11 23:04:40 -05:00
continue ;
case Dx9VariableType . Vector4 :
if ( variableInfo . IsDynamic )
{
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "{0} {1};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name ));
2021-07-11 23:04:40 -05:00
continue ;
}
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "static const {0} {1} = {2};\r\n" , effectBuilder . ConvertToString ( variableInfo . Type ), variableInfo . Name , (( Vector4 ) variableInfo . DefaultValue ). ToDxShaderString ()));
2021-07-11 23:04:40 -05:00
continue ;
case Dx9VariableType . Texture :
TextureVariableInfo textureVariableInfo = ( TextureVariableInfo ) variableInfo ;
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "\r\n{0} {1};\r\n" , effectBuilder . ConvertToString ( textureVariableInfo . Type ), textureVariableInfo . Name ));
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "sampler {0} = \r\n sampler_state\r\n {{\r\n Texture = <{1}>;\r\n MinFilter = {2};\r\n MagFilter = {3};\r\n AddressU = Clamp;\r\n AddressV = Clamp;\r\n }};\r\n\r\n" , textureVariableInfo . SamplerName , textureVariableInfo . Name , textureVariableInfo . MinFilter , textureVariableInfo . MagFilter ));
2021-07-11 23:04:40 -05:00
continue ;
default :
continue ;
}
}
}
}
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
effectBuilder . EmitEffectFragment ( "\r\n" );
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
protected void EmitShaders ( Dx9EffectBuilder effectBuilder )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
effectBuilder . EmitEffectFragment ( effectBuilder . ShaderDeclarations );
2021-07-11 23:07:04 -05:00
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "VS_OUTPUT {0}(VS_INPUT Input)\r\n{{\r\n VS_OUTPUT Output;\r\n\r\n{1}\r\n return Output;\r\n}}\r\n\r\n" , k_stVertexShaderName , effectBuilder . VertexShader ));
effectBuilder . EmitEffectFragment ( InvariantString . Format ( "PS_OUTPUT {0}(VS_OUTPUT Input)\r\n{{\r\n PS_OUTPUT Output;\r\n\r\n{1} // Include Vertex color contribution\r\n Output.Color = {2} * Input.Color;\r\n\r\n // Return the final result\r\n return Output;\r\n}}\r\n\r\n" , k_stPixelShaderName , effectBuilder . PixelShader , effectBuilder . PixelShaderOutput ));
2021-07-11 23:04:40 -05:00
}
2021-07-11 23:07:04 -05:00
protected void EmitTechnique ( Dx9EffectBuilder effectBuilder ) => effectBuilder . EmitEffectFragment ( InvariantString . Format ( "technique GeneratedTechnique\r\n{{\r\n pass P0\r\n {{\r\n // Shaders\r\n PixelShader = compile {0} {1}();\r\n VertexShader = compile {2} {3}();\r\n }}\r\n}}\r\n" , PixelShaderVersion , k_stPixelShaderName , VertexShaderVersion , k_stVertexShaderName ));
2021-07-11 23:04:40 -05:00
private void GenerateEffect ( Dx9EffectBuilder effectBuilder )
{
this . EmitHeader ( effectBuilder );
this . EmitShaders ( effectBuilder );
this . EmitTechnique ( effectBuilder );
}
private bool ProcessEffectInput ( EffectInput efiCurrent , ref Dx9EffectBuilder effectBuilder )
{
bool flag = true ;
switch ( efiCurrent . Type )
{
case EffectInputType . Color :
Dx9ColorElement . Generate (( ColorElement ) efiCurrent , ref effectBuilder );
break ;
case EffectInputType . Image :
Dx9ImageElement . Generate (( ImageElement ) efiCurrent , ref effectBuilder );
break ;
case EffectInputType . Blend :
BlendElement efiBlend = ( BlendElement ) efiCurrent ;
this . ProcessEffectInput ( efiBlend . Input1 , ref effectBuilder );
string pixelShaderOutput1 = effectBuilder . PixelShaderOutput ;
this . ProcessEffectInput ( efiBlend . Input2 , ref effectBuilder );
string pixelShaderOutput2 = effectBuilder . PixelShaderOutput ;
Dx9BlendElement . Generate ( efiBlend , pixelShaderOutput1 , pixelShaderOutput2 , ref effectBuilder );
break ;
case EffectInputType . Interpolate :
InterpolateElement efiInterpolate = ( InterpolateElement ) efiCurrent ;
this . ProcessEffectInput ( efiInterpolate . Input1 , ref effectBuilder );
string pixelShaderOutput3 = effectBuilder . PixelShaderOutput ;
this . ProcessEffectInput ( efiInterpolate . Input2 , ref effectBuilder );
string pixelShaderOutput4 = effectBuilder . PixelShaderOutput ;
Dx9InterpolateElement . Generate ( efiInterpolate , pixelShaderOutput3 , pixelShaderOutput4 , ref effectBuilder );
break ;
case EffectInputType . Layer :
flag = this . ProcessEffectLayer (( EffectLayer ) efiCurrent , ref effectBuilder );
break ;
case EffectInputType . ComplexImage :
Dx9ComplexImageElement . Generate (( ComplexImageElement ) efiCurrent , ref effectBuilder );
break ;
case EffectInputType . Video :
Dx9VideoElement . Generate (( VideoElement ) efiCurrent , ref effectBuilder );
break ;
case EffectInputType . Spotlight2D :
Dx9SpotLight2DElement . Generate (( SpotLight2DElement ) efiCurrent , ref effectBuilder );
break ;
case EffectInputType . PointLight2D :
Dx9PointLight2DElement . Generate (( PointLight2DElement ) efiCurrent , ref effectBuilder );
break ;
case EffectInputType . Destination :
Dx9DestinationElement . Generate (( DestinationElement ) efiCurrent , ref effectBuilder );
this . m_sizeGutter . Width = Math . Max ( this . m_sizeGutter . Width , 1 );
this . m_sizeGutter . Height = Math . Max ( this . m_sizeGutter . Height , 1 );
break ;
}
return flag && effectBuilder . Validate ();
}
private bool ProcessEffectLayer ( EffectLayer eflCurrent , ref Dx9EffectBuilder effectBuilder )
{
if (! this . ProcessEffectInput ( eflCurrent . Input , ref effectBuilder ))
return false ;
if ( eflCurrent . Operations != null )
{
2021-07-11 23:07:04 -05:00
foreach ( EffectOperation operation in eflCurrent . Operations )
2021-07-11 23:04:40 -05:00
{
switch ( operation . Type )
{
case EffectOperationType . Brightness :
Dx9BrightnessElement . Generate (( BrightnessElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . Contrast :
Dx9ContrastElement . Generate (( ContrastElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . Desaturate :
Dx9DesaturateElement . Generate (( DesaturateElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . EdgeDetection :
Dx9EdgeDetectionElement . Generate (( EdgeDetectionElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . Emboss :
Dx9EmbossElement . Generate (( EmbossElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . GaussianBlur :
Debug2 . Validate ( eflCurrent . Input . Type == EffectInputType . Image || eflCurrent . Input . Type == EffectInputType . Video || eflCurrent . Input . Type == EffectInputType . Destination , typeof ( InvalidOperationException ), "GaussianBlurElement only valid for inputs with ImageElement inputs" );
GaussianBlurElement efoBlur = ( GaussianBlurElement ) operation ;
Dx9GaussianBlurElement . Generate ( efoBlur , ref effectBuilder );
this . m_sizeGutter . Width = Math . Max ( this . m_sizeGutter . Width , efoBlur . KernelRadius + 1 );
this . m_sizeGutter . Height = Math . Max ( this . m_sizeGutter . Height , efoBlur . KernelRadius + 1 );
continue ;
case EffectOperationType . HSL :
Dx9HSLElement . Generate (( HSLElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . HSV :
Dx9HSVElement . Generate (( HSVElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . InvAlpha :
Dx9InvAlphaElement . Generate ( operation , ref effectBuilder );
continue ;
case EffectOperationType . InvColor :
Dx9InvColorElement . Generate ( operation , ref effectBuilder );
continue ;
case EffectOperationType . Invert :
Dx9InvertElement . Generate (( InvertElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . LightShaft :
Debug2 . Validate ( eflCurrent . Input . Type == EffectInputType . Image || eflCurrent . Input . Type == EffectInputType . Video || eflCurrent . Input . Type == EffectInputType . Destination , typeof ( InvalidOperationException ), "LightShaftElement only valid for inputs with ImageElement inputs" );
Dx9LightShaftElement . Generate (( LightShaftElement ) operation , ref effectBuilder );
continue ;
case EffectOperationType . Sepia :
Dx9SepiaElement . Generate (( SepiaElement ) operation , ref effectBuilder );
continue ;
default :
continue ;
}
}
}
return true ;
2021-07-11 22:59:29 -05:00
}
}
}