Files
Xune/UIX.RenderApi.Skia/Microsoft/Iris/Render/Graphics/Dx9EffectResource.cs
T

398 lines
22 KiB
C#

// 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
{
internal class Dx9EffectResource : SharedRenderObject, IRenderHandleOwner
{
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";
internal Dx9EffectResource(
RenderSession session,
string stName,
Dx9EffectManager effectManager)
{
this.m_session = session;
this.m_stName = stName;
this.m_effectManager = effectManager;
this.m_tracker = MessagingSession.Current.CreateDataBufferTracker(this);
}
protected override void Dispose(bool fInDispose)
{
try
{
if (fInDispose)
{
if (this.m_tracker != null)
MessagingSession.Current.ReturnDataBufferTracker(this.m_tracker);
if (this.m_remoteEffect != null)
this.m_remoteEffect.Dispose();
}
this.m_tracker = null;
this.m_remoteEffect = null;
}
finally
{
base.Dispose(fInDispose);
}
}
public RemoteDx9EffectResource RemoteStub => this.m_remoteEffect;
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;
void IRenderHandleOwner.OnDisconnect() => this.m_remoteEffect = null;
internal bool Create(EffectInput element)
{
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;
}
}
// TODO: Re-implement
//this.RemoteEffect(effectBuilder, pEffectBlob.ToPointer(), pBlobBuffer, nBlobSize);
return true;
}
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 = 0U;
try
{
EngineApi.IFC(EngineApi.SpDx9CompileEffect(effectBuilder.EffectDefinition, null, out pErrorString, out pErrorBuffer, out pEffectBlob, out nBlobSize, out pBlobBuffer));
flag = true;
}
catch (Exception ex)
{
if (Marshal.PtrToStringAnsi(pErrorString) == null)
throw;
}
finally
{
if (pErrorBuffer != IntPtr.Zero)
Marshal.Release(pErrorBuffer);
}
return flag;
}
private void RemoteEffect(
Dx9EffectBuilder effectBuilder,
byte[] pEffectBlob,
IntPtr pBlobBuffer,
uint nBlobSize)
{
DataBuffer dataBuffer = this.m_session.BuildDataBuffer(pEffectBlob, nBlobSize);
this.m_tracker.Track(dataBuffer, new DataBufferTracker.CleanupEventHandler(OnReleaseLocalData), pBlobBuffer);
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);
}
}
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]
{
effectBuilder.PropertyVariables,
effectBuilder.GlobalVariables
};
for (int index = 0; index < vectorArray.Length; ++index)
{
if (vectorArray[index] != null)
{
foreach (VariableInfo variableInfo in vectorArray[index])
{
if (variableInfo.Name != null)
{
switch (variableInfo.Type)
{
case Dx9VariableType.Integer:
if (variableInfo.IsDynamic)
{
effectBuilder.EmitEffectFragment(InvariantString.Format("{0} {1};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name));
continue;
}
effectBuilder.EmitEffectFragment(InvariantString.Format("static const {0} {1} = {2};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name, (int)variableInfo.DefaultValue));
continue;
case Dx9VariableType.Float:
if (variableInfo.IsDynamic)
{
effectBuilder.EmitEffectFragment(InvariantString.Format("{0} {1};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name));
continue;
}
effectBuilder.EmitEffectFragment(InvariantString.Format("static const {0} {1} = {2};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name, (float)variableInfo.DefaultValue));
continue;
case Dx9VariableType.Vector2:
if (variableInfo.IsDynamic)
{
effectBuilder.EmitEffectFragment(InvariantString.Format("{0} {1};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name));
continue;
}
effectBuilder.EmitEffectFragment(InvariantString.Format("static const {0} {1} = {2};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name, ((Vector2)variableInfo.DefaultValue).ToDxShaderString()));
continue;
case Dx9VariableType.Vector3:
if (variableInfo.IsDynamic)
{
effectBuilder.EmitEffectFragment(InvariantString.Format("{0} {1};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name));
continue;
}
effectBuilder.EmitEffectFragment(InvariantString.Format("static const {0} {1} = {2};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name, ((Vector3)variableInfo.DefaultValue).ToDxShaderString()));
continue;
case Dx9VariableType.Vector4:
if (variableInfo.IsDynamic)
{
effectBuilder.EmitEffectFragment(InvariantString.Format("{0} {1};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name));
continue;
}
effectBuilder.EmitEffectFragment(InvariantString.Format("static const {0} {1} = {2};\r\n", effectBuilder.ConvertToString(variableInfo.Type), variableInfo.Name, ((Vector4)variableInfo.DefaultValue).ToDxShaderString()));
continue;
case Dx9VariableType.Texture:
TextureVariableInfo textureVariableInfo = (TextureVariableInfo)variableInfo;
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));
continue;
default:
continue;
}
}
}
}
}
effectBuilder.EmitEffectFragment("\r\n");
}
protected void EmitShaders(Dx9EffectBuilder effectBuilder)
{
effectBuilder.EmitEffectFragment(effectBuilder.ShaderDeclarations);
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));
}
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));
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)
{
foreach (EffectOperation operation in eflCurrent.Operations)
{
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;
}
}
}