Refactored a lot of the rendering in the metro system and improved the memory usage of the ParameterBuffer
This commit is contained in:
parent
2ffe3004cd
commit
947287b0ab
@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using ANX.Framework.Graphics;
|
||||
using ANX.Framework.NonXNA;
|
||||
using Dx11 = SharpDX.Direct3D11;
|
||||
using ANX.RenderSystem.Windows.Metro.Shader;
|
||||
using Dx11 = SharpDX.Direct3D11;
|
||||
|
||||
// This file is part of the ANX.Framework created by the
|
||||
// "ANX.Framework developer group" and released under the Ms-PL license.
|
||||
@ -31,34 +30,6 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Dx11.VertexShader VertexShader
|
||||
{
|
||||
get
|
||||
{
|
||||
if (vertexShader == null)
|
||||
{
|
||||
vertexShader = new Dx11.VertexShader(
|
||||
NativeDxDevice.Current.NativeDevice, nativePass.VertexCode);
|
||||
}
|
||||
|
||||
return vertexShader;
|
||||
}
|
||||
}
|
||||
|
||||
public Dx11.PixelShader PixelShader
|
||||
{
|
||||
get
|
||||
{
|
||||
if (pixelShader == null)
|
||||
{
|
||||
pixelShader = new Dx11.PixelShader(
|
||||
NativeDxDevice.Current.NativeDevice, nativePass.PixelCode);
|
||||
}
|
||||
|
||||
return pixelShader;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
@ -72,10 +43,25 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Dx11.InputLayout BuildLayout(Dx11.Device d3dDevice,
|
||||
Dx11.InputElement[] elements)
|
||||
#region BuildLayout
|
||||
public Dx11.InputLayout BuildLayout(Dx11.Device d3dDevice, Dx11.InputElement[] elements)
|
||||
{
|
||||
return new Dx11.InputLayout(d3dDevice, nativePass.VertexCode, elements);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Apply
|
||||
public void Apply(NativeDxDevice device)
|
||||
{
|
||||
if (vertexShader == null)
|
||||
vertexShader = new Dx11.VertexShader(device.NativeDevice, nativePass.VertexCode);
|
||||
|
||||
if (pixelShader == null)
|
||||
pixelShader = new Dx11.PixelShader(device.NativeDevice, nativePass.PixelCode);
|
||||
|
||||
device.NativeContext.VertexShader.Set(vertexShader);
|
||||
device.NativeContext.PixelShader.Set(pixelShader);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using ANX.Framework.Graphics;
|
||||
using ANX.Framework.NonXNA;
|
||||
using Dx11 = SharpDX.Direct3D11;
|
||||
using ANX.RenderSystem.Windows.Metro.Shader;
|
||||
|
||||
// This file is part of the ANX.Framework created by the
|
||||
@ -13,8 +12,7 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
public class EffectTechnique_Metro : INativeEffectTechnique
|
||||
{
|
||||
#region Private
|
||||
private Effect parentEffect;
|
||||
private List<EffectPass_Metro> passes;
|
||||
private EffectPass_Metro[] passes;
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
@ -24,6 +22,14 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
private set;
|
||||
}
|
||||
|
||||
public int PassCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return passes.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<EffectPass> Passes
|
||||
{
|
||||
get
|
||||
@ -34,33 +40,28 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public EffectPass_Metro this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return passes[index];
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public EffectTechnique_Metro(string setName, Effect setParentEffect,
|
||||
public EffectTechnique_Metro(string setName, Effect parentEffect,
|
||||
ExtendedShaderPass[] nativePasses)
|
||||
{
|
||||
Name = setName;
|
||||
parentEffect = setParentEffect;
|
||||
ParsePasses(nativePasses);
|
||||
Name = setName;
|
||||
|
||||
passes = new EffectPass_Metro[nativePasses.Length];
|
||||
for (int index = 0; index < nativePasses.Length; index++)
|
||||
{
|
||||
passes[index] = new EffectPass_Metro(parentEffect, nativePasses[index]);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ParsePasses
|
||||
private void ParsePasses(ExtendedShaderPass[] nativePasses)
|
||||
{
|
||||
passes = new List<EffectPass_Metro>();
|
||||
|
||||
foreach (ExtendedShaderPass pass in nativePasses)
|
||||
{
|
||||
passes.Add(new EffectPass_Metro(parentEffect, pass));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public EffectPass_Metro GetPass(int index)
|
||||
{
|
||||
return passes[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,10 +87,9 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
{
|
||||
techniques = new List<EffectTechnique>();
|
||||
|
||||
foreach (string key in shader.Techniques.Keys)
|
||||
foreach (string key in shader.TechniqueNames)
|
||||
{
|
||||
var nativeTechnique = new EffectTechnique_Metro(key, ManagedEffect,
|
||||
shader.Techniques[key]);
|
||||
var nativeTechnique = new EffectTechnique_Metro(key, ManagedEffect, shader[key]);
|
||||
techniques.Add(new EffectTechnique(ManagedEffect, nativeTechnique));
|
||||
}
|
||||
}
|
||||
@ -131,7 +130,9 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
#region Apply
|
||||
public void Apply(GraphicsDevice graphicsDevice)
|
||||
{
|
||||
((GraphicsDeviceWindowsMetro)graphicsDevice.NativeDevice).currentEffect = this;
|
||||
var metroDevice = (GraphicsDeviceWindowsMetro)graphicsDevice.NativeDevice;
|
||||
metroDevice.currentTechnique =
|
||||
ManagedEffect.CurrentTechnique.NativeTechnique as EffectTechnique_Metro;
|
||||
paramBuffer.Apply();
|
||||
}
|
||||
#endregion
|
||||
|
@ -18,7 +18,7 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
#endregion
|
||||
|
||||
#region Private
|
||||
internal Effect_Metro currentEffect;
|
||||
internal EffectTechnique_Metro currentTechnique;
|
||||
private VertexBuffer currentVertexBuffer;
|
||||
private Dx11.Viewport currentViewport;
|
||||
private uint lastClearColor;
|
||||
@ -121,52 +121,34 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
#region DrawIndexedPrimitives
|
||||
public void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex,
|
||||
int minVertexIndex, int numVertices, int startIndex, int primitiveCount)
|
||||
{
|
||||
var technique = currentEffect.ManagedEffect.CurrentTechnique;
|
||||
var nativeTechnique = technique.NativeTechnique as EffectTechnique_Metro;
|
||||
EffectPass_Metro nativePass = nativeTechnique.GetPass(0);
|
||||
|
||||
SetInputLayout(currentVertexBuffer.VertexDeclaration, nativePass);
|
||||
|
||||
var d3dContext = NativeDevice.NativeContext;
|
||||
d3dContext.InputAssembler.PrimitiveTopology = FormatConverter.Translate(primitiveType);
|
||||
d3dContext.VertexShader.Set(nativePass.VertexShader);
|
||||
d3dContext.PixelShader.Set(nativePass.PixelShader);
|
||||
|
||||
//d3dContext.PixelShader.SetSampler(0, sampler);
|
||||
|
||||
{
|
||||
SetInputLayout();
|
||||
ApplyPrimitiveType(primitiveType);
|
||||
NativeDevice.SetDefaultTargets();
|
||||
//d3dContext.PixelShader.SetSampler(0, sampler);
|
||||
|
||||
//for (int i = 0; i < technique.Description.PassCount; ++i)
|
||||
//{
|
||||
// pass.Apply();
|
||||
int indexCount = CalculateVertexCount(primitiveType, primitiveCount);
|
||||
d3dContext.DrawIndexed(indexCount, startIndex, baseVertex);
|
||||
//}
|
||||
for (int passIndex = 0; passIndex < currentTechnique.PassCount; passIndex++)
|
||||
{
|
||||
currentTechnique[passIndex].Apply(NativeDevice);
|
||||
NativeDevice.NativeContext.DrawIndexed(indexCount, startIndex, baseVertex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DrawPrimitives
|
||||
public void DrawPrimitives(PrimitiveType primitiveType, int vertexOffset, int primitiveCount)
|
||||
{
|
||||
var technique = currentEffect.ManagedEffect.CurrentTechnique;
|
||||
var nativeTechnique = technique.NativeTechnique as EffectTechnique_Metro;
|
||||
EffectPass_Metro nativePass = nativeTechnique.GetPass(0);
|
||||
|
||||
SetInputLayout(currentVertexBuffer.VertexDeclaration, nativePass);
|
||||
|
||||
var d3dContext = NativeDevice.NativeContext;
|
||||
d3dContext.InputAssembler.PrimitiveTopology = FormatConverter.Translate(primitiveType);
|
||||
d3dContext.VertexShader.Set(nativePass.VertexShader);
|
||||
d3dContext.PixelShader.Set(nativePass.PixelShader);
|
||||
|
||||
SetInputLayout();
|
||||
ApplyPrimitiveType(primitiveType);
|
||||
NativeDevice.SetDefaultTargets();
|
||||
//d3dContext.PixelShader.SetSampler(0, sampler);
|
||||
|
||||
//for (int i = 0; i < technique.Description.PassCount; ++i)
|
||||
//{
|
||||
// pass.Apply();
|
||||
d3dContext.Draw(primitiveCount, vertexOffset);
|
||||
//}
|
||||
for (int passIndex = 0; passIndex < currentTechnique.PassCount; passIndex++)
|
||||
{
|
||||
currentTechnique[passIndex].Apply(NativeDevice);
|
||||
NativeDevice.NativeContext.Draw(primitiveCount, vertexOffset);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -229,6 +211,14 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
}
|
||||
|
||||
#endregion // DrawUserPrimitives<T>
|
||||
|
||||
#region ApplyPrimitiveType
|
||||
private void ApplyPrimitiveType(PrimitiveType primitiveType)
|
||||
{
|
||||
var d3dContext = NativeDevice.NativeContext;
|
||||
d3dContext.InputAssembler.PrimitiveTopology = FormatConverter.Translate(primitiveType);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CalculateVertexCount
|
||||
private int CalculateVertexCount(PrimitiveType type, int primitiveCount)
|
||||
@ -306,9 +296,9 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
#endregion
|
||||
|
||||
#region SetInputLayout
|
||||
private void SetInputLayout(VertexDeclaration vertexDeclaration, EffectPass_Metro nativePass)
|
||||
private void SetInputLayout()
|
||||
{
|
||||
VertexElement[] vertexElements = vertexDeclaration.GetVertexElements();
|
||||
VertexElement[] vertexElements = currentVertexBuffer.VertexDeclaration.GetVertexElements();
|
||||
int elementCount = vertexElements.Length;
|
||||
var inputElements = new Dx11.InputElement[elementCount];
|
||||
|
||||
@ -317,6 +307,7 @@ namespace ANX.RenderSystem.Windows.Metro
|
||||
inputElements[i] = CreateInputElementFromVertexElement(vertexElements[i]);
|
||||
}
|
||||
|
||||
var nativePass = currentTechnique[0];
|
||||
NativeDevice.NativeContext.InputAssembler.InputLayout =
|
||||
nativePass.BuildLayout(NativeDevice.NativeDevice, inputElements);
|
||||
}
|
||||
|
@ -9,21 +9,47 @@ using System.IO;
|
||||
namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
{
|
||||
public class ExtendedShader
|
||||
{
|
||||
public Dictionary<string, ExtendedShaderPass[]> Techniques;
|
||||
public List<ExtendedShaderParameter> Parameters;
|
||||
{
|
||||
#region Private
|
||||
private Dictionary<string, ExtendedShaderPass[]> techniques;
|
||||
#endregion
|
||||
|
||||
public ExtendedShader(Stream stream)
|
||||
#region Public
|
||||
public ExtendedShaderPass[] this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
return techniques[name];
|
||||
}
|
||||
}
|
||||
|
||||
public string[] TechniqueNames
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<string>(techniques.Keys).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public ExtendedShaderParameter[] Parameters
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public ExtendedShader(Stream stream)
|
||||
{
|
||||
Techniques = new Dictionary<string, ExtendedShaderPass[]>();
|
||||
Parameters = new List<ExtendedShaderParameter>();
|
||||
techniques = new Dictionary<string, ExtendedShaderPass[]>();
|
||||
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
|
||||
int numberOfVariables = reader.ReadInt32();
|
||||
Parameters = new ExtendedShaderParameter[numberOfVariables];
|
||||
for (int index = 0; index < numberOfVariables; index++)
|
||||
{
|
||||
Parameters.Add(new ExtendedShaderParameter(reader));
|
||||
Parameters[index] = new ExtendedShaderParameter(reader);
|
||||
}
|
||||
|
||||
int numberOfStructures = reader.ReadInt32();
|
||||
@ -45,13 +71,14 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
string name = reader.ReadString();
|
||||
int numberOfPasses = reader.ReadInt32();
|
||||
ExtendedShaderPass[] passes = new ExtendedShaderPass[numberOfPasses];
|
||||
Techniques.Add(name, passes);
|
||||
techniques.Add(name, passes);
|
||||
|
||||
for (int passIndex = 0; passIndex < numberOfPasses; passIndex++)
|
||||
{
|
||||
passes[passIndex] = new ExtendedShaderPass(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,9 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
ArraySize = reader.ReadInt32();
|
||||
|
||||
IsTexture = Type.ToLower().Contains("texture");
|
||||
SizeInBytes = GetParameterTypeSize() * ArraySize;
|
||||
SizeInBytes = GetParameterTypeSize();
|
||||
if (ArraySize > 0)
|
||||
SizeInBytes *= ArraySize;
|
||||
|
||||
int numberOfDimensions = reader.ReadByte();
|
||||
TypeDimensions = new int[numberOfDimensions];
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dx11 = SharpDX.Direct3D11;
|
||||
|
||||
@ -16,8 +15,8 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
private NativeDxDevice graphicsDevice;
|
||||
private Effect_Metro parentEffect;
|
||||
|
||||
private Array[] setData;
|
||||
|
||||
private int[] parameterOffsets;
|
||||
private byte[] setData;
|
||||
private int dataSize;
|
||||
#endregion
|
||||
|
||||
@ -27,7 +26,20 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
{
|
||||
graphicsDevice = setGraphicsDevice;
|
||||
parentEffect = setParentEffect;
|
||||
setData = new Array[parentEffect.shader.Parameters.Count];
|
||||
dataSize = 0;
|
||||
|
||||
var offsets = new System.Collections.Generic.List<int>();
|
||||
foreach(var parameter in parentEffect.shader.Parameters)
|
||||
{
|
||||
if (parameter.IsTexture == false)
|
||||
{
|
||||
offsets.Add(dataSize);
|
||||
dataSize += parameter.SizeInBytes;
|
||||
}
|
||||
}
|
||||
|
||||
parameterOffsets = offsets.ToArray();
|
||||
setData = new byte[dataSize];
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -38,7 +50,8 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
if (indexOfParameter == -1)
|
||||
return;
|
||||
|
||||
setData[indexOfParameter] = StructureToBytes(value);
|
||||
byte[] dataToAdd = StructureToBytes(value);
|
||||
Array.Copy(dataToAdd, 0, setData, parameterOffsets[indexOfParameter], dataToAdd.Length);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -52,18 +65,15 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
value = FillArrayIfNeeded(value, indexOfParameter);
|
||||
|
||||
int sizePerItem = Marshal.SizeOf(typeof(T));
|
||||
byte[] result = new byte[sizePerItem * value.Length];
|
||||
int offset = 0;
|
||||
IntPtr ptr = Marshal.AllocHGlobal(sizePerItem);
|
||||
for (int index = 0; index < value.Length; index++)
|
||||
{
|
||||
Marshal.StructureToPtr(value[index], ptr, true);
|
||||
Marshal.Copy(ptr, result, offset, sizePerItem);
|
||||
Marshal.Copy(ptr, setData, parameterOffsets[indexOfParameter] + offset, sizePerItem);
|
||||
offset += sizePerItem;
|
||||
}
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
|
||||
setData[indexOfParameter] = result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -76,12 +86,8 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
|
||||
value = FillArrayIfNeeded(value, indexOfParameter);
|
||||
|
||||
byte[] convertData = null;
|
||||
byte[] result = UnionArraySerializer.Unify(value);
|
||||
convertData = new byte[result.Length];
|
||||
Array.Copy(result, convertData, result.Length);
|
||||
|
||||
setData[indexOfParameter] = convertData;
|
||||
byte[] result = UnionArraySerializer.Unify(value);
|
||||
Array.Copy(result, 0, setData, parameterOffsets[indexOfParameter], result.Length);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -94,12 +100,8 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
|
||||
value = FillArrayIfNeeded(value, indexOfParameter);
|
||||
|
||||
byte[] convertData = null;
|
||||
byte[] result = UnionArraySerializer.Unify(value);
|
||||
convertData = new byte[result.Length];
|
||||
Array.Copy(result, convertData, result.Length);
|
||||
|
||||
setData[indexOfParameter] = convertData;
|
||||
byte[] result = UnionArraySerializer.Unify(value);
|
||||
Array.Copy(result, 0, setData, parameterOffsets[indexOfParameter], result.Length);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -110,7 +112,7 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
if (indexOfParameter == -1)
|
||||
return;
|
||||
|
||||
setData[indexOfParameter] = value;
|
||||
Array.Copy(value, 0, setData, parameterOffsets[indexOfParameter], value.Length);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -178,41 +180,17 @@ namespace ANX.RenderSystem.Windows.Metro.Shader
|
||||
#region CreateBufferData
|
||||
private SharpDX.DataBox CreateBufferData()
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
BinaryWriter writer = new BinaryWriter(stream);
|
||||
|
||||
for(int index = 0; index < setData.Length; index++)
|
||||
{
|
||||
byte[] data = (byte[])setData[index];
|
||||
if (data != null)
|
||||
{
|
||||
writer.Write(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var parameter = parentEffect.shader.Parameters[index];
|
||||
if (parameter.IsTexture)
|
||||
continue;
|
||||
|
||||
writer.Write(new byte[parameter.SizeInBytes]);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] streamBytes = stream.ToArray();
|
||||
stream.Dispose();
|
||||
|
||||
IntPtr dataPtr;
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* ptr = &streamBytes[0])
|
||||
fixed (byte* ptr = &setData[0])
|
||||
{
|
||||
dataPtr = (IntPtr)ptr;
|
||||
}
|
||||
}
|
||||
|
||||
dataSize = streamBytes.Length;
|
||||
|
||||
setData = new Array[parentEffect.shader.Parameters.Count];
|
||||
// Reset really needed? evaluate
|
||||
setData = new byte[dataSize];
|
||||
return new SharpDX.DataBox(dataPtr);
|
||||
}
|
||||
#endregion
|
||||
|
Loading…
x
Reference in New Issue
Block a user