Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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());
            }
        }
Example #4
0
        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);
            }
        }
Example #5
0
        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;
        }
Example #6
0
        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();
        }
Example #7
0
        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);
        }
Example #8
0
        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
            });
        }
Example #10
0
        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..]);
Example #11
0
 protected virtual void CreateAssets()
 {
     SilkMarshal.ThrowHResult(GraphicsCommandList->Close());
     ExecuteGraphicsCommandList();
     WaitForGpu(moveToNextFrame: false);
 }