Ejemplo n.º 1
0
    protected override void CreateDeviceDependentResources()
    {
        _dxgiFactory = CreateDxgiFactory();
        _dxgiAdapter = GetDxgiAdapter();
        _d3dDevice   = CreateD3DDevice(out _immediateContext);

        CreateAssets();

        ID3D11Device *CreateD3DDevice(out ID3D11DeviceContext *pImmediateContext)
        {
            ID3D11Device *       d3dDevice;
            ID3D11DeviceContext *immediateContext;

            var featureLevel = D3D_FEATURE_LEVEL_11_0;

            ThrowIfFailed(D3D11CreateDevice((IDXGIAdapter *)DxgiAdapter, D3D_DRIVER_TYPE_HARDWARE, Software: HMODULE.NULL, Flags: 0, &featureLevel, FeatureLevels: 1, D3D11_SDK_VERSION, &d3dDevice, pFeatureLevel: null, &immediateContext));

            pImmediateContext = immediateContext;
            return(d3dDevice);
        }

        IDXGIFactory1 *CreateDxgiFactory()
        {
            IDXGIFactory1 *dxgiFactory;

            ThrowIfFailed(CreateDXGIFactory1(__uuidof <IDXGIFactory1>(), (void **)&dxgiFactory));
            return(dxgiFactory);
        }

        IDXGIAdapter1 *GetDxgiAdapter()
        {
            return(UseWarpDevice ? throw new NotImplementedException("WARP Device not supported for D3D11.") : GetHardwareAdapter(_dxgiFactory));
        }
    }
Ejemplo n.º 2
0
    // Helper function for acquiring the first available hardware adapter that supports the required Direct3D version.
    // If no such adapter can be found, returns null.
    protected IDXGIAdapter1 *GetHardwareAdapter(IDXGIFactory1 *pFactory)
    {
        IDXGIAdapter1 *adapter;

        for (var adapterIndex = 0u; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex)
        {
            DXGI_ADAPTER_DESC1 desc;
            _ = adapter->GetDesc1(&desc);

            if ((desc.Flags & (uint)DXGI_ADAPTER_FLAG_SOFTWARE) != 0)
            {
                // Don't select the Basic Render Driver adapter.
                // If you want a software adapter, pass in "/warp" on the command line.
                continue;
            }

            // Check to see if the adapter supports the required Direct3D version, but don't create the
            // actual device yet.
            if (SupportsRequiredDirect3DVersion(adapter))
            {
                break;
            }
        }

        return(adapter);
    }
Ejemplo n.º 3
0
        // Helper function for acquiring the first available hardware adapter that supports the required Direct3D version.
        // If no such adapter can be found, returns null.
        protected IDXGIAdapter1 *GetHardwareAdapter(IDXGIFactory1 *pFactory)
        {
            IDXGIAdapter1 *adapter;

            // TODO DXGI_ERROR_NOT_FOUND is 0x887A0002 - maybe we should add Winerror.h somewhere in Silk.NET.Core?
            const int errorNotFound = unchecked ((int)0x887A0002);

            for (var adapterIndex = 0u;
                 errorNotFound != pFactory->EnumAdapters1(adapterIndex, &adapter);
                 ++adapterIndex)
            {
                AdapterDesc1 desc;
                _ = adapter->GetDesc1(&desc);

                if ((desc.Flags & (uint)AdapterFlag.AdapterFlagSoftware) != 0)
                {
                    // Don't select the Basic Render Driver adapter.
                    // If you want a software adapter, pass in "/warp" on the command line.
                    continue;
                }

                // Check to see if the adapter supports the required Direct3D version, but don't create the
                // actual device yet.
                if (SupportsRequiredDirect3DVersion(adapter))
                {
                    break;
                }
            }

            return(adapter);
        }
Ejemplo n.º 4
0
    protected override void DestroyDeviceDependentResources()
    {
        DestroyAssets();

        DestroyImmediateContext();
        DestroyD3DDevice();
        DestroyDxgiAdapter();
        DestroyDxgiFactory();

        void DestroyD3DDevice()
        {
            var d3dDevice = _d3dDevice;

            if (d3dDevice != null)
            {
                _d3dDevice = null;
                _          = d3dDevice->Release();
            }
        }

        void DestroyDxgiAdapter()
        {
            var dxgiAdapter = _dxgiAdapter;

            if (dxgiAdapter != null)
            {
                _dxgiAdapter = null;
                _            = dxgiAdapter->Release();
            }
        }

        void DestroyDxgiFactory()
        {
            var dxgiFactory = _dxgiFactory;

            if (dxgiFactory != null)
            {
                _dxgiFactory = null;
                _            = dxgiFactory->Release();
            }
        }

        void DestroyImmediateContext()
        {
            var immediateContext = _immediateContext;

            if (immediateContext != null)
            {
                _immediateContext = null;
                _ = immediateContext->Release();
            }
        }
    }
Ejemplo n.º 5
0
        public override void OnInit()
        {
            Guid             iid;
            IDXGIFactory1 *  factory    = null;
            IDXGIAdapter *   adapter    = null;
            ID3D11Texture2D *backBuffer = null;

            try
            {
                iid = IID_IDXGIFactory1;
                ThrowIfFailed(nameof(CreateDXGIFactory1), CreateDXGIFactory1(&iid, (void **)&factory));

                if (UseWarpDevice)
                {
                    throw new NotImplementedException("WARP Device not supported for D3D11.");
                }
                else
                {
                    adapter = GetHardwareAdapter(factory);
                }

                fixed(ID3D11Device **device = &_device)
                fixed(ID3D11DeviceContext **immediateContext = &_immediateContext)
                {
                    var featureLevel = D3D_FEATURE_LEVEL_11_0;

                    ThrowIfFailed(nameof(D3D11CreateDevice), D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, Software: IntPtr.Zero, Flags: 0, &featureLevel, FeatureLevels: 1, D3D11_SDK_VERSION, device, pFeatureLevel: null, immediateContext));
                }

                // Describe and create the swap chain.
                var swapChainDesc = new DXGI_SWAP_CHAIN_DESC {
                    BufferDesc = new DXGI_MODE_DESC {
                        Width  = Width,
                        Height = Height,
                        Format = DXGI_FORMAT_R8G8B8A8_UNORM,
                    },
                    SampleDesc = new DXGI_SAMPLE_DESC {
                        Count = 1
                    },
                    BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT,
                    BufferCount  = FrameCount,
                    OutputWindow = Win32Application.Hwnd,
                    Windowed     = TRUE,
                    SwapEffect   = DXGI_SWAP_EFFECT_DISCARD,
                };

                fixed(IDXGISwapChain **swapChain = &_swapChain)
                {
                    ThrowIfFailed(nameof(IDXGIFactory1.CreateSwapChain), factory->CreateSwapChain(
                                      (IUnknown *)_device,
                                      &swapChainDesc,
                                      swapChain
                                      ));
                }

                // This sample does not support fullscreen transitions.
                ThrowIfFailed(nameof(IDXGIFactory.MakeWindowAssociation), factory->MakeWindowAssociation(Win32Application.Hwnd, DXGI_MWA_NO_ALT_ENTER));

                fixed(ID3D11RenderTargetView **renderTarget = &_renderTarget)
                {
                    iid = IID_ID3D11Texture2D;

                    ThrowIfFailed(nameof(IDXGISwapChain.GetBuffer), _swapChain->GetBuffer(0, &iid, (void **)&backBuffer));
                    ThrowIfFailed(nameof(ID3D11Device.CreateRenderTargetView), _device->CreateRenderTargetView((ID3D11Resource *)backBuffer, null, renderTarget));

                    _immediateContext->OMSetRenderTargets(1, renderTarget, pDepthStencilView: null);
                }

                var vp = new D3D11_VIEWPORT {
                    Width    = Width,
                    Height   = Height,
                    MinDepth = 0.0f,
                    MaxDepth = 1.0f,
                    TopLeftX = 0,
                    TopLeftY = 0,
                };
                _immediateContext->RSSetViewports(1, &vp);
            }
            finally
            {
                if (backBuffer != null)
                {
                    _ = backBuffer->Release();
                }

                if (adapter != null)
                {
                    _ = adapter->Release();
                }

                if (factory != null)
                {
                    _ = factory->Release();
                }
            }
        }
        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
            });
        }
Ejemplo n.º 7
0
        public override void OnInit()
        {
            Guid             iid;
            IDXGIFactory1 *  factory          = null;
            IDXGIAdapter *   adapter          = null;
            ID3D11Texture2D *backBuffer       = null;
            ID3DBlob *       vertexShaderBlob = null;
            ID3DBlob *       pixelShaderBlob  = null;

            try
            {
                iid = IID_IDXGIFactory1;
                ThrowIfFailed(nameof(CreateDXGIFactory1), CreateDXGIFactory1(&iid, (void **)&factory));

                if (UseWarpDevice)
                {
                    throw new NotImplementedException("WARP Device not supported for D3D11.");
                }
                else
                {
                    adapter = GetHardwareAdapter(factory);
                }

                fixed(ID3D11Device **device = &_device)
                fixed(ID3D11DeviceContext **immediateContext = &_immediateContext)
                {
                    var featureLevel = D3D_FEATURE_LEVEL_11_0;

                    ThrowIfFailed(nameof(D3D11CreateDevice), D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, Software: IntPtr.Zero, Flags: 0, &featureLevel, FeatureLevels: 1, D3D11_SDK_VERSION, device, pFeatureLevel: null, immediateContext));
                }

                // Describe and create the swap chain.
                var swapChainDesc = new DXGI_SWAP_CHAIN_DESC {
                    BufferDesc = new DXGI_MODE_DESC {
                        Width  = Width,
                        Height = Height,
                        Format = DXGI_FORMAT_R8G8B8A8_UNORM,
                    },
                    SampleDesc = new DXGI_SAMPLE_DESC {
                        Count = 1
                    },
                    BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT,
                    BufferCount  = FrameCount,
                    OutputWindow = Win32Application.Hwnd,
                    Windowed     = TRUE,
                    SwapEffect   = DXGI_SWAP_EFFECT_DISCARD,
                };

                fixed(IDXGISwapChain **swapChain = &_swapChain)
                {
                    ThrowIfFailed(nameof(IDXGIFactory1.CreateSwapChain), factory->CreateSwapChain(
                                      (IUnknown *)_device,
                                      &swapChainDesc,
                                      swapChain
                                      ));
                }

                // This sample does not support fullscreen transitions.
                ThrowIfFailed(nameof(IDXGIFactory.MakeWindowAssociation), factory->MakeWindowAssociation(Win32Application.Hwnd, DXGI_MWA_NO_ALT_ENTER));

                fixed(ID3D11RenderTargetView **renderTarget = &_renderTarget)
                {
                    iid = IID_ID3D11Texture2D;

                    ThrowIfFailed(nameof(IDXGISwapChain.GetBuffer), _swapChain->GetBuffer(0, &iid, (void **)&backBuffer));
                    ThrowIfFailed(nameof(ID3D11Device.CreateRenderTargetView), _device->CreateRenderTargetView((ID3D11Resource *)backBuffer, null, renderTarget));

                    _immediateContext->OMSetRenderTargets(1, renderTarget, pDepthStencilView: null);
                }

                var vp = new D3D11_VIEWPORT {
                    Width    = Width,
                    Height   = Height,
                    MinDepth = 0.0f,
                    MaxDepth = 1.0f,
                    TopLeftX = 0,
                    TopLeftY = 0,
                };
                _immediateContext->RSSetViewports(1, &vp);

                var compileFlags = 0u;

                fixed(char *fileName = GetAssetFullPath(@"D3D11\Assets\Shaders\HelloTriangle.hlsl"))
                fixed(ID3D11VertexShader **vertexShader = &_vertexShader)
                fixed(ID3D11PixelShader **pixelShader   = &_pixelShader)
                {
                    var entryPoint = 0x00006E69614D5356;    // VSMain
                    var target     = 0x0000305F345F7376;    // vs_4_0

                    ThrowIfFailed(nameof(D3DCompileFromFile), D3DCompileFromFile((ushort *)fileName, null, null, (sbyte *)&entryPoint, (sbyte *)&target, compileFlags, 0, &vertexShaderBlob, null));

                    ThrowIfFailed(nameof(ID3D11Device.CreateVertexShader), _device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), pClassLinkage: null, vertexShader));

                    entryPoint = 0x00006E69614D5350;        // PSMain
                    target     = 0x0000305F345F7370;        // ps_4_0
                    ThrowIfFailed(nameof(D3DCompileFromFile), D3DCompileFromFile((ushort *)fileName, null, null, (sbyte *)&entryPoint, (sbyte *)&target, compileFlags, 0, &pixelShaderBlob, null));

                    ThrowIfFailed(nameof(ID3D11Device.CreatePixelShader), _device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), pClassLinkage: null, pixelShader));
                }

                var inputElementDescs = stackalloc D3D11_INPUT_ELEMENT_DESC[2];
                {
                    var semanticName0 = stackalloc sbyte[9];
                    {
                        ((ulong *)semanticName0)[0] = 0x4E4F495449534F50;      // POSITION
                    }
                    inputElementDescs[0] = new D3D11_INPUT_ELEMENT_DESC {
                        SemanticName         = semanticName0,
                        SemanticIndex        = 0,
                        Format               = DXGI_FORMAT_R32G32B32_FLOAT,
                        InputSlot            = 0,
                        AlignedByteOffset    = 0,
                        InputSlotClass       = D3D11_INPUT_PER_VERTEX_DATA,
                        InstanceDataStepRate = 0
                    };

                    var semanticName1 = 0x000000524F4C4F43;                     // COLOR
                    inputElementDescs[1] = new D3D11_INPUT_ELEMENT_DESC {
                        SemanticName         = (sbyte *)&semanticName1,
                        SemanticIndex        = 0,
                        Format               = DXGI_FORMAT_R32G32B32A32_FLOAT,
                        InputSlot            = 0,
                        AlignedByteOffset    = 12,
                        InputSlotClass       = D3D11_INPUT_PER_VERTEX_DATA,
                        InstanceDataStepRate = 0
                    };
                }

                fixed(ID3D11InputLayout **inputLayout = &_inputLayout)
                {
                    ThrowIfFailed(nameof(ID3D11Device.CreateInputLayout), _device->CreateInputLayout(inputElementDescs, NumElements: 2, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), inputLayout));
                }

                _immediateContext->IASetInputLayout(_inputLayout);

                var triangleVertices = stackalloc Vertex[3];
                {
                    triangleVertices[0] = new Vertex {
                        Position = new Vector3(0.0f, 0.25f * AspectRatio, 0.0f),
                        Color    = new Vector4(1.0f, 0.0f, 0.0f, 1.0f)
                    };
                    triangleVertices[1] = new Vertex {
                        Position = new Vector3(0.25f, -0.25f * AspectRatio, 0.0f),
                        Color    = new Vector4(0.0f, 1.0f, 0.0f, 1.0f)
                    };
                    triangleVertices[2] = new Vertex {
                        Position = new Vector3(-0.25f, -0.25f * AspectRatio, 0.0f),
                        Color    = new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
                    };
                }

                var vertexBufferSize = (uint)sizeof(Vertex) * 3;

                var vertexBufferDesc = new D3D11_BUFFER_DESC {
                    ByteWidth = vertexBufferSize,
                    Usage     = D3D11_USAGE_DEFAULT,
                    BindFlags = (uint)D3D11_BIND_VERTEX_BUFFER
                };

                var vertexBufferData = new D3D11_SUBRESOURCE_DATA {
                    pSysMem = triangleVertices
                };

                fixed(ID3D11Buffer **vertexBuffer = &_vertexBuffer)
                {
                    ThrowIfFailed(nameof(ID3D11Device.CreateBuffer), _device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, vertexBuffer));

                    var stride = (uint)sizeof(Vertex);
                    var offset = 0u;

                    _immediateContext->IASetVertexBuffers(0, 1, vertexBuffer, &stride, &offset);
                }

                _immediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
            }
            finally
            {
                if (pixelShaderBlob != null)
                {
                    _ = pixelShaderBlob->Release();
                }

                if (vertexShaderBlob != null)
                {
                    _ = vertexShaderBlob->Release();
                }

                if (backBuffer != null)
                {
                    _ = backBuffer->Release();
                }

                if (adapter != null)
                {
                    _ = adapter->Release();
                }

                if (factory != null)
                {
                    _ = factory->Release();
                }
            }
        }