protected override unsafe ID3D12RootSignature *CreateRootSignature() { using ComPtr <ID3D10Blob> signature = null; using ComPtr <ID3D10Blob> error = null; var rootSignatureDesc = new RootSignatureDesc { Flags = RootSignatureFlags.RootSignatureFlagAllowInputAssemblerInputLayout }; SilkMarshal.ThrowHResult ( D3D12.SerializeRootSignature ( &rootSignatureDesc, D3DRootSignatureVersion.D3DRootSignatureVersion1, signature.GetAddressOf(), error.GetAddressOf() ) ); ID3D12RootSignature *rootSignature; var iid = ID3D12RootSignature.Guid; SilkMarshal.ThrowHResult ( D3DDevice->CreateRootSignature ( nodeMask: 0, signature.Get().GetBufferPointer(), signature.Get().GetBufferSize(), &iid, (void **)&rootSignature ) ); return(rootSignature); }
protected virtual ID3D12Resource *CreateDepthStencil() { ID3D12Resource *depthStencil; var heapProperties = new HeapProperties(HeapType.HeapTypeDefault); var resourceDesc = new ResourceDesc ( ResourceDimension.ResourceDimensionTexture2D, 0ul, (ulong)Size.X, (uint)Size.Y, 1, 1, DepthBufferFormat, new SampleDesc() { Count = 1, Quality = 0 }, TextureLayout.TextureLayoutUnknown, ResourceFlags.ResourceFlagAllowDepthStencil ); var clearValue = new ClearValue(DepthBufferFormat, depthStencil: new DepthStencilValue(1.0f, 0)); var iid = ID3D12Resource.Guid; SilkMarshal.ThrowHResult ( D3DDevice->CreateCommittedResource ( &heapProperties, HeapFlags.HeapFlagNone, &resourceDesc, ResourceStates.ResourceStateDepthWrite, &clearValue, &iid, (void **)&depthStencil ) ); var dsvDesc = new DepthStencilViewDesc { Format = DepthBufferFormat, ViewDimension = DsvDimension.DsvDimensionTexture2D }; D3DDevice->CreateDepthStencilView(depthStencil, &dsvDesc, DSVHeap->GetCPUDescriptorHandleForHeapStart()); return(depthStencil); }
public override void OnRender() { PopulateGraphicsCommandList(); ExecuteGraphicsCommandList(); SilkMarshal.ThrowHResult(_swapChain->Present(SyncInterval: 1, Flags: 0)); WaitForGpu(moveToNextFrame: true); void PopulateGraphicsCommandList() { WaitForGpu(moveToNextFrame: false); SilkMarshal.ThrowHResult(CommandAllocator->Reset()); SilkMarshal.ThrowHResult(GraphicsCommandList->Reset(CommandAllocator, PipelineState)); SetGraphicsCommandListState(); TransitionForRender(); var backgroundColor = BackgroundColor; // in d3dx12.h: // new CpuDescriptorHandle(RTVHeap->GetCPUDescriptorHandleForHeapStart(), (int)FrameIndex, // RTVDescriptorSize) var rtvHandle = new CpuDescriptorHandle { Ptr = (nuint)((long)@RTVHeap->GetCPUDescriptorHandleForHeapStart().Ptr + ((long)FrameIndex * (long)RTVDescriptorSize)) }; GraphicsCommandList->ClearRenderTargetView(rtvHandle, (float *)&backgroundColor, 0, null); var dsvHandle = DSVHeap->GetCPUDescriptorHandleForHeapStart(); GraphicsCommandList->ClearDepthStencilView(dsvHandle, ClearFlags.ClearFlagDepth, 1, 0, 0, null); GraphicsCommandList->OMSetRenderTargets(1, &rtvHandle, 0, &dsvHandle); Draw(); TransitionForPresent(); SilkMarshal.ThrowHResult(GraphicsCommandList->Close()); } }
protected virtual void CreateDescriptorHeaps() { _rtvHeap = CreateRTVHeap(out _rtvDescriptorSize); _dsvHeap = CreateDSVHeap(); ID3D12DescriptorHeap *CreateDSVHeap() { var dsvHeapDesc = new DescriptorHeapDesc { NumDescriptors = 1, Type = DescriptorHeapType.DescriptorHeapTypeDsv, }; ID3D12DescriptorHeap *dsvHeap; var iid = ID3D12DescriptorHeap.Guid; SilkMarshal.ThrowHResult(D3DDevice->CreateDescriptorHeap(&dsvHeapDesc, &iid, (void **)&dsvHeap)); return(dsvHeap); } ID3D12DescriptorHeap *CreateRTVHeap(out uint rtvDescriptorSize) { var rtvHeapDesc = new DescriptorHeapDesc { NumDescriptors = FrameCount, Type = DescriptorHeapType.DescriptorHeapTypeRtv, }; ID3D12DescriptorHeap *rtvHeap; var iid = ID3D12DescriptorHeap.Guid; SilkMarshal.ThrowHResult(D3DDevice->CreateDescriptorHeap(&rtvHeapDesc, &iid, (void **)&rtvHeap)); rtvDescriptorSize = D3DDevice->GetDescriptorHandleIncrementSize (DescriptorHeapType.DescriptorHeapTypeRtv); return(rtvHeap); } }
private void MainWindow_Loaded(object sender, RoutedEventArgs e) { // 根据 [Surface sharing between Windows graphics APIs - Win32 apps](https://docs.microsoft.com/en-us/windows/win32/direct3darticles/surface-sharing-between-windows-graphics-apis?WT.mc_id=WD-MVP-5003260 ) 文档 var width = ImageWidth; var height = ImageHeight; // 2021.12.23 不能在 x86 下运行,会炸掉。参阅 https://github.com/dotnet/Silk.NET/issues/731 var texture2DDesc = new D3D11.Texture2DDesc() { BindFlags = (uint)(D3D11.BindFlag.BindRenderTarget | D3D11.BindFlag.BindShaderResource), Format = DXGI.Format.FormatB8G8R8A8Unorm, // 最好使用此格式,否则还需要后续转换 Width = (uint)width, Height = (uint)height, MipLevels = 1, SampleDesc = new DXGI.SampleDesc(1, 0), Usage = D3D11.Usage.UsageDefault, MiscFlags = (uint)D3D11.ResourceMiscFlag.ResourceMiscShared, // The D3D11_RESOURCE_MISC_FLAG cannot be used when creating resources with D3D11_CPU_ACCESS flags. CPUAccessFlags = 0, //(uint) D3D11.CpuAccessFlag.None, ArraySize = 1 }; D3D11.ID3D11Device * pD3D11Device; D3D11.ID3D11DeviceContext *pD3D11DeviceContext; D3DFeatureLevel pD3DFeatureLevel = default; D3D11.D3D11 d3D11 = D3D11.D3D11.GetApi(); var hr = d3D11.CreateDevice((DXGI.IDXGIAdapter *)IntPtr.Zero, D3DDriverType.D3DDriverTypeHardware, Software: 0, Flags: (uint)D3D11.CreateDeviceFlag.CreateDeviceBgraSupport, (D3DFeatureLevel *)IntPtr.Zero, FeatureLevels: 0, // D3DFeatureLevel 的长度 SDKVersion: 7, (D3D11.ID3D11Device * *) & pD3D11Device, // 参阅 [C# 从零开始写 SharpDx 应用 聊聊功能等级](https://blog.lindexi.com/post/C-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E5%86%99-SharpDx-%E5%BA%94%E7%94%A8-%E8%81%8A%E8%81%8A%E5%8A%9F%E8%83%BD%E7%AD%89%E7%BA%A7.html ) ref pD3DFeatureLevel, (D3D11.ID3D11DeviceContext * *) & pD3D11DeviceContext ); SilkMarshal.ThrowHResult(hr); Debugger.Launch(); Debugger.Break(); _pD3D11Device = pD3D11Device; _pD3D11DeviceContext = pD3D11DeviceContext; D3D11.ID3D11Texture2D *pD3D11Texture2D; hr = pD3D11Device->CreateTexture2D(ref texture2DDesc, (D3D11.SubresourceData *)IntPtr.Zero, &pD3D11Texture2D); SilkMarshal.ThrowHResult(hr); var renderTarget = pD3D11Texture2D; _pD3D11Texture2D = pD3D11Texture2D; DXGI.IDXGISurface *pDXGISurface; var dxgiSurfaceGuid = DXGI.IDXGISurface.Guid; renderTarget->QueryInterface(ref dxgiSurfaceGuid, (void **)&pDXGISurface); _pDXGISurface = pDXGISurface; var d2DFactory = new D2D.Factory(); var renderTargetProperties = new D2D.RenderTargetProperties(new D2D.PixelFormat(SharpDXDXGI.Format.Unknown, D2D.AlphaMode.Premultiplied)); var surface = new SharpDXDXGI.Surface(new IntPtr((void *)pDXGISurface)); _d2DRenderTarget = new D2D.RenderTarget(d2DFactory, surface, renderTargetProperties); SetRenderTarget(renderTarget); var viewport = new D3D11.Viewport(0, 0, width, height, 0, 1); pD3D11DeviceContext->RSSetViewports(NumViewports: 1, ref viewport); CompositionTarget.Rendering += CompositionTarget_Rendering; }
private void SetRenderTarget(D3D11.ID3D11Texture2D *target) { DXGI.IDXGIResource *pDXGIResource; var dxgiResourceGuid = DXGI.IDXGIResource.Guid; target->QueryInterface(ref dxgiResourceGuid, (void **)&pDXGIResource); D3D11.Texture2DDesc texture2DDescription = default; target->GetDesc(ref texture2DDescription); void *sharedHandle; var hr = pDXGIResource->GetSharedHandle(&sharedHandle); SilkMarshal.ThrowHResult(hr); var d3d9 = D3D9.D3D9.GetApi(); D3D9.IDirect3D9Ex *pDirect3D9Ex; hr = d3d9.Direct3DCreate9Ex(SDKVersion: 32, &pDirect3D9Ex); SilkMarshal.ThrowHResult(hr); var d3DContext = pDirect3D9Ex; _pDirect3D9Ex = pDirect3D9Ex; var presentParameters = new D3D9.PresentParameters() { Windowed = 1,// true SwapEffect = D3D9.Swapeffect.SwapeffectDiscard, HDeviceWindow = GetDesktopWindow(), PresentationInterval = D3D9.D3D9.PresentIntervalDefault, }; // 设置使用多线程方式,这样的性能才足够 uint createFlags = D3D9.D3D9.CreateHardwareVertexprocessing | D3D9.D3D9.CreateMultithreaded | D3D9.D3D9.CreateFpuPreserve; D3D9.IDirect3DDevice9Ex *pDirect3DDevice9Ex; hr = d3DContext->CreateDeviceEx(Adapter: 0, DeviceType: D3D9.Devtype.DevtypeHal,// 使用硬件渲染 hFocusWindow: IntPtr.Zero, createFlags, ref presentParameters, pFullscreenDisplayMode: (D3D9.Displaymodeex *)IntPtr.Zero, &pDirect3DDevice9Ex); SilkMarshal.ThrowHResult(hr); var d3DDevice = pDirect3DDevice9Ex; D3D9.IDirect3DTexture9 *pDirect3DTexture9; hr = d3DDevice->CreateTexture(texture2DDescription.Width, texture2DDescription.Height, Levels: 1, D3D9.D3D9.UsageRendertarget, D3D9.Format.FmtA8R8G8B8, // 这是必须要求的颜色,不能使用其他颜色 D3D9.Pool.PoolDefault, &pDirect3DTexture9, &sharedHandle); SilkMarshal.ThrowHResult(hr); _renderTarget = pDirect3DTexture9; D3D9.IDirect3DSurface9 *pDirect3DSurface9; _renderTarget->GetSurfaceLevel(0, &pDirect3DSurface9); _pDirect3DSurface9 = pDirect3DSurface9; D3DImage.Lock(); D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, new IntPtr(pDirect3DSurface9)); D3DImage.Unlock(); }
protected override unsafe ID3D12PipelineState *CreatePipelineState() { using ComPtr <ID3D10Blob> pixelShader = null; using ComPtr <ID3D10Blob> vertexShader = null; var compileFlags = 0u; #if DEBUG // Enable better shader debugging with the graphics debugging tools. compileFlags |= (1 << 0) | (1 << 2); #endif fixed(char *fileName = GetAssetFullPath(@"HelloTriangle.hlsl")) { var entryPoint = 0x00006E69614D5356; // VSMain var target = 0x0000305F355F7376; // vs_5_0 ID3D10Blob *errorMsgs; SilkMarshal.ThrowHResult ( _d3d.CompileFromFile ( (char *)fileName, pDefines: null, pInclude: null, (byte *)&entryPoint, (byte *)&target, compileFlags, Flags2: 0, vertexShader.GetAddressOf(), ppErrorMsgs: &errorMsgs ) ); entryPoint = 0x00006E69614D5350; // PSMain target = 0x0000305F355F7370; // ps_5_0 SilkMarshal.ThrowHResult ( _d3d.CompileFromFile ( (char *)fileName, pDefines: null, pInclude: null, (byte *)&entryPoint, (byte *)&target, compileFlags, Flags2: 0, pixelShader.GetAddressOf(), ppErrorMsgs: &errorMsgs ) ); } // Define the vertex input layout. const int InputElementDescsCount = 2; var semanticName0 = stackalloc ulong[2] { 0x4E4F495449534F50, // POSITION 0x0000000000000000, }; var semanticName1 = stackalloc ulong[1] { 0x000000524F4C4F43, // COLOR }; var inputElementDescs = stackalloc InputElementDesc[InputElementDescsCount] { new InputElementDesc { SemanticName = (byte *)semanticName0, Format = Format.FormatR32G32B32Float, InputSlotClass = InputClassification.InputClassificationPerVertexData, }, new InputElementDesc { SemanticName = (byte *)semanticName1, Format = Format.FormatR32G32B32A32Float, AlignedByteOffset = 12, InputSlotClass = InputClassification.InputClassificationPerVertexData, }, }; var defaultRenderTargetBlend = new RenderTargetBlendDesc() { BlendEnable = 0, LogicOpEnable = 0, SrcBlend = Blend.BlendOne, DestBlend = Blend.BlendZero, BlendOp = BlendOp.BlendOpAdd, SrcBlendAlpha = Blend.BlendOne, DestBlendAlpha = Blend.BlendZero, BlendOpAlpha = BlendOp.BlendOpAdd, LogicOp = LogicOp.LogicOpNoop, RenderTargetWriteMask = (byte)ColorWriteEnable.ColorWriteEnableAll }; var defaultStencilOp = new DepthStencilopDesc { StencilFailOp = StencilOp.StencilOpKeep, StencilDepthFailOp = StencilOp.StencilOpKeep, StencilPassOp = StencilOp.StencilOpKeep, StencilFunc = ComparisonFunc.ComparisonFuncAlways }; // Describe and create the graphics pipeline state object (PSO). var psoDesc = new GraphicsPipelineStateDesc { InputLayout = new InputLayoutDesc { PInputElementDescs = inputElementDescs, NumElements = InputElementDescsCount, }, PRootSignature = RootSignature, VS = new ShaderBytecode(vertexShader.Get().GetBufferPointer(), vertexShader.Get().GetBufferSize()), PS = new ShaderBytecode(pixelShader.Get().GetBufferPointer(), pixelShader.Get().GetBufferSize()), RasterizerState = new RasterizerDesc { FillMode = FillMode.FillModeSolid, CullMode = CullMode.CullModeBack, FrontCounterClockwise = 0, DepthBias = D3D12.DefaultDepthBias, DepthBiasClamp = 0, SlopeScaledDepthBias = 0, DepthClipEnable = 1, MultisampleEnable = 0, AntialiasedLineEnable = 0, ForcedSampleCount = 0, ConservativeRaster = ConservativeRasterizationMode.ConservativeRasterizationModeOff, }, BlendState = new BlendDesc { AlphaToCoverageEnable = 0, IndependentBlendEnable = 0, RenderTarget = new BlendDesc.RenderTargetBuffer() { [0] = defaultRenderTargetBlend, [1] = defaultRenderTargetBlend, [2] = defaultRenderTargetBlend, [3] = defaultRenderTargetBlend, [4] = defaultRenderTargetBlend, [5] = defaultRenderTargetBlend, [6] = defaultRenderTargetBlend, [7] = defaultRenderTargetBlend } }, DepthStencilState = new DepthStencilDesc { DepthEnable = 1, DepthWriteMask = DepthWriteMask.DepthWriteMaskAll, DepthFunc = ComparisonFunc.ComparisonFuncLess, StencilEnable = 0, StencilReadMask = D3D12.DefaultStencilReadMask, StencilWriteMask = D3D12.DefaultStencilWriteMask, FrontFace = defaultStencilOp, BackFace = defaultStencilOp }, SampleMask = uint.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.PrimitiveTopologyTypeTriangle, NumRenderTargets = 1, SampleDesc = new SampleDesc(count: 1, quality: 0), }; psoDesc.DepthStencilState.DepthEnable = 0; psoDesc.RTVFormats[0] = Format.FormatR8G8B8A8Unorm; ID3D12PipelineState *pipelineState; var iid = ID3D12PipelineState.Guid; SilkMarshal.ThrowHResult(D3DDevice->CreateGraphicsPipelineState(&psoDesc, &iid, (void **)&pipelineState)); return(pipelineState); }
protected virtual ID3D12Resource *CreateVertexBuffer(out VertexBufferView vertexBufferView) { // Define the geometry for a triangle. const int TriangleVerticesCount = 3; var triangleVertices = stackalloc Vertex[TriangleVerticesCount] { new Vertex { Position = new Vector3(0.0f, 0.5f, 0.0f), Color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f) }, new Vertex { Position = new Vector3(0.5f, -0.5f, 0.0f), Color = new Vector4(0.0f, 1.0f, 0.0f, 1.0f) }, new Vertex { Position = new Vector3(-0.5f, -0.5f, 0.0f), Color = new Vector4(0.0f, 0.0f, 1.0f, 1.0f) }, }; var vertexBufferSize = (uint)sizeof(Vertex) * TriangleVerticesCount; // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. ID3D12Resource *vertexBuffer; var heapProperties = new HeapProperties(HeapType.HeapTypeUpload); var bufferDesc = new ResourceDesc ( ResourceDimension.ResourceDimensionBuffer, 0, vertexBufferSize, 1, 1, 1, Format.FormatUnknown, new SampleDesc(1, 0), TextureLayout.TextureLayoutRowMajor, ResourceFlags.ResourceFlagNone ); var iid = ID3D12Resource.Guid; SilkMarshal.ThrowHResult ( D3DDevice->CreateCommittedResource ( &heapProperties, HeapFlags.HeapFlagNone, &bufferDesc, ResourceStates.ResourceStateGenericRead, pOptimizedClearValue: null, &iid, (void **)&vertexBuffer ) ); // Copy the triangle data to the vertex buffer. var readRange = new Range(); byte *pVertexDataBegin; SilkMarshal.ThrowHResult(vertexBuffer->Map(Subresource: 0, &readRange, (void **)&pVertexDataBegin)); Unsafe.CopyBlock(pVertexDataBegin, triangleVertices, vertexBufferSize); vertexBuffer->Unmap(0, null); // Initialize the vertex buffer view. vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); vertexBufferView.StrideInBytes = (uint)sizeof(Vertex); vertexBufferView.SizeInBytes = vertexBufferSize; return(vertexBuffer); }
public static SystemParameters Create() { var(width, height, _) = GetDisplays().First(d => d.IsPrimary); /*using var f = new SharpDX.DXGI.Factory1(); * var video_memory = f.Adapters1.Select(a => * Math.Max(a.Description.DedicatedSystemMemory, (long)a.Description.DedicatedVideoMemory)).Max();*/ var dxgiMemory = 0UL; unsafe { using var api = DXGI.GetApi(); IDXGIFactory1 *factory1 = default; try { //https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-createdxgifactory1 SilkMarshal.ThrowHResult(api.CreateDXGIFactory1(SilkMarshal.GuidPtrOf <IDXGIFactory1>(), (void **)&factory1)); uint i = 0u; while (true) { IDXGIAdapter1 *adapter1 = default; //https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgifactory1-enumadapters1 var res = factory1->EnumAdapters1(i, &adapter1); var exception = Marshal.GetExceptionForHR(res); if (exception != null) { break; } AdapterDesc1 adapterDesc = default; //https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgiadapter1-getdesc1 SilkMarshal.ThrowHResult(adapter1->GetDesc1(&adapterDesc)); var systemMemory = (ulong)adapterDesc.DedicatedSystemMemory; var videoMemory = (ulong)adapterDesc.DedicatedVideoMemory; var maxMemory = Math.Max(systemMemory, videoMemory); if (maxMemory > dxgiMemory) { dxgiMemory = maxMemory; } adapter1->Release(); i++; } } catch (Exception e) { Utils.ErrorThrow(e); } finally { if (factory1->LpVtbl != (void **)IntPtr.Zero) { factory1->Release(); } } } var memory = Utils.GetMemoryStatus(); return(new SystemParameters { ScreenWidth = width, ScreenHeight = height, VideoMemorySize = (long)dxgiMemory, SystemMemorySize = (long)memory.ullTotalPhys, SystemPageSize = (long)memory.ullTotalPageFile - (long)memory.ullTotalPhys }); }
protected override void CreateDeviceDependentResources() { _dxgiFactory = CreateDxgiFactory(); _dxgiAdapter = GetDxgiAdapter(); _d3dDevice = CreateD3DDevice(); StartInfoPump(); _commandQueue = CreateCommandQueue(); CreateDescriptorHeaps(); for (int i = 0; i < FrameCount; i++) { _commandAllocators[i] = CreateCommandAllocator(); } _fence = CreateFence(); _fenceValues = CreateFenceValues(); _fenceEvent = CreateFenceEvent(); _rootSignature = CreateRootSignature(); _pipelineState = CreatePipelineState(); _graphicsCommandLists = CreateGraphicsCommandLists(); SilkMarshal.ThrowHResult(CommandAllocator->Reset()); SilkMarshal.ThrowHResult(GraphicsCommandList->Reset(CommandAllocator, PipelineState)); CreateAssets(); ID3D12CommandAllocator *CreateCommandAllocator() { ID3D12CommandAllocator *commandAllocator; var iid = ID3D12CommandAllocator.Guid; SilkMarshal.ThrowHResult ( D3DDevice->CreateCommandAllocator (CommandListType.CommandListTypeDirect, &iid, (void **)&commandAllocator) ); return(commandAllocator); } ID3D12CommandQueue *CreateCommandQueue() { var queueDesc = new CommandQueueDesc(); ID3D12CommandQueue *commandQueue; var iid = ID3D12CommandQueue.Guid; SilkMarshal.ThrowHResult(D3DDevice->CreateCommandQueue(&queueDesc, &iid, (void **)&commandQueue)); return(commandQueue); } ID3D12Device *CreateD3DDevice() { ID3D12Device *d3dDevice; var iid = ID3D12Device.Guid; SilkMarshal.ThrowHResult ( D3D12.CreateDevice ((IUnknown *)_dxgiAdapter, D3DFeatureLevel.D3DFeatureLevel110, &iid, (void **)&d3dDevice) ); return(d3dDevice); } IDXGIFactory4 *CreateDxgiFactory() { var dxgiFactoryFlags = TryEnableDebugLayer() ? 0x01 : 0u; IDXGIFactory4 *dxgiFactory; var iid = IDXGIFactory4.Guid; SilkMarshal.ThrowHResult(Dxgi.CreateDXGIFactory2(dxgiFactoryFlags, &iid, (void **)&dxgiFactory)); return(dxgiFactory); } ID3D12Fence *CreateFence() { ID3D12Fence *fence; var iid = ID3D12Fence.Guid; SilkMarshal.ThrowHResult (D3DDevice->CreateFence(InitialValue: 0, FenceFlags.FenceFlagNone, &iid, (void **)&fence)); return(fence); } IntPtr CreateFenceEvent() { var fenceEvent = SilkMarshal.CreateWindowsEvent(null, false, false, null); if (fenceEvent == IntPtr.Zero) { var hr = Marshal.GetHRForLastWin32Error(); Marshal.ThrowExceptionForHR(hr); } return(fenceEvent); } ulong[] CreateFenceValues() { var fenceValues = new ulong[FrameCount]; fenceValues[0] = 1; return(fenceValues); } ID3D12GraphicsCommandList *[] CreateGraphicsCommandLists() { var graphicsCommandLists = new ID3D12GraphicsCommandList *[FrameCount]; for (uint i = 0u; i < FrameCount; i++) { ID3D12GraphicsCommandList *graphicsCommandList; var iid = ID3D12GraphicsCommandList.Guid; SilkMarshal.ThrowHResult ( D3DDevice->CreateCommandList ( nodeMask: 0, CommandListType.CommandListTypeDirect, _commandAllocators[i], PipelineState, &iid, (void **)&graphicsCommandList ) ); SilkMarshal.ThrowHResult(graphicsCommandList->Close()); graphicsCommandLists[i] = graphicsCommandList; } return(graphicsCommandLists); } IDXGIAdapter1 *GetDxgiAdapter() { if (UseWarpDevice) { IDXGIAdapter1 *adapter; var iid = IDXGIAdapter.Guid; SilkMarshal.ThrowHResult(_dxgiFactory->EnumWarpAdapter(&iid, (void **)&adapter)); return(adapter); } else { return(GetHardwareAdapter((IDXGIFactory1 *)_dxgiFactory)); } } bool TryEnableDebugLayer() { #if DEBUG // Enable the debug layer (requires the Graphics Tools "optional feature"). // NOTE: Enabling the debug layer after device creation will invalidate the active device. using ComPtr <ID3D12Debug> debugController = null; var iid = ID3D12Debug.Guid; var hr = D3D12.GetDebugInterface(&iid, (void **)&debugController); if (HResult.IndicatesSuccess(hr)) { debugController.Get().EnableDebugLayer(); Log.LogInformation("Debug layer enabled"); return(_debug = true); } else { Log.LogWarning ( Marshal.GetExceptionForHR(hr), $"Failed to enable debug layer, failed with result {hr} (0x{hr:x8})" ); } #endif return(false); } void StartInfoPump() { #if DEBUG if (!_debug) { Log.LogInformation("Skipped creation of info pump due to the debug layer not being enabled."); return; } var iid = ID3D12InfoQueue.Guid; fixed(ID3D12InfoQueue ** @out = &_infoQueue) { SilkMarshal.ThrowHResult(D3DDevice->QueryInterface(&iid, (void **)@out)); } _infoPumpCancellationToken = new(); _infoPump = Task.Run ( () => { Log.LogInformation("Info queue pump started"); while (!_infoPumpCancellationToken.Token.IsCancellationRequested) { var numMessages = _infoQueue->GetNumStoredMessages(); if (numMessages == 0) { continue; } for (var i = 0ul; i < numMessages; i++) { nuint msgByteLength; SilkMarshal.ThrowHResult(_infoQueue->GetMessageA(i, null, &msgByteLength)); using var memory = GlobalMemory.Allocate((int)msgByteLength); SilkMarshal.ThrowHResult ( _infoQueue->GetMessageA(i, memory.AsPtr <Message>(), &msgByteLength) ); ref var msg = ref memory.AsRef <Message>(); var descBytes = new Span <byte>(msg.PDescription, (int)msg.DescriptionByteLength); var desc = Encoding.UTF8.GetString(descBytes[..^ 1]); var eid = new EventId((int)msg.ID, msg.ID.ToString()["MessageID".Length..]);
protected virtual void CreateAssets() { SilkMarshal.ThrowHResult(GraphicsCommandList->Close()); ExecuteGraphicsCommandList(); WaitForGpu(moveToNextFrame: false); }