Modified:
/branches/lite/SlimDX.Toolkit/Drawing/CommonStates.cs
/branches/lite/SlimDX.Toolkit/Fonts/Font.cs
/branches/lite/SlimDX.Toolkit/Fonts/Internal/FontShaders.cs
/branches/lite/SlimDX.Toolkit/Fonts/Internal/RenderData.cs
/branches/lite/SlimDX.Toolkit/Fonts/Internal/VertexDrawer.cs
=======================================
--- /branches/lite/SlimDX.Toolkit/Drawing/CommonStates.cs Sat Mar 24
18:37:53 2012
+++ /branches/lite/SlimDX.Toolkit/Drawing/CommonStates.cs Sat Mar 24
20:12:36 2012
@@ -139,7 +139,7 @@
AddressV = addressMode,
AddressW = addressMode,
MaximumLod = float.MaxValue,
- MaximumAnisotropy = 16,
+ MaximumAnisotropy = filter == Filter.Anisotropic ?
device.FeatureLevel >= FeatureLevel.Level_9_2 ? 5 : 2 : 0,
ComparisonFunction = Comparison.Never
});
}
=======================================
--- /branches/lite/SlimDX.Toolkit/Fonts/Font.cs Sat Mar 24 18:37:53 2012
+++ /branches/lite/SlimDX.Toolkit/Fonts/Font.cs Sat Mar 24 20:12:36 2012
@@ -86,8 +86,8 @@
TextFormat defaultFormat;
TextRenderer renderer;
FeatureLevel featureLevel;
- RenderData renderStates;
VertexDrawer glyphDrawer;
+ bool anisotropic;
/// <summary>
/// Initializes a new instance of the <see cref="Font"/> class.
@@ -110,10 +110,11 @@
{
this.factory = factory;
featureLevel = device.FeatureLevel;
+ anisotropic = options.AnisotropicFiltering;
+
glyphAtlas = new GlyphAtlas(device, options.GlyphSheetWidth,
options.GlyphSheetHeight, options.MaxGlyphCountPerSheet, 4096);
glyphProvider = new GlyphProvider(factory, glyphAtlas,
options.MaxGlyphWidth, options.MaxGlyphHeight);
glyphDrawer = new VertexDrawer(device,
options.VertexBufferSize);
- renderStates = new RenderData(device,
options.AnisotropicFiltering);
renderer = new TextRenderer(glyphProvider);
if
(!string.IsNullOrEmpty(options.DefaultFontParameters.FontFamily))
@@ -138,8 +139,6 @@
glyphAtlas.Dispose();
if (glyphProvider != null)
glyphProvider.Dispose();
- if (renderStates != null)
- renderStates.Dispose();
if (glyphDrawer != null)
glyphDrawer.Dispose();
if (defaultFormat != null)
@@ -147,7 +146,6 @@
glyphAtlas = null;
glyphProvider = null;
- renderStates = null;
glyphDrawer = null;
defaultFormat = null;
}
@@ -312,16 +310,7 @@
unsafe void DrawGeometry(DeviceContext context, RectangleF*
clipBounds, Matrix* transformMatrix, TextOptions flags)
{
using (new StateSaver(context, (flags &
TextOptions.RestoreState) != 0))
- {
- // set states and shaders
- if ((flags & TextOptions.StatePrepared) == 0)
- renderStates.SetStates(context, flags);
- if ((flags & TextOptions.ConstantsPrepared) == 0)
- renderStates.UpdateShaderConstants(context,
clipBounds, transformMatrix);
-
- // draw glyphs
- glyphDrawer.DrawVertices(context, glyphAtlas,
renderer.SortVertices(), flags);
- }
+ glyphDrawer.DrawVertices(context, glyphAtlas,
renderer.SortVertices(), anisotropic, clipBounds, transformMatrix, flags);
}
}
}
=======================================
--- /branches/lite/SlimDX.Toolkit/Fonts/Internal/FontShaders.cs Sat Mar 24
18:37:53 2012
+++ /branches/lite/SlimDX.Toolkit/Fonts/Internal/FontShaders.cs Sat Mar 24
20:12:36 2012
@@ -10,16 +10,6 @@
{
static class FontShaders
{
- public const string EmptyVertexShader = @"
-struct GSIn {
- float3 PositionIndex : POSITIONINDEX;
- float4 GlyphColor : GLYPHCOLOR;
-};
-
-GSIn VS(GSIn Input) {
- return Input;
-}
-";
public const string SimpleVertexShader = @"
cbuffer ShaderConstants : register(b0) {
float4x4 TransformMatrix : packoffset(c0);
@@ -74,112 +64,6 @@
return Output;
}
-";
- public const string SimpleGeometryShader = @"
-cbuffer ShaderConstants : register(b0) {
- float4x4 TransformMatrix : packoffset(c0);
-};
-
-Buffer<float4> tex0 : register(t0);
-
-struct GSIn {
- float3 PositionIndex : POSITIONINDEX;
- float4 GlyphColor : GLYPHCOLOR;
-};
-
-struct GSOut {
- float4 Position : SV_Position;
- float4 GlyphColor : COLOR;
- float2 TexCoord : TEXCOORD;
-};
-
-[maxvertexcount(4)]
-void GS(point GSIn Input[1], inout TriangleStream<GSOut> TriStream) {
- const float2 basePosition = Input[0].PositionIndex.xy;
- const uint glyphIndex = asuint(Input[0].PositionIndex.z);
-
- float4 texCoords = tex0.Load(uint2(glyphIndex*2, 0));
- float4 offsets = tex0.Load(uint2(glyphIndex*2+1, 0));
-
- GSOut Output;
- Output.GlyphColor = Input[0].GlyphColor;
-
- float4 positions = basePosition.xyxy + offsets;
-
- Output.Position = mul(TransformMatrix, float4(positions.xy, 0.0f, 1.0f));
- Output.TexCoord = texCoords.xy;
- TriStream.Append(Output);
-
- Output.Position = mul(TransformMatrix, float4(positions.zy, 0.0f, 1.0f));
- Output.TexCoord = texCoords.zy;
- TriStream.Append(Output);
-
- Output.Position = mul(TransformMatrix, float4(positions.xw, 0.0f, 1.0f));
- Output.TexCoord = texCoords.xw;
- TriStream.Append(Output);
-
- Output.Position = mul(TransformMatrix, float4(positions.zw, 0.0f, 1.0f));
- Output.TexCoord = texCoords.zw;
- TriStream.Append(Output);
-
- TriStream.RestartStrip();
-}
-";
- public const string ClippingGeometryShader = @"
-cbuffer ShaderConstants : register(b0) {
- float4x4 TransformMatrix : packoffset(c0);
- float4 ClipRect : packoffset(c4);
-};
-
-Buffer<float4> tex0 : register(t0);
-
-struct GSIn {
- float3 PositionIndex : POSITIONINDEX;
- float4 GlyphColor : GLYPHCOLOR;
-};
-
-struct GSOut {
- float4 Position : SV_Position;
- float4 GlyphColor : COLOR;
- float2 TexCoord : TEXCOORD;
- float4 ClipDistance : SV_ClipDistance;
-};
-
-[maxvertexcount(4)]
-void GS(point GSIn Input[1], inout TriangleStream<GSOut> TriStream) {
- const float2 basePosition = Input[0].PositionIndex.xy;
- const uint glyphIndex = asuint(Input[0].PositionIndex.z);
-
- float4 texCoords = tex0.Load(uint2(glyphIndex*2, 0));
- float4 offsets = tex0.Load(uint2(glyphIndex*2+1, 0));
-
- GSOut Output;
- Output.GlyphColor = Input[0].GlyphColor;
-
- float4 positions = basePosition.xyxy + offsets;
-
- Output.Position = mul(TransformMatrix, float4(positions.xy, 0.0f, 1.0f));
- Output.TexCoord = texCoords.xy;
- Output.ClipDistance = ClipRect + float4(positions.xy, -positions.xy);
- TriStream.Append(Output);
-
- Output.Position = mul(TransformMatrix, float4(positions.zy, 0.0f, 1.0f));
- Output.TexCoord = texCoords.zy;
- Output.ClipDistance = ClipRect + float4(positions.zy, -positions.zy);
- TriStream.Append(Output);
-
- Output.Position = mul(TransformMatrix, float4(positions.xw, 0.0f, 1.0f));
- Output.TexCoord = texCoords.xw;
- Output.ClipDistance = ClipRect + float4(positions.xw, -positions.xw);
- TriStream.Append(Output);
-
- Output.Position = mul(TransformMatrix, float4(positions.zw, 0.0f, 1.0f));
- Output.TexCoord = texCoords.zw;
- Output.ClipDistance = ClipRect + float4(positions.zw, -positions.zw);
- TriStream.Append(Output);
-
- TriStream.RestartStrip();
-}
";
public const string SimplePixelShader = @"
SamplerState sampler0 : register(s0);
=======================================
--- /branches/lite/SlimDX.Toolkit/Fonts/Internal/RenderData.cs Sat Mar 24
18:37:53 2012
+++ /branches/lite/SlimDX.Toolkit/Fonts/Internal/RenderData.cs Sat Mar 24
20:12:36 2012
@@ -14,19 +14,18 @@
namespace SlimDX.Toolkit
{
+ /// <summary>
+ /// Contains D3D resources used for rendering fonts. Shared between
fonts.
+ /// </summary>
class RenderData : IDisposable
{
[StructLayout(LayoutKind.Sequential)]
struct ShaderConstants
{
- public static readonly int SizeInBytes =
Marshal.SizeOf(typeof(ShaderConstants));
-
public Matrix Transform;
public RectangleF ClipRect;
}
- HashSet<IDisposable> resources = new HashSet<IDisposable>(); //
I'm lazy
- Device device;
FeatureLevel featureLevel;
VertexShader simpleVertexShader;
VertexShader clippingVertexShader;
@@ -34,30 +33,54 @@
PixelShader clippingPixelShader;
InputLayout inputLayout;
ConstantBuffer<ShaderConstants> constantBuffer;
- BlendState blendState;
- SamplerState samplerState;
- DepthStencilState depthStencilState;
- RasterizerState rasterizerState;
-
- public RenderData(Device device, bool anisotropicFiltering)
- {
- this.device = device;
+ CommonStates states;
+ bool disposed;
+
+ public RenderData(Device device)
+ {
featureLevel = device.FeatureLevel;
- CreateQuadShaders();
- CreatePixelShaders();
- CreateConstantBuffer();
- CreateRenderStates(anisotropicFiltering);
+ // compile vertex shaders
+ using (var bytecode =
ShaderBytecode.Compile(FontShaders.SimpleVertexShader, "VS",
device.VertexShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
+ {
+ simpleVertexShader = new VertexShader(device, bytecode);
+ inputLayout = new InputLayout(device, bytecode, new[] {
+ new InputElement("POSITION", 0,
Format.R32G32B32A32_Float, 0),
+ new InputElement("GLYPHCOLOR", 0,
Format.R8G8B8A8_UNorm, 0)
+ });
+ }
+
+ using (var bytecode =
ShaderBytecode.Compile(FontShaders.ClippingVertexShader, "VS",
device.VertexShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
+ clippingVertexShader = new VertexShader(device, bytecode);
+
+ // compile pixel shaders
+ using (var bytecode =
ShaderBytecode.Compile(FontShaders.SimplePixelShader, "PS",
device.PixelShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
+ simplePixelShader = new PixelShader(device, bytecode);
+
+ using (var bytecode =
ShaderBytecode.Compile(FontShaders.ClippingPixelShader, "PS",
device.PixelShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
+ clippingPixelShader = new PixelShader(device, bytecode);
+
+ constantBuffer = new ConstantBuffer<ShaderConstants>(device);
+ states = new CommonStates(device);
}
public void Dispose()
{
- foreach (var resource in resources)
- resource.Dispose();
- resources.Clear();
+ if (disposed)
+ return;
+
+ disposed = true;
+
+ simpleVertexShader.Dispose();
+ clippingVertexShader.Dispose();
+ simplePixelShader.Dispose();
+ clippingPixelShader.Dispose();
+ inputLayout.Dispose();
+ constantBuffer.Dispose();
+ states.Dispose();
}
- public void SetStates(DeviceContext context, TextOptions flags)
+ public void SetStates(DeviceContext context, bool
anisotropicFiltering, TextOptions flags)
{
// quads constructed on the CPU
context.InputAssembler.PrimitiveTopology =
PrimitiveTopology.TriangleList;
@@ -77,10 +100,10 @@
}
// set render states
- context.OutputMerger.SetBlendState(blendState, new Color4(0),
-1);
- context.OutputMerger.SetDepthStencilState(depthStencilState,
0);
- context.Rasterizer.State = rasterizerState;
- context.PixelShader.SetSampler(samplerState, 0);
+ context.OutputMerger.SetBlendState(states.AlphaBlend, new
Color4(0), -1);
+ context.OutputMerger.SetDepthStencilState(states.DepthNone, 0);
+ context.Rasterizer.State = states.CullNone;
+ context.PixelShader.SetSampler(anisotropicFiltering ?
states.AnisotropicClamp : states.LinearClamp, 0);
}
public unsafe void UpdateShaderConstants(DeviceContext context,
RectangleF* clipRect, Matrix* transform)
@@ -119,92 +142,5 @@
constantBuffer.SetData(context, ref constants);
}
-
- void CreateQuadShaders()
- {
- // compile vertex shaders
- using (var bytecode =
ShaderBytecode.Compile(FontShaders.SimpleVertexShader, "VS",
device.VertexShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
- {
- simpleVertexShader = new VertexShader(device, bytecode);
- inputLayout = new InputLayout(device, bytecode, new[] {
- new InputElement("POSITION", 0,
Format.R32G32B32A32_Float, 0),
- new InputElement("GLYPHCOLOR", 0,
Format.R8G8B8A8_UNorm, 0)
- });
- }
-
- using (var bytecode =
ShaderBytecode.Compile(FontShaders.ClippingVertexShader, "VS",
device.VertexShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
- clippingVertexShader = new VertexShader(device, bytecode);
-
- resources.Add(simpleVertexShader);
- resources.Add(inputLayout);
- resources.Add(clippingVertexShader);
- }
-
- void CreatePixelShaders()
- {
- // compile pixel shaders
- using (var bytecode =
ShaderBytecode.Compile(FontShaders.SimplePixelShader, "PS",
device.PixelShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
- simplePixelShader = new PixelShader(device, bytecode);
-
- using (var bytecode =
ShaderBytecode.Compile(FontShaders.ClippingPixelShader, "PS",
device.PixelShaderProfile, ShaderFlags.OptimizationLevel3,
EffectFlags.None))
- clippingPixelShader = new PixelShader(device, bytecode);
-
- resources.Add(simplePixelShader);
- resources.Add(clippingPixelShader);
- }
-
- void CreateConstantBuffer()
- {
- constantBuffer = new ConstantBuffer<ShaderConstants>(device);
- resources.Add(constantBuffer);
- }
-
- void CreateRenderStates(bool anisotropicFiltering)
- {
- var blendDesc = new BlendStateDescription();
- for (int i = 0; i < 4; i++)
- {
- blendDesc.RenderTargets[i] = new
RenderTargetBlendDescription
- {
- BlendEnable = true,
- SourceBlend = BlendOption.One,
- DestinationBlend = BlendOption.InverseSourceAlpha,
- BlendOperation = BlendOperation.Add,
- SourceBlendAlpha = BlendOption.One,
- DestinationBlendAlpha = BlendOption.Zero,
- BlendOperationAlpha = BlendOperation.Add,
- RenderTargetWriteMask = ColorWriteMaskFlags.All
- };
- }
-
- blendState = BlendState.FromDescription(device, blendDesc);
- samplerState = SamplerState.FromDescription(device, new
SamplerDescription
- {
- AddressU = TextureAddressMode.Clamp,
- AddressV = TextureAddressMode.Clamp,
- AddressW = TextureAddressMode.Clamp,
- MaximumLod = float.MaxValue,
- Filter = anisotropicFiltering ? Filter.Anisotropic :
Filter.MinMagMipLinear,
- MaximumAnisotropy = anisotropicFiltering ? featureLevel >=
FeatureLevel.Level_9_2 ? 5 : 2 : 0
- });
-
- rasterizerState = RasterizerState.FromDescription(device, new
RasterizerStateDescription
- {
- FillMode = FillMode.Solid,
- CullMode = CullMode.None,
- IsFrontCounterclockwise = false,
- IsDepthClipEnabled = true
- });
-
- depthStencilState = DepthStencilState.FromDescription(device,
new DepthStencilStateDescription
- {
- IsDepthEnabled = false
- });
-
- resources.Add(blendState);
- resources.Add(samplerState);
- resources.Add(rasterizerState);
- resources.Add(depthStencilState);
- }
}
}
=======================================
--- /branches/lite/SlimDX.Toolkit/Fonts/Internal/VertexDrawer.cs Sat Mar 24
18:37:53 2012
+++ /branches/lite/SlimDX.Toolkit/Fonts/Internal/VertexDrawer.cs Sat Mar 24
20:12:36 2012
@@ -7,6 +7,7 @@
using Device = SlimDX.Direct3D11.Device;
using MapFlags = SlimDX.Direct3D11.MapFlags;
using System.Runtime.InteropServices;
+using System.Drawing;
namespace SlimDX.Toolkit
{
@@ -15,6 +16,8 @@
/// </summary>
class VertexDrawer : IDisposable
{
+ static SharedResourcePool<Device, RenderData> sharedRenderData =
new SharedResourcePool<Device, RenderData>();
+
[StructLayout(LayoutKind.Sequential)]
struct QuadVertex
{
@@ -25,6 +28,7 @@
public int Color;
}
+ ISharedResource<RenderData> renderData;
Buffer vertexBuffer;
Buffer indexBuffer;
int bufferSize = 4096 * 16;
@@ -71,22 +75,32 @@
BindFlags = BindFlags.IndexBuffer
});
}
+
+ renderData = sharedRenderData.DemandCreate(device, () => new
RenderData(device));
}
public void Dispose()
{
if (vertexBuffer != null)
vertexBuffer.Dispose();
-
if (indexBuffer != null)
indexBuffer.Dispose();
+ if (renderData != null)
+ renderData.Release();
vertexBuffer = null;
indexBuffer = null;
+ renderData = null;
}
- public void DrawVertices(DeviceContext context, GlyphAtlas
glyphAtlas, IList<GlyphVertex> vertexData, TextOptions flags)
- {
+ public unsafe void DrawVertices(DeviceContext context, GlyphAtlas
glyphAtlas, IList<GlyphVertex> vertexData, bool anisotropic, RectangleF*
clipBounds, Matrix* transformMatrix, TextOptions flags)
+ {
+ // set states and shaders
+ if ((flags & TextOptions.StatePrepared) == 0)
+ renderData.Resource.SetStates(context, anisotropic, flags);
+ if ((flags & TextOptions.ConstantsPrepared) == 0)
+ renderData.Resource.UpdateShaderConstants(context,
clipBounds, transformMatrix);
+
if ((flags & TextOptions.BuffersPrepared) == 0)
{
context.InputAssembler.SetIndexBuffer(indexBuffer,
Format.R16_UInt, 0);