1using System.Runtime.InteropServices;
3using SharpDX.D3DCompiler;
5using SharpDX.Direct3D11;
7using Device = SharpDX.Direct3D11.Device;
8using Device2 = SharpDX.Direct3D11.Device2;
59 FeatureLevel.Level_9_1
64 throw new InvalidOperationException(
"Failed to get window handle");
67 DeviceCreationFlags deviceCreationFlags = DeviceCreationFlags.Debug;
69 DeviceCreationFlags deviceCreationFlags = DeviceCreationFlags.None;
71 using (
Device device =
new(
79 FeatureLevel.Level_9_1
85 SwapChainDescription1 swapChainDescription =
new() {
86 AlphaMode = AlphaMode.Ignore,
88 Format = Format.R8G8B8A8_UNorm,
91 SampleDescription =
new SampleDescription(1, 0),
92 Scaling = Scaling.Stretch,
94 SwapEffect = SwapEffect.FlipSequential,
95 Usage = Usage.RenderTargetOutput
98 using (Factory3 parent = device2.Adapter.GetParent<Factory3>()) {
99 using (SwapChain1 swapChain =
new(parent,
Device,
Window.
Handle, ref swapChainDescription)) {
100 SwapChain = swapChain.QueryInterface<SwapChain2>();
103 device2.MaximumFrameLatency = 1;
120 Display.DeviceDescription =
121 $
"DX11 Metro, FeatureLevel={FeatureLevel}, Debug={Context.Device.CreationFlags.HasFlag(DeviceCreationFlags.Debug)}, ReqTexture2DUOrVDimension={(REQ_TEXTURE2D_U_OR_V_DIMENSION > 0 ? REQ_TEXTURE2D_U_OR_V_DIMENSION : "unknown
")}";
132 DeviceDebug deviceDebug =
null;
133 if ((
Device.CreationFlags & DeviceCreationFlags.Debug) != DeviceCreationFlags.None) {
134 deviceDebug =
new DeviceDebug(
Device);
138 rasterizerState.Dispose();
142 depthStencilState.Dispose();
145 foreach (SharpDX.Direct3D11.BlendState blendState in
m_dxBlendStates.Values) {
146 blendState.Dispose();
149 foreach (SharpDX.Direct3D11.SamplerState samplerState in
m_dxSamplerStates.Values) {
150 samplerState.Dispose();
176 if (deviceDebug !=
null) {
177 deviceDebug.ReportLiveDeviceObjects(ReportingLevel.Detail);
178 deviceDebug.Dispose();
197 public static void Present(
int presentationInterval) {
199 SwapChain.Present(presentationInterval, PresentFlags.None);
207 catch (SharpDXException ex) {
208 if (ex.HResult ==
ResultCode.DeviceRemoved.Code
209 || ex.HResult ==
ResultCode.DeviceReset.Code) {
213 Log.
Error(
"SwapChain.Present failed. Reason: {0}", ex.Message);
216 catch (Exception ex2) {
217 Log.
Error(
"SwapChain.Present failed. Reason: {0}", ex2.Message);
223 public static int AppendUserVertices<T>(T[] vertices,
int vertexStride,
int startVertex,
int verticesCount) where T :
struct {
224 int num = vertexStride * startVertex;
225 int num2 = vertexStride * verticesCount;
233 new BufferDescription {
234 BindFlags = BindFlags.VertexBuffer,
235 Usage = ResourceUsage.Dynamic,
236 CpuAccessFlags = CpuAccessFlags.Write,
243 GCHandle gchandle = GCHandle.Alloc(vertices, GCHandleType.Pinned);
249 return userVertexBufferOffset;
252 GCHandle gchandle2 = GCHandle.Alloc(vertices, GCHandleType.Pinned);
253 CopyMemory(gchandle2.AddrOfPinnedObject() + num, dataBox2.DataPointer, num2);
260 public static int AppendUserIndices(
int[] indices,
int indexStride,
int startIndex,
int indicesCount) {
261 int num = indexStride * startIndex;
262 int num2 = indexStride * indicesCount;
270 new BufferDescription {
271 BindFlags = BindFlags.IndexBuffer,
272 Usage = ResourceUsage.Dynamic,
273 CpuAccessFlags = CpuAccessFlags.Write,
280 GCHandle gchandle = GCHandle.Alloc(indices, GCHandleType.Pinned);
286 return userIndexBufferOffset;
289 GCHandle gchandle2 = GCHandle.Alloc(indices, GCHandleType.Pinned);
290 CopyMemory(gchandle2.AddrOfPinnedObject() + num, dataBox2.DataPointer, num2);
305 Context.Rasterizer.SetScissorRectangle(
306 scissorRectangle.
Left,
307 scissorRectangle.
Top,
308 scissorRectangle.
Left + scissorRectangle.
Width,
309 scissorRectangle.
Top + scissorRectangle.
Height
317 if (!
m_dxRasterizerStates.TryGetValue(rasterizerState, out SharpDX.Direct3D11.RasterizerState rasterizerState2)) {
318 RasterizerStateDescription rasterizerStateDescription = RasterizerStateDescription.Default();
319 rasterizerStateDescription.FillMode = FillMode.Solid;
321 case CullMode.None: rasterizerStateDescription.CullMode = SharpDX.Direct3D11.CullMode.None;
break;
323 rasterizerStateDescription.CullMode = SharpDX.Direct3D11.CullMode.Back;
324 rasterizerStateDescription.IsFrontCounterClockwise =
true;
327 rasterizerStateDescription.CullMode = SharpDX.Direct3D11.CullMode.Back;
328 rasterizerStateDescription.IsFrontCounterClockwise =
false;
330 default:
throw new InvalidOperationException(
"Unsupported cull mode.");
332 rasterizerStateDescription.DepthBias = (int)rasterizerState.
DepthBias;
333 rasterizerStateDescription.DepthBiasClamp = 0f;
335 rasterizerStateDescription.IsDepthClipEnabled =
true;
337 rasterizerStateDescription.IsMultisampleEnabled =
false;
338 rasterizerStateDescription.IsAntialiasedLineEnabled =
false;
339 rasterizerState2 =
new SharpDX.Direct3D11.RasterizerState(
Device, rasterizerStateDescription);
342 Context.Rasterizer.State = rasterizerState2;
349 if (!
m_dxDepthStencilStates.TryGetValue(depthStencilState, out SharpDX.Direct3D11.DepthStencilState depthStencilState2)) {
350 DepthStencilStateDescription depthStencilStateDescription = DepthStencilStateDescription.Default();
351 depthStencilStateDescription.IsStencilEnabled =
false;
352 depthStencilStateDescription.IsDepthEnabled = depthStencilState.DepthBufferTestEnable || depthStencilState.
DepthBufferWriteEnable;
353 depthStencilStateDescription.DepthWriteMask = depthStencilState.DepthBufferWriteEnable ? DepthWriteMask.All : DepthWriteMask.Zero;
354 depthStencilStateDescription.DepthComparison = depthStencilState.DepthBufferTestEnable
357 depthStencilState2 =
new SharpDX.Direct3D11.DepthStencilState(
Device, depthStencilStateDescription);
360 Context.OutputMerger.SetDepthStencilState(depthStencilState2);
367 if (!
m_dxBlendStates.TryGetValue(blendState, out SharpDX.Direct3D11.BlendState blendState2)) {
368 BlendStateDescription blendStateDescription = BlendStateDescription.Default();
369 blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
376 blendStateDescription.RenderTarget[0].IsBlendEnabled =
false;
379 blendStateDescription.RenderTarget[0].IsBlendEnabled =
true;
387 blendState2 =
new SharpDX.Direct3D11.BlendState(
Device, blendStateDescription);
391 Context.OutputMerger.SetBlendState(blendState2, color);
412 if (renderTarget !=
null) {
415 Context.OutputMerger.SetRenderTargets(renderTarget.m_depthTextureView, renderTarget.m_colorTextureView);
426 InputLayout inputLayout;
427 if (vertexDeclaration == shader.m_lastVertexDeclaration) {
428 inputLayout = shader.m_lastInputLayout;
431 if (!shader.m_inputLayouts.TryGetValue(vertexDeclaration, out inputLayout)) {
432 InputElement[] array =
new InputElement[vertexDeclaration.
m_elements.Length];
433 for (
int i = 0; i < array.Length; i++) {
435 array[i] =
new InputElement {
437 AlignedByteOffset = vertexElement.
Offset,
439 Classification = InputClassification.PerVertexData,
441 SemanticIndex = vertexElement.SemanticIndex
444 inputLayout =
new InputLayout(
Device, shader.m_vertexShaderBytecode, array);
445 shader.m_inputLayouts.Add(vertexDeclaration, inputLayout);
447 shader.m_lastVertexDeclaration = vertexDeclaration;
448 shader.m_lastInputLayout = inputLayout;
451 Context.InputAssembler.InputLayout = inputLayout;
465 if (shaderParameter.VsResourceBindingSlot != -1) {
466 Context.VertexShader.SetShaderResource(
467 shaderParameter.VsResourceBindingSlot,
468 texture2D !=
null ? texture2D.m_textureView :
null
471 if (shaderParameter.PsResourceBindingSlot != -1) {
472 Context.PixelShader.SetShaderResource(
473 shaderParameter.PsResourceBindingSlot,
474 texture2D !=
null ? texture2D.m_textureView :
null
477 shaderParameter.IsChanged =
false;
485 if (samplerState !=
null) {
486 if (shaderParameter.VsResourceBindingSlot != -1) {
489 if (shaderParameter.PsResourceBindingSlot != -1) {
493 shaderParameter.IsChanged =
false;
497 if (shaderParameter.VsBufferIndex != -1
498 &&
m_dataPointers[shaderParameter.VsBufferIndex] == IntPtr.Zero) {
499 SharpDX.Direct3D11.Buffer buffer = shader.m_allConstantBuffers[shaderParameter.VsBufferIndex];
503 if (shaderParameter.PsBufferIndex != -1
504 &&
m_dataPointers[shaderParameter.PsBufferIndex] == IntPtr.Zero) {
505 SharpDX.Direct3D11.Buffer buffer2 = shader.m_allConstantBuffers[shaderParameter.PsBufferIndex];
509 shaderParameter.IsChanged =
false;
512 for (
int k = 0; k < shader.m_allConstantBuffers.Length; k++) {
515 Context.UnmapSubresource(shader.m_allConstantBuffers[k], 0);
522 if (shader.m_vertexShaderConstantBuffers.Length != 0) {
523 Context.VertexShader.SetConstantBuffers(0, shader.m_vertexShaderConstantBuffers);
529 if (shader.m_pixelShaderConstantBuffers.Length != 0) {
530 Context.PixelShader.SetConstantBuffers(0, shader.m_pixelShaderConstantBuffers);
535 public static void ApplyVertexBuffer(SharpDX.Direct3D11.Buffer vertexBuffer,
int vertexStride,
int vertexOffset) {
539 Context.InputAssembler.SetVertexBuffers(0,
new VertexBufferBinding(vertexBuffer, vertexStride, vertexOffset));
546 public static void ApplyIndexBuffer(SharpDX.Direct3D11.Buffer indexBuffer, Format format,
int indexOffset) {
549 Context.InputAssembler.SetIndexBuffer(indexBuffer, format, indexOffset);
558 Context.InputAssembler.PrimitiveTopology = primitiveTopology;
564 if (!
m_dxSamplerStates.TryGetValue(samplerState, out SharpDX.Direct3D11.SamplerState samplerState2)) {
565 SamplerStateDescription samplerStateDescription = SamplerStateDescription.Default();
568 samplerStateDescription.AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap;
569 samplerStateDescription.MaximumAnisotropy = samplerState.
MaxAnisotropy;
571 samplerStateDescription.MinimumLod = samplerState.
MinLod;
572 samplerStateDescription.MaximumLod = samplerState.
MaxLod;
574 samplerStateDescription.MipLodBias = samplerState.
MipLodBias;
575 samplerStateDescription.ComparisonFunction = Comparison.Always;
576 samplerStateDescription.BorderColor =
new Color4(0f, 0f, 0f, 1f);
578 samplerState2 =
new SharpDX.Direct3D11.SamplerState(
Device, samplerStateDescription);
581 return samplerState2;
585 switch (primitiveType) {
586 case PrimitiveType.LineList:
return PrimitiveTopology.LineList;
587 case PrimitiveType.LineStrip:
return PrimitiveTopology.LineStrip;
588 case PrimitiveType.TriangleList:
return PrimitiveTopology.TriangleList;
589 case PrimitiveType.TriangleStrip:
return PrimitiveTopology.TriangleStrip;
590 default:
throw new InvalidOperationException(
"Unsupported primitive type.");
595 return description.Type
switch {
596 ShaderVariableType.Float when description.Class == ShaderVariableClass.Scalar =>
ShaderParameterType.Float,
597 ShaderVariableType.Float when description is { Class: ShaderVariableClass.Vector, ColumnCount: 2 } =>
ShaderParameterType.Vector2,
598 ShaderVariableType.Float when description is { Class: ShaderVariableClass.Vector, ColumnCount: 3 } =>
ShaderParameterType.Vector3,
599 ShaderVariableType.Float when description is { Class: ShaderVariableClass.Vector, ColumnCount: 4 } =>
ShaderParameterType.Vector4,
600 ShaderVariableType.Float when description is { Class: ShaderVariableClass.MatrixColumns, RowCount: 4, ColumnCount: 4 } =>
602 _ =>
throw new InvalidOperationException(
603 string.Format(
"Variable \"{0}\" uses unsupported shader variable type.",
new object[] { description.Name })
609 if (description is { Type: ShaderInputType.Texture, Dimension: ShaderResourceViewDimension.Texture2D, BindCount: 1 }) {
612 if (description is { Type: ShaderInputType.Sampler, BindCount: 1 }) {
615 throw new InvalidOperationException(
616 string.Format(
"Shader resource \"{0}\" uses unsupported shader resource type.",
new object[] { description.Name })
621 switch (vertexElementFormat) {
632 default:
throw new InvalidOperationException(
"Unsupported VertexElementFormat.");
638 return Format.R16_UInt;
641 throw new InvalidOperationException(
"Unsupported IndexFormat.");
643 return Format.R32_UInt;
647 switch (colorFormat) {
648 case ColorFormat.Rgba8888:
return Format.R8G8B8A8_UNorm;
649 case ColorFormat.Rgba5551:
return Format.B5G5R5A1_UNorm;
650 case ColorFormat.Rgb565:
return Format.B5G6R5_UNorm;
653 case ColorFormat.RG32f:
return Format.R32G32_Float;
654 case ColorFormat.RGBA32f:
return Format.R32G32B32A32_Float;
655 default:
throw new InvalidOperationException(
"Unsupported ColorFormat.");
661 return Format.D16_UNorm;
664 throw new InvalidOperationException(
"Unsupported DepthFormat.");
666 return Format.D24_UNorm_S8_UInt;
670 switch (blendFunction) {
673 case BlendFunction.ReverseSubtract:
return BlendOperation.ReverseSubtract;
674 default:
throw new InvalidOperationException(
"Unsupported BlendFunction.");
680 case Blend.Zero:
return BlendOption.Zero;
681 case Blend.One:
return BlendOption.One;
682 case Blend.SourceColor:
return BlendOption.SourceColor;
683 case Blend.InverseSourceColor:
return BlendOption.InverseSourceColor;
684 case Blend.DestinationColor:
return BlendOption.DestinationColor;
685 case Blend.InverseDestinationColor:
return BlendOption.InverseDestinationColor;
686 case Blend.SourceAlpha:
return BlendOption.SourceAlpha;
687 case Blend.InverseSourceAlpha:
return BlendOption.InverseSourceAlpha;
688 case Blend.DestinationAlpha:
return BlendOption.DestinationAlpha;
689 case Blend.InverseDestinationAlpha:
return BlendOption.InverseDestinationAlpha;
690 case Blend.BlendFactor:
return BlendOption.BlendFactor;
691 case Blend.InverseBlendFactor:
return BlendOption.InverseBlendFactor;
692 case Blend.SourceAlphaSaturation:
return BlendOption.SourceAlphaSaturate;
693 default:
throw new InvalidOperationException(
"Unsupported Blend.");
698 switch (textureAddressMode) {
701 case TextureAddressMode.MirrorWrap:
return SharpDX.Direct3D11.TextureAddressMode.Mirror;
702 default:
throw new InvalidOperationException(
"Unsupported TextureAddressMode.");
707 switch (textureFilterMode) {
713 case TextureFilterMode.MinPointMagLinearMipPoint:
return Filter.MinPointMagLinearMipPoint;
714 case TextureFilterMode.MinPointMagLinearMipLinear:
return Filter.MinPointMagMipLinear;
715 case TextureFilterMode.MinLinearMagPointMipPoint:
return Filter.MinLinearMagMipPoint;
716 case TextureFilterMode.MinLinearMagPointMipLinear:
return Filter.MinLinearMagPointMipLinear;
717 default:
throw new InvalidOperationException(
"Unsupported TextureFilterMode.");
722 switch (compareFunction) {
731 default:
throw new InvalidOperationException(
"Unsupported CompareFunction.");
737 using (SharpDX.Direct3D11.Texture2D backBuffer =
SwapChain.GetBackBuffer<SharpDX.Direct3D11.Texture2D>(0)) {
739 point =
new Point2(backBuffer.Description.Width, backBuffer.Description.Height);
741 Texture2DDescription texture2DDescription =
new() {
743 BindFlags = BindFlags.DepthStencil,
744 CpuAccessFlags = CpuAccessFlags.None,
747 OptionFlags = ResourceOptionFlags.None,
748 SampleDescription =
new SampleDescription(1, 0),
749 Usage = ResourceUsage.Default,
753 using (SharpDX.Direct3D11.Texture2D texture2D =
new(
Device, texture2DDescription)) {
764 int* ptr = (
int*)source.ToPointer();
765 int* ptr2 = (
int*)((
byte*)source.ToPointer() + (IntPtr)(count / 4) * 4);
766 int* ptr3 = (
int*)destination.ToPointer();
772 byte* ptr4 = (
byte*)ptr;
773 byte* ptr5 = (
byte*)source.ToPointer() + count;
774 byte* ptr6 = (
byte*)ptr3;
775 while (ptr4 < ptr5) {
793 catch (Exception ex) {
794 Log.
Error(
"Failed to recreate graphics device. Reason: {0}", ex.Message);
SharpDX.DXGI.ResultCode ResultCode
SharpDX.DXGI.Device3 Device3
SharpDX.Direct3D11.MapFlags MapFlags
SharpDX.Direct3D11.Device2 Device2
SharpDX.Direct3D11.Device Device
Blend ColorDestinationBlend
BlendFunction AlphaBlendFunction
BlendFunction ColorBlendFunction
Blend AlphaDestinationBlend
static void ApplyPsSamplerState(int slot, SamplerState samplerState)
static Dictionary< RasterizerState, SharpDX.Direct3D11.RasterizerState > m_dxRasterizerStates
static DepthStencilView DepthBufferView
static PrimitiveTopology TranslatePrimitiveType(PrimitiveType primitiveType)
static void Present(int presentationInterval)
static ? Viewport m_viewport
static void CreateBufferViews()
static unsafe void CopyMemory(IntPtr source, IntPtr destination, int count)
static Format TranslateVertexElementFormat(VertexElementFormat vertexElementFormat)
static bool ResizeSwapChainIfNeeded()
static BlendOption TranslateBlend(Blend blend)
static void ApplyRasterizerState(RasterizerState rasterizerState)
static FeatureLevel[] m_featureLevels
static void ApplyVertexBuffer(SharpDX.Direct3D11.Buffer vertexBuffer, int vertexStride, int vertexOffset)
static SharpDX.Direct3D11.SamplerState GetDxSamplerState(SamplerState samplerState)
static FeatureLevel FeatureLevel
static PrimitiveTopology m_primitiveTopology
static void ApplyViewportScissor(Viewport viewport, Rectangle scissorRectangle)
static Dictionary< SamplerState, SharpDX.Direct3D11.SamplerState > m_dxSamplerStates
static void DisposeDevice()
static int m_userIndexBufferSize
static BlendOperation TranslateBlendFunction(BlendFunction blendFunction)
static DeviceContext2 Context
static RenderTargetView m_renderTargetView
static DepthStencilView m_depthStencilView
static void ApplyBlendState(BlendState blendState)
static void ApplyVsSamplerState(int slot, SamplerState samplerState)
static void ApplyShaderAndRenderTarget(RenderTarget2D renderTarget, Shader shader, VertexDeclaration vertexDeclaration)
static Format TranslateDepthFormat(DepthFormat depthFormat)
static void CreateDevice()
static SharpDX.Direct3D11.Buffer UserIndexBuffer
static Dictionary< DepthStencilState, SharpDX.Direct3D11.DepthStencilState > m_dxDepthStencilStates
static int REQ_TEXTURE2D_U_OR_V_DIMENSION
static int m_userVertexBufferSize
static Format TranslateColorFormat(ColorFormat colorFormat)
static Comparison TranslateCompareFunction(CompareFunction compareFunction)
static void ApplyIndexBuffer(SharpDX.Direct3D11.Buffer indexBuffer, Format format, int indexOffset)
static int m_vertexStride
static BlendState m_blendState
static int AppendUserIndices(int[] indices, int indexStride, int startIndex, int indicesCount)
static Filter TranslateTextureFilterMode(TextureFilterMode textureFilterMode)
static SharpDX.Direct3D11.Buffer m_indexBuffer
static void ApplyDepthStencilState(DepthStencilState depthStencilState)
static SharpDX.Direct3D11.Buffer m_vertexBuffer
static RenderTargetView ColorBufferView
static IntPtr[] m_dataPointers
static int m_userVertexBufferOffset
static RasterizerState m_rasterizerState
static ? Rectangle m_scissorRectangle
static SharpDX.Direct3D11.Buffer UserVertexBuffer
static SwapChain2 SwapChain
static SamplerState[] m_vsSamplerStates
static ShaderParameterType TranslateShaderTypeDescription(ShaderTypeDescription description)
static SharpDX.Direct3D11.TextureAddressMode TranslateTextureAddressMode(TextureAddressMode textureAddressMode)
static int m_userIndexBufferOffset
static Format TranslateIndexFormat(IndexFormat indexFormat)
static VertexShader m_vertexShader
static void HandleDeviceLost()
static InputLayout m_inputLayout
static DepthStencilState m_depthStencilState
static void ApplyPrimitiveType(PrimitiveType primitiveType)
static SamplerState[] m_psSamplerStates
static PixelShader m_pixelShader
static int AppendUserVertices< T >(T[] vertices, int vertexStride, int startVertex, int verticesCount)
static Dictionary< BlendState, SharpDX.Direct3D11.BlendState > m_dxBlendStates
static int m_vertexOffset
static ShaderParameterType TranslateInputBindingDescription(InputBindingDescription description)
static void DisposeBufferViews()
bool DepthBufferWriteEnable
CompareFunction DepthBufferFunction
static void HandleDeviceLost()
static void HandleDeviceReset()
static string DeviceDescription
float SlopeScaleDepthBias
TextureAddressMode AddressModeU
TextureFilterMode FilterMode
TextureAddressMode AddressModeV
ShaderParameter[] m_parameters
virtual void PrepareForDrawing()
readonly ShaderParameterType Type
readonly VertexElement[] m_elements
VertexElementFormat Format
static void Error(object message)
static void Information(object message)