Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
DXWrapper.cs
浏览该文件的文档.
1using System.Runtime.InteropServices;
2using SharpDX;
3using SharpDX.D3DCompiler;
4using SharpDX.Direct3D;
5using SharpDX.Direct3D11;
6using SharpDX.DXGI;
7using Device = SharpDX.Direct3D11.Device;
8using Device2 = SharpDX.Direct3D11.Device2;
9using Device3 = SharpDX.DXGI.Device3;
10using MapFlags = SharpDX.Direct3D11.MapFlags;
11using ResultCode = SharpDX.DXGI.ResultCode;
12
13namespace Engine.Graphics {
14 public static class DXWrapper {
15 public static Device2 Device;
16 public static DeviceContext2 Context;
17 public static SwapChain2 SwapChain;
18 public static RenderTargetView ColorBufferView;
19 public static DepthStencilView DepthBufferView;
21 public static Dictionary<RasterizerState, SharpDX.Direct3D11.RasterizerState> m_dxRasterizerStates = new();
22 public static Dictionary<DepthStencilState, SharpDX.Direct3D11.DepthStencilState> m_dxDepthStencilStates = new();
23 public static Dictionary<BlendState, SharpDX.Direct3D11.BlendState> m_dxBlendStates = new();
24 public static Dictionary<SamplerState, SharpDX.Direct3D11.SamplerState> m_dxSamplerStates = new();
25 public static Viewport? m_viewport;
27 public static IntPtr[] m_dataPointers;
28 public static RenderTargetView m_renderTargetView;
29 public static DepthStencilView m_depthStencilView;
30 public static VertexShader m_vertexShader;
31 public static PixelShader m_pixelShader;
32 public static InputLayout m_inputLayout;
33 public static PrimitiveTopology m_primitiveTopology;
34 public static SharpDX.Direct3D11.Buffer m_vertexBuffer;
35 public static int m_vertexStride;
36 public static int m_vertexOffset;
37 public static SharpDX.Direct3D11.Buffer m_indexBuffer;
38 public static int m_indexOffset;
41 public static BlendState m_blendState;
42 public static SamplerState[] m_vsSamplerStates = new SamplerState[16];
43 public static SamplerState[] m_psSamplerStates = new SamplerState[16];
44 public static SharpDX.Direct3D11.Buffer UserVertexBuffer;
45 public static SharpDX.Direct3D11.Buffer UserIndexBuffer;
46 public static int m_userVertexBufferOffset;
47 public static int m_userIndexBufferOffset;
48 public static int m_userVertexBufferSize;
49 public static int m_userIndexBufferSize;
51
52 public static FeatureLevel[] m_featureLevels = [
53 FeatureLevel.Level_11_1,
54 FeatureLevel.Level_11_0,
55 FeatureLevel.Level_10_1,
56 FeatureLevel.Level_10_0,
57 FeatureLevel.Level_9_3,
58 FeatureLevel.Level_9_2,
59 FeatureLevel.Level_9_1
60 ];
61
62 public static void CreateDevice() {
63 if (Window.Handle == IntPtr.Zero) {
64 throw new InvalidOperationException("Failed to get window handle");
65 }
66#if DEBUG
67 DeviceCreationFlags deviceCreationFlags = DeviceCreationFlags.Debug;
68#else
69 DeviceCreationFlags deviceCreationFlags = DeviceCreationFlags.None;
70#endif
71 using (Device device = new(
72 DriverType.Hardware,
73 deviceCreationFlags,
74 FeatureLevel.Level_11_0,
75 FeatureLevel.Level_10_1,
76 FeatureLevel.Level_10_0,
77 FeatureLevel.Level_9_3,
78 FeatureLevel.Level_9_2,
79 FeatureLevel.Level_9_1
80 )) {
81 Device = device.QueryInterface<Device2>();
82 }
83 Context = Device.ImmediateContext2;
84 FeatureLevel = Device.FeatureLevel;
85 SwapChainDescription1 swapChainDescription = new() {
86 AlphaMode = AlphaMode.Ignore,
87 BufferCount = 2,
88 Format = Format.R8G8B8A8_UNorm,
89 Width = Window.Size.X,
90 Height = Window.Size.Y,
91 SampleDescription = new SampleDescription(1, 0),
92 Scaling = Scaling.Stretch,
93 Stereo = false,
94 SwapEffect = SwapEffect.FlipSequential,
95 Usage = Usage.RenderTargetOutput
96 };
97 using (Device3 device2 = Device.QueryInterface<Device3>()) {
98 using (Factory3 parent = device2.Adapter.GetParent<Factory3>()) {
99 using (SwapChain1 swapChain = new(parent, Device, Window.Handle, ref swapChainDescription)) {
100 SwapChain = swapChain.QueryInterface<SwapChain2>();
101 }
102 }
103 device2.MaximumFrameLatency = 1;
104 }
105 /*using (ISwapChainPanelNative swapChainPanelNative = ComObject.As<ISwapChainPanelNative>(Window.m_swapChainPanel))
106 {
107 swapChainPanelNative.SwapChain = SwapChain;
108 }*/
110 switch (FeatureLevel) {
111 case FeatureLevel.Level_11_1:
112 case FeatureLevel.Level_11_0: REQ_TEXTURE2D_U_OR_V_DIMENSION = 16384; break;
113 case FeatureLevel.Level_10_1:
114 case FeatureLevel.Level_10_0: REQ_TEXTURE2D_U_OR_V_DIMENSION = 8192; break;
115 case FeatureLevel.Level_9_3: REQ_TEXTURE2D_U_OR_V_DIMENSION = 4096; break;
116 case FeatureLevel.Level_9_2:
117 case FeatureLevel.Level_9_1: REQ_TEXTURE2D_U_OR_V_DIMENSION = 2048; break;
118 default: REQ_TEXTURE2D_U_OR_V_DIMENSION = -1; break;
119 }
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")}";
122 Log.Information("Initialized display device: " + Display.DeviceDescription);
123 }
124
125 public static void Trim() {
126 using (Device3 device = Device.QueryInterface<Device3>()) {
127 device.Trim();
128 }
129 }
130
131 public static void DisposeDevice() {
132 DeviceDebug deviceDebug = null;
133 if ((Device.CreationFlags & DeviceCreationFlags.Debug) != DeviceCreationFlags.None) {
134 deviceDebug = new DeviceDebug(Device);
135 }
137 foreach (SharpDX.Direct3D11.RasterizerState rasterizerState in m_dxRasterizerStates.Values) {
138 rasterizerState.Dispose();
139 }
140 m_dxRasterizerStates.Clear();
141 foreach (SharpDX.Direct3D11.DepthStencilState depthStencilState in m_dxDepthStencilStates.Values) {
142 depthStencilState.Dispose();
143 }
145 foreach (SharpDX.Direct3D11.BlendState blendState in m_dxBlendStates.Values) {
146 blendState.Dispose();
147 }
148 m_dxBlendStates.Clear();
149 foreach (SharpDX.Direct3D11.SamplerState samplerState in m_dxSamplerStates.Values) {
150 samplerState.Dispose();
151 }
152 m_dxSamplerStates.Clear();
153 Utilities.Dispose(ref UserVertexBuffer);
154 Utilities.Dispose(ref UserIndexBuffer);
155 Utilities.Dispose(ref Context);
156 Utilities.Dispose(ref SwapChain);
157 Utilities.Dispose(ref Device);
158 m_viewport = null;
159 m_scissorRectangle = null;
160 m_renderTargetView = null;
161 m_depthStencilView = null;
162 m_vertexShader = null;
163 m_pixelShader = null;
164 m_inputLayout = null;
165 m_primitiveTopology = PrimitiveTopology.Undefined;
166 m_vertexBuffer = null;
167 m_vertexStride = 0;
168 m_vertexOffset = 0;
169 m_indexBuffer = null;
170 m_indexOffset = 0;
171 m_rasterizerState = null;
172 m_depthStencilState = null;
173 m_blendState = null;
174 Array.Clear(m_vsSamplerStates, 0, m_vsSamplerStates.Length);
175 Array.Clear(m_psSamplerStates, 0, m_psSamplerStates.Length);
176 if (deviceDebug != null) {
177 deviceDebug.ReportLiveDeviceObjects(ReportingLevel.Detail);
178 deviceDebug.Dispose();
179 }
180 }
181
182 public static bool ResizeSwapChainIfNeeded() {
183 /*Matrix3x2 matrix3x = default(Matrix3x2);
184 matrix3x.M11 = 1f / Window.m_swapChainPanel.CompositionScaleX;
185 matrix3x.M22 = 1f / Window.m_swapChainPanel.CompositionScaleY;
186 SwapChain.MatrixTransform = matrix3x;*/
187 if (Window.Size.X != SwapChain.Description.ModeDescription.Width
188 || Window.Size.Y != SwapChain.Description.ModeDescription.Height) {
190 SwapChain.ResizeBuffers(2, Window.Size.X, Window.Size.Y, Format.R8G8B8A8_UNorm, SwapChainFlags.None);
192 return true;
193 }
194 return false;
195 }
196
197 public static void Present(int presentationInterval) {
198 try {
199 SwapChain.Present(presentationInterval, PresentFlags.None);
200 if (ColorBufferView != null) {
201 Context.DiscardView(ColorBufferView);
202 }
203 if (DepthBufferView != null) {
204 Context.DiscardView(DepthBufferView);
205 }
206 }
207 catch (SharpDXException ex) {
208 if (ex.HResult == ResultCode.DeviceRemoved.Code
209 || ex.HResult == ResultCode.DeviceReset.Code) {
211 }
212 else {
213 Log.Error("SwapChain.Present failed. Reason: {0}", ex.Message);
214 }
215 }
216 catch (Exception ex2) {
217 Log.Error("SwapChain.Present failed. Reason: {0}", ex2.Message);
218 }
219 m_renderTargetView = null;
220 m_depthStencilView = null;
221 }
222
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;
226 if (UserVertexBuffer == null
227 || num2 > m_userVertexBufferSize) {
228 Utilities.Dispose(ref UserVertexBuffer);
231 UserVertexBuffer = new SharpDX.Direct3D11.Buffer(
232 Device,
233 new BufferDescription {
234 BindFlags = BindFlags.VertexBuffer,
235 Usage = ResourceUsage.Dynamic,
236 CpuAccessFlags = CpuAccessFlags.Write,
237 SizeInBytes = m_userVertexBufferSize
238 }
239 );
240 }
242 DataBox dataBox = Context.MapSubresource(UserVertexBuffer, 0, MapMode.WriteNoOverwrite, MapFlags.None);
243 GCHandle gchandle = GCHandle.Alloc(vertices, GCHandleType.Pinned);
244 CopyMemory(gchandle.AddrOfPinnedObject() + num, dataBox.DataPointer + m_userVertexBufferOffset, num2);
245 gchandle.Free();
246 Context.UnmapSubresource(UserVertexBuffer, 0);
247 int userVertexBufferOffset = m_userVertexBufferOffset;
249 return userVertexBufferOffset;
250 }
251 DataBox dataBox2 = Context.MapSubresource(UserVertexBuffer, 0, MapMode.WriteDiscard, MapFlags.None);
252 GCHandle gchandle2 = GCHandle.Alloc(vertices, GCHandleType.Pinned);
253 CopyMemory(gchandle2.AddrOfPinnedObject() + num, dataBox2.DataPointer, num2);
254 gchandle2.Free();
255 Context.UnmapSubresource(UserVertexBuffer, 0);
257 return 0;
258 }
259
260 public static int AppendUserIndices(int[] indices, int indexStride, int startIndex, int indicesCount) {
261 int num = indexStride * startIndex;
262 int num2 = indexStride * indicesCount;
263 if (UserIndexBuffer == null
264 || num2 > m_userIndexBufferSize) {
265 Utilities.Dispose(ref UserIndexBuffer);
268 UserIndexBuffer = new SharpDX.Direct3D11.Buffer(
269 Device,
270 new BufferDescription {
271 BindFlags = BindFlags.IndexBuffer,
272 Usage = ResourceUsage.Dynamic,
273 CpuAccessFlags = CpuAccessFlags.Write,
274 SizeInBytes = m_userIndexBufferSize
275 }
276 );
277 }
279 DataBox dataBox = Context.MapSubresource(UserIndexBuffer, 0, MapMode.WriteNoOverwrite, MapFlags.None);
280 GCHandle gchandle = GCHandle.Alloc(indices, GCHandleType.Pinned);
281 CopyMemory(gchandle.AddrOfPinnedObject() + num, dataBox.DataPointer + m_userIndexBufferOffset, num2);
282 gchandle.Free();
283 Context.UnmapSubresource(UserIndexBuffer, 0);
284 int userIndexBufferOffset = m_userIndexBufferOffset;
286 return userIndexBufferOffset;
287 }
288 DataBox dataBox2 = Context.MapSubresource(UserIndexBuffer, 0, MapMode.WriteDiscard, MapFlags.None);
289 GCHandle gchandle2 = GCHandle.Alloc(indices, GCHandleType.Pinned);
290 CopyMemory(gchandle2.AddrOfPinnedObject() + num, dataBox2.DataPointer, num2);
291 gchandle2.Free();
292 Context.UnmapSubresource(UserIndexBuffer, 0);
294 return 0;
295 }
296
297 public static void ApplyViewportScissor(Viewport viewport, Rectangle scissorRectangle) {
298 if (m_viewport == null
299 || viewport != m_viewport.Value) {
300 Context.Rasterizer.SetViewport(viewport.X, viewport.Y, viewport.Width, viewport.Height, viewport.MinDepth, viewport.MaxDepth);
301 m_viewport = viewport;
302 }
303 if (m_scissorRectangle == null
304 || scissorRectangle != m_scissorRectangle.Value) {
305 Context.Rasterizer.SetScissorRectangle(
306 scissorRectangle.Left,
307 scissorRectangle.Top,
308 scissorRectangle.Left + scissorRectangle.Width,
309 scissorRectangle.Top + scissorRectangle.Height
310 );
311 m_scissorRectangle = scissorRectangle;
312 }
313 }
314
315 public static void ApplyRasterizerState(RasterizerState rasterizerState) {
316 if (rasterizerState != m_rasterizerState) {
317 if (!m_dxRasterizerStates.TryGetValue(rasterizerState, out SharpDX.Direct3D11.RasterizerState rasterizerState2)) {
318 RasterizerStateDescription rasterizerStateDescription = RasterizerStateDescription.Default();
319 rasterizerStateDescription.FillMode = FillMode.Solid;
320 switch (rasterizerState.CullMode) {
321 case CullMode.None: rasterizerStateDescription.CullMode = SharpDX.Direct3D11.CullMode.None; break;
322 case CullMode.CullClockwise:
323 rasterizerStateDescription.CullMode = SharpDX.Direct3D11.CullMode.Back;
324 rasterizerStateDescription.IsFrontCounterClockwise = true;
325 break;
326 case CullMode.CullCounterClockwise:
327 rasterizerStateDescription.CullMode = SharpDX.Direct3D11.CullMode.Back;
328 rasterizerStateDescription.IsFrontCounterClockwise = false;
329 break;
330 default: throw new InvalidOperationException("Unsupported cull mode.");
331 }
332 rasterizerStateDescription.DepthBias = (int)rasterizerState.DepthBias;
333 rasterizerStateDescription.DepthBiasClamp = 0f;
334 rasterizerStateDescription.SlopeScaledDepthBias = rasterizerState.SlopeScaleDepthBias;
335 rasterizerStateDescription.IsDepthClipEnabled = true;
336 rasterizerStateDescription.IsScissorEnabled = rasterizerState.ScissorTestEnable;
337 rasterizerStateDescription.IsMultisampleEnabled = false;
338 rasterizerStateDescription.IsAntialiasedLineEnabled = false;
339 rasterizerState2 = new SharpDX.Direct3D11.RasterizerState(Device, rasterizerStateDescription);
340 m_dxRasterizerStates.Add(rasterizerState, rasterizerState2);
341 }
342 Context.Rasterizer.State = rasterizerState2;
343 m_rasterizerState = rasterizerState;
344 }
345 }
346
347 public static void ApplyDepthStencilState(DepthStencilState depthStencilState) {
348 if (depthStencilState != m_depthStencilState) {
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
356 : Comparison.Always;
357 depthStencilState2 = new SharpDX.Direct3D11.DepthStencilState(Device, depthStencilStateDescription);
358 m_dxDepthStencilStates.Add(depthStencilState, depthStencilState2);
359 }
360 Context.OutputMerger.SetDepthStencilState(depthStencilState2);
361 m_depthStencilState = depthStencilState;
362 }
363 }
364
365 public static void ApplyBlendState(BlendState blendState) {
366 if (blendState != m_blendState) {
367 if (!m_dxBlendStates.TryGetValue(blendState, out SharpDX.Direct3D11.BlendState blendState2)) {
368 BlendStateDescription blendStateDescription = BlendStateDescription.Default();
369 blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
370 if (blendState.ColorBlendFunction == BlendFunction.Add
371 && blendState.ColorSourceBlend == Blend.One
372 && blendState.ColorDestinationBlend == Blend.Zero
373 && blendState.AlphaBlendFunction == BlendFunction.Add
374 && blendState.AlphaSourceBlend == Blend.One
375 && blendState.AlphaDestinationBlend == Blend.Zero) {
376 blendStateDescription.RenderTarget[0].IsBlendEnabled = false;
377 }
378 else {
379 blendStateDescription.RenderTarget[0].IsBlendEnabled = true;
380 blendStateDescription.RenderTarget[0].BlendOperation = TranslateBlendFunction(blendState.ColorBlendFunction);
381 blendStateDescription.RenderTarget[0].AlphaBlendOperation = TranslateBlendFunction(blendState.AlphaBlendFunction);
382 blendStateDescription.RenderTarget[0].SourceBlend = TranslateBlend(blendState.ColorSourceBlend);
383 blendStateDescription.RenderTarget[0].SourceAlphaBlend = TranslateBlend(blendState.AlphaSourceBlend);
384 blendStateDescription.RenderTarget[0].DestinationBlend = TranslateBlend(blendState.ColorDestinationBlend);
385 blendStateDescription.RenderTarget[0].DestinationAlphaBlend = TranslateBlend(blendState.AlphaDestinationBlend);
386 }
387 blendState2 = new SharpDX.Direct3D11.BlendState(Device, blendStateDescription);
388 m_dxBlendStates.Add(blendState, blendState2);
389 }
390 Color4 color = new(blendState.BlendFactor.X, blendState.BlendFactor.Y, blendState.BlendFactor.Z, blendState.BlendFactor.W);
391 Context.OutputMerger.SetBlendState(blendState2, color);
392 m_blendState = blendState;
393 }
394 }
395
396 public static void ApplyVsSamplerState(int slot, SamplerState samplerState) {
397 if (m_vsSamplerStates[slot] != samplerState) {
398 Context.VertexShader.SetSampler(slot, GetDxSamplerState(samplerState));
399 m_vsSamplerStates[slot] = samplerState;
400 }
401 }
402
403 public static void ApplyPsSamplerState(int slot, SamplerState samplerState) {
404 if (m_psSamplerStates[slot] != samplerState) {
405 Context.PixelShader.SetSampler(slot, GetDxSamplerState(samplerState));
406 m_psSamplerStates[slot] = samplerState;
407 }
408 }
409
410 public static void ApplyShaderAndRenderTarget(RenderTarget2D renderTarget, Shader shader, VertexDeclaration vertexDeclaration) {
411 shader.PrepareForDrawing();
412 if (renderTarget != null) {
413 if (renderTarget.m_colorTextureView != m_renderTargetView
414 || renderTarget.m_depthTextureView != m_depthStencilView) {
415 Context.OutputMerger.SetRenderTargets(renderTarget.m_depthTextureView, renderTarget.m_colorTextureView);
416 m_renderTargetView = renderTarget.m_colorTextureView;
417 m_depthStencilView = renderTarget.m_depthTextureView;
418 }
419 }
422 Context.OutputMerger.SetRenderTargets(DepthBufferView, ColorBufferView);
425 }
426 InputLayout inputLayout;
427 if (vertexDeclaration == shader.m_lastVertexDeclaration) {
428 inputLayout = shader.m_lastInputLayout;
429 }
430 else {
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++) {
434 VertexElement vertexElement = vertexDeclaration.m_elements[i];
435 array[i] = new InputElement {
436 SemanticName = vertexElement.SemanticName,
437 AlignedByteOffset = vertexElement.Offset,
438 Format = TranslateVertexElementFormat(vertexElement.Format),
439 Classification = InputClassification.PerVertexData,
440 Slot = 0,
441 SemanticIndex = vertexElement.SemanticIndex
442 };
443 }
444 inputLayout = new InputLayout(Device, shader.m_vertexShaderBytecode, array);
445 shader.m_inputLayouts.Add(vertexDeclaration, inputLayout);
446 }
447 shader.m_lastVertexDeclaration = vertexDeclaration;
448 shader.m_lastInputLayout = inputLayout;
449 }
450 if (inputLayout != m_inputLayout) {
451 Context.InputAssembler.InputLayout = inputLayout;
452 m_inputLayout = inputLayout;
453 }
454 if (m_dataPointers == null
455 || m_dataPointers.Length < shader.m_allConstantBuffers.Length) {
456 m_dataPointers = new IntPtr[shader.m_allConstantBuffers.Length];
457 }
458 for (int j = 0; j < shader.m_parameters.Length; j++) {
459 ShaderParameter shaderParameter = shader.m_parameters[j];
460 if (shaderParameter.Type == ShaderParameterType.Texture2D) {
461 if (shaderParameter.IsChanged
462 || shader.m_pixelShader != m_pixelShader
463 || shader.m_vertexShader != m_vertexShader) {
464 Texture2D texture2D = (Texture2D)shaderParameter.Resource;
465 if (shaderParameter.VsResourceBindingSlot != -1) {
466 Context.VertexShader.SetShaderResource(
467 shaderParameter.VsResourceBindingSlot,
468 texture2D != null ? texture2D.m_textureView : null
469 );
470 }
471 if (shaderParameter.PsResourceBindingSlot != -1) {
472 Context.PixelShader.SetShaderResource(
473 shaderParameter.PsResourceBindingSlot,
474 texture2D != null ? texture2D.m_textureView : null
475 );
476 }
477 shaderParameter.IsChanged = false;
478 }
479 }
480 else if (shaderParameter.Type == ShaderParameterType.Sampler2D) {
481 if (shaderParameter.IsChanged
482 || shader.m_pixelShader != m_pixelShader
483 || shader.m_vertexShader != m_vertexShader) {
484 SamplerState samplerState = (SamplerState)shaderParameter.Resource;
485 if (samplerState != null) {
486 if (shaderParameter.VsResourceBindingSlot != -1) {
487 ApplyVsSamplerState(shaderParameter.VsResourceBindingSlot, samplerState);
488 }
489 if (shaderParameter.PsResourceBindingSlot != -1) {
490 ApplyPsSamplerState(shaderParameter.PsResourceBindingSlot, samplerState);
491 }
492 }
493 shaderParameter.IsChanged = false;
494 }
495 }
496 else if (shaderParameter.IsChanged) {
497 if (shaderParameter.VsBufferIndex != -1
498 && m_dataPointers[shaderParameter.VsBufferIndex] == IntPtr.Zero) {
499 SharpDX.Direct3D11.Buffer buffer = shader.m_allConstantBuffers[shaderParameter.VsBufferIndex];
500 m_dataPointers[shaderParameter.VsBufferIndex] = Context.MapSubresource(buffer, 0, MapMode.WriteDiscard, MapFlags.None)
501 .DataPointer;
502 }
503 if (shaderParameter.PsBufferIndex != -1
504 && m_dataPointers[shaderParameter.PsBufferIndex] == IntPtr.Zero) {
505 SharpDX.Direct3D11.Buffer buffer2 = shader.m_allConstantBuffers[shaderParameter.PsBufferIndex];
506 m_dataPointers[shaderParameter.PsBufferIndex] = Context.MapSubresource(buffer2, 0, MapMode.WriteDiscard, MapFlags.None)
507 .DataPointer;
508 }
509 shaderParameter.IsChanged = false;
510 }
511 }
512 for (int k = 0; k < shader.m_allConstantBuffers.Length; k++) {
513 if (m_dataPointers[k] != IntPtr.Zero) {
514 CopyMemory(shader.m_allConstantBuffersCpu[k], m_dataPointers[k], shader.m_allConstantBuffersSizes[k]);
515 Context.UnmapSubresource(shader.m_allConstantBuffers[k], 0);
516 m_dataPointers[k] = IntPtr.Zero;
517 }
518 }
519 if (shader.m_vertexShader != m_vertexShader) {
520 Context.VertexShader.Set(shader.m_vertexShader);
522 if (shader.m_vertexShaderConstantBuffers.Length != 0) {
523 Context.VertexShader.SetConstantBuffers(0, shader.m_vertexShaderConstantBuffers);
524 }
525 }
526 if (shader.m_pixelShader != m_pixelShader) {
527 Context.PixelShader.Set(shader.m_pixelShader);
529 if (shader.m_pixelShaderConstantBuffers.Length != 0) {
530 Context.PixelShader.SetConstantBuffers(0, shader.m_pixelShaderConstantBuffers);
531 }
532 }
533 }
534
535 public static void ApplyVertexBuffer(SharpDX.Direct3D11.Buffer vertexBuffer, int vertexStride, int vertexOffset) {
536 if (vertexBuffer != m_vertexBuffer
537 || vertexStride != m_vertexStride
538 || vertexOffset != m_vertexOffset) {
539 Context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, vertexStride, vertexOffset));
540 m_vertexBuffer = vertexBuffer;
541 m_vertexStride = vertexStride;
542 m_vertexOffset = vertexOffset;
543 }
544 }
545
546 public static void ApplyIndexBuffer(SharpDX.Direct3D11.Buffer indexBuffer, Format format, int indexOffset) {
547 if (indexBuffer != m_indexBuffer
548 || indexOffset != m_indexOffset) {
549 Context.InputAssembler.SetIndexBuffer(indexBuffer, format, indexOffset);
550 m_indexBuffer = indexBuffer;
551 m_indexOffset = indexOffset;
552 }
553 }
554
555 public static void ApplyPrimitiveType(PrimitiveType primitiveType) {
556 PrimitiveTopology primitiveTopology = TranslatePrimitiveType(primitiveType);
557 if (primitiveTopology != m_primitiveTopology) {
558 Context.InputAssembler.PrimitiveTopology = primitiveTopology;
559 m_primitiveTopology = primitiveTopology;
560 }
561 }
562
563 public static SharpDX.Direct3D11.SamplerState GetDxSamplerState(SamplerState samplerState) {
564 if (!m_dxSamplerStates.TryGetValue(samplerState, out SharpDX.Direct3D11.SamplerState samplerState2)) {
565 SamplerStateDescription samplerStateDescription = SamplerStateDescription.Default();
566 samplerStateDescription.AddressU = TranslateTextureAddressMode(samplerState.AddressModeU);
567 samplerStateDescription.AddressV = TranslateTextureAddressMode(samplerState.AddressModeV);
568 samplerStateDescription.AddressW = SharpDX.Direct3D11.TextureAddressMode.Wrap;
569 samplerStateDescription.MaximumAnisotropy = samplerState.MaxAnisotropy;
570 if (FeatureLevel >= FeatureLevel.Level_10_0) {
571 samplerStateDescription.MinimumLod = samplerState.MinLod;
572 samplerStateDescription.MaximumLod = samplerState.MaxLod;
573 }
574 samplerStateDescription.MipLodBias = samplerState.MipLodBias;
575 samplerStateDescription.ComparisonFunction = Comparison.Always;
576 samplerStateDescription.BorderColor = new Color4(0f, 0f, 0f, 1f);
577 samplerStateDescription.Filter = TranslateTextureFilterMode(samplerState.FilterMode);
578 samplerState2 = new SharpDX.Direct3D11.SamplerState(Device, samplerStateDescription);
579 m_dxSamplerStates.Add(samplerState, samplerState2);
580 }
581 return samplerState2;
582 }
583
584 public static PrimitiveTopology TranslatePrimitiveType(PrimitiveType primitiveType) {
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.");
591 }
592 }
593
594 public static ShaderParameterType TranslateShaderTypeDescription(ShaderTypeDescription description) {
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 } =>
601 ShaderParameterType.Matrix,
602 _ => throw new InvalidOperationException(
603 string.Format("Variable \"{0}\" uses unsupported shader variable type.", new object[] { description.Name })
604 )
605 };
606 }
607
608 public static ShaderParameterType TranslateInputBindingDescription(InputBindingDescription description) {
609 if (description is { Type: ShaderInputType.Texture, Dimension: ShaderResourceViewDimension.Texture2D, BindCount: 1 }) {
610 return ShaderParameterType.Texture2D;
611 }
612 if (description is { Type: ShaderInputType.Sampler, BindCount: 1 }) {
613 return ShaderParameterType.Sampler2D;
614 }
615 throw new InvalidOperationException(
616 string.Format("Shader resource \"{0}\" uses unsupported shader resource type.", new object[] { description.Name })
617 );
618 }
619
620 public static Format TranslateVertexElementFormat(VertexElementFormat vertexElementFormat) {
621 switch (vertexElementFormat) {
622 case VertexElementFormat.Single: return Format.R32_Float;
623 case VertexElementFormat.Vector2: return Format.R32G32_Float;
624 case VertexElementFormat.Vector3: return Format.R32G32B32_Float;
625 case VertexElementFormat.Vector4: return Format.R32G32B32A32_Float;
626 case VertexElementFormat.Byte4: return Format.R8G8B8A8_UInt;
627 case VertexElementFormat.NormalizedByte4: return Format.R8G8B8A8_UNorm;
628 case VertexElementFormat.Short2: return Format.R16G16_SInt;
629 case VertexElementFormat.NormalizedShort2: return Format.R16G16_SNorm;
630 case VertexElementFormat.Short4: return Format.R16G16B16A16_SInt;
631 case VertexElementFormat.NormalizedShort4: return Format.R16G16B16A16_SNorm;
632 default: throw new InvalidOperationException("Unsupported VertexElementFormat.");
633 }
634 }
635
636 public static Format TranslateIndexFormat(IndexFormat indexFormat) {
637 if (indexFormat == IndexFormat.SixteenBits) {
638 return Format.R16_UInt;
639 }
640 if (indexFormat != IndexFormat.ThirtyTwoBits) {
641 throw new InvalidOperationException("Unsupported IndexFormat.");
642 }
643 return Format.R32_UInt;
644 }
645
646 public static Format TranslateColorFormat(ColorFormat colorFormat) {
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;
651 case ColorFormat.R8: return Format.R8_UNorm;
652 case ColorFormat.R32f: return Format.R32_Float;
653 case ColorFormat.RG32f: return Format.R32G32_Float;
654 case ColorFormat.RGBA32f: return Format.R32G32B32A32_Float;
655 default: throw new InvalidOperationException("Unsupported ColorFormat.");
656 }
657 }
658
659 public static Format TranslateDepthFormat(DepthFormat depthFormat) {
660 if (depthFormat == DepthFormat.Depth16) {
661 return Format.D16_UNorm;
662 }
663 if (depthFormat != DepthFormat.Depth24Stencil8) {
664 throw new InvalidOperationException("Unsupported DepthFormat.");
665 }
666 return Format.D24_UNorm_S8_UInt;
667 }
668
669 public static BlendOperation TranslateBlendFunction(BlendFunction blendFunction) {
670 switch (blendFunction) {
671 case BlendFunction.Add: return BlendOperation.Add;
672 case BlendFunction.Subtract: return BlendOperation.Subtract;
673 case BlendFunction.ReverseSubtract: return BlendOperation.ReverseSubtract;
674 default: throw new InvalidOperationException("Unsupported BlendFunction.");
675 }
676 }
677
678 public static BlendOption TranslateBlend(Blend blend) {
679 switch (blend) {
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.");
694 }
695 }
696
697 public static SharpDX.Direct3D11.TextureAddressMode TranslateTextureAddressMode(TextureAddressMode textureAddressMode) {
698 switch (textureAddressMode) {
699 case TextureAddressMode.Clamp: return SharpDX.Direct3D11.TextureAddressMode.Clamp;
700 case TextureAddressMode.Wrap: return SharpDX.Direct3D11.TextureAddressMode.Wrap;
701 case TextureAddressMode.MirrorWrap: return SharpDX.Direct3D11.TextureAddressMode.Mirror;
702 default: throw new InvalidOperationException("Unsupported TextureAddressMode.");
703 }
704 }
705
706 public static Filter TranslateTextureFilterMode(TextureFilterMode textureFilterMode) {
707 switch (textureFilterMode) {
708 case TextureFilterMode.Point: return Filter.MinMagMipPoint;
709 case TextureFilterMode.Linear: return Filter.MinMagMipLinear;
710 case TextureFilterMode.Anisotropic: return Filter.Anisotropic;
711 case TextureFilterMode.PointMipLinear: return Filter.MinMagPointMipLinear;
712 case TextureFilterMode.LinearMipPoint: return Filter.MinMagLinearMipPoint;
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.");
718 }
719 }
720
721 public static Comparison TranslateCompareFunction(CompareFunction compareFunction) {
722 switch (compareFunction) {
723 case CompareFunction.Always: return Comparison.Always;
724 case CompareFunction.Never: return Comparison.Never;
725 case CompareFunction.Less: return Comparison.Less;
726 case CompareFunction.LessEqual: return Comparison.LessEqual;
727 case CompareFunction.Equal: return Comparison.Equal;
728 case CompareFunction.GreaterEqual: return Comparison.GreaterEqual;
729 case CompareFunction.Greater: return Comparison.Greater;
730 case CompareFunction.NotEqual: return Comparison.NotEqual;
731 default: throw new InvalidOperationException("Unsupported CompareFunction.");
732 }
733 }
734
735 public static void CreateBufferViews() {
736 Point2 point;
737 using (SharpDX.Direct3D11.Texture2D backBuffer = SwapChain.GetBackBuffer<SharpDX.Direct3D11.Texture2D>(0)) {
738 ColorBufferView = new RenderTargetView(Device, backBuffer);
739 point = new Point2(backBuffer.Description.Width, backBuffer.Description.Height);
740 }
741 Texture2DDescription texture2DDescription = new() {
742 ArraySize = 1,
743 BindFlags = BindFlags.DepthStencil,
744 CpuAccessFlags = CpuAccessFlags.None,
745 Format = TranslateDepthFormat(DepthFormat.Depth24Stencil8),
746 MipLevels = 1,
747 OptionFlags = ResourceOptionFlags.None,
748 SampleDescription = new SampleDescription(1, 0),
749 Usage = ResourceUsage.Default,
750 Width = point.X,
751 Height = point.Y
752 };
753 using (SharpDX.Direct3D11.Texture2D texture2D = new(Device, texture2DDescription)) {
754 DepthBufferView = new DepthStencilView(Device, texture2D);
755 }
756 }
757
758 public static void DisposeBufferViews() {
759 Utilities.Dispose(ref ColorBufferView);
760 Utilities.Dispose(ref DepthBufferView);
761 }
762
763 public static unsafe void CopyMemory(IntPtr source, IntPtr destination, int count) {
764 int* ptr = (int*)source.ToPointer();
765 int* ptr2 = (int*)((byte*)source.ToPointer() + (IntPtr)(count / 4) * 4);
766 int* ptr3 = (int*)destination.ToPointer();
767 while (ptr < ptr2) {
768 *ptr3 = *ptr;
769 ptr++;
770 ptr3++;
771 }
772 byte* ptr4 = (byte*)ptr;
773 byte* ptr5 = (byte*)source.ToPointer() + count;
774 byte* ptr6 = (byte*)ptr3;
775 while (ptr4 < ptr5) {
776 *ptr6 = *ptr4;
777 ptr4++;
778 ptr6++;
779 }
780 }
781
782 public static void HandleDeviceLost() {
783 try {
784 Log.Information("Device lost");
787 GC.Collect();
788 CreateDevice();
789 Display.Resize();
791 Log.Information("Device reset");
792 }
793 catch (Exception ex) {
794 Log.Error("Failed to recreate graphics device. Reason: {0}", ex.Message);
795 }
796 }
797 }
798}
SharpDX.DXGI.ResultCode ResultCode
SharpDX.DXGI.Device3 Device3
SharpDX.Direct3D11.MapFlags MapFlags
SharpDX.Direct3D11.Device2 Device2
SharpDX.Direct3D11.Device Device
unsafe
定义 Main.cs:15
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 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 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 SharpDX.Direct3D11.Buffer UserIndexBuffer
static Dictionary< DepthStencilState, SharpDX.Direct3D11.DepthStencilState > m_dxDepthStencilStates
static int REQ_TEXTURE2D_U_OR_V_DIMENSION
static Format TranslateColorFormat(ColorFormat colorFormat)
static Comparison TranslateCompareFunction(CompareFunction compareFunction)
static void ApplyIndexBuffer(SharpDX.Direct3D11.Buffer indexBuffer, Format format, int indexOffset)
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 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 Format TranslateIndexFormat(IndexFormat indexFormat)
static VertexShader m_vertexShader
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 ShaderParameterType TranslateInputBindingDescription(InputBindingDescription description)
static void HandleDeviceLost()
static void HandleDeviceReset()
static string DeviceDescription
ShaderParameter[] m_parameters
virtual void PrepareForDrawing()
readonly ShaderParameterType Type
static void Error(object message)
定义 Log.cs:80
static void Information(object message)
定义 Log.cs:56
static Point2 Size
static IntPtr Handle