/// <summary> /// Creates a new <see cref="GraphicsDevice"/> instance for the input <see cref="ID3D12Device"/>. /// </summary> /// <param name="d3D12Device">The <see cref="ID3D12Device"/> to use for the new <see cref="GraphicsDevice"/> instance.</param> /// <param name="dxgiAdapter">The <see cref="IDXGIAdapter"/> that <paramref name="d3D12Device"/> was created from.</param> /// <param name="dxgiDescription1">The available info for the new <see cref="GraphicsDevice"/> instance.</param> internal GraphicsDevice(ID3D12Device *d3D12Device, IDXGIAdapter *dxgiAdapter, DXGI_ADAPTER_DESC1 *dxgiDescription1) { this.d3D12Device = new ComPtr <ID3D12Device>(d3D12Device); this.d3D12ComputeCommandQueue = d3D12Device->CreateCommandQueue(D3D12_COMMAND_LIST_TYPE_COMPUTE); this.d3D12CopyCommandQueue = d3D12Device->CreateCommandQueue(D3D12_COMMAND_LIST_TYPE_COPY); this.d3D12ComputeFence = d3D12Device->CreateFence(); this.d3D12CopyFence = d3D12Device->CreateFence(); this.computeCommandAllocatorPool = new ID3D12CommandAllocatorPool(D3D12_COMMAND_LIST_TYPE_COMPUTE); this.copyCommandAllocatorPool = new ID3D12CommandAllocatorPool(D3D12_COMMAND_LIST_TYPE_COPY); this.shaderResourceViewDescriptorAllocator = new ID3D12DescriptorHandleAllocator(d3D12Device); Luid = Luid.FromLUID(dxgiDescription1->AdapterLuid); Name = new string((char *)dxgiDescription1->Description); DedicatedMemorySize = dxgiDescription1->DedicatedVideoMemory; SharedMemorySize = dxgiDescription1->SharedSystemMemory; IsHardwareAccelerated = (dxgiDescription1->Flags & (uint)DXGI_ADAPTER_FLAG_SOFTWARE) == 0; var d3D12Options1Data = d3D12Device->CheckFeatureSupport <D3D12_FEATURE_DATA_D3D12_OPTIONS1>(D3D12_FEATURE_D3D12_OPTIONS1); ComputeUnits = d3D12Options1Data.TotalLaneCount; WavefrontSize = d3D12Options1Data.WaveLaneCountMin; var d3D12Architecture1Data = d3D12Device->CheckFeatureSupport <D3D12_FEATURE_DATA_ARCHITECTURE1>(D3D12_FEATURE_ARCHITECTURE1); IsCacheCoherentUMA = d3D12Architecture1Data.CacheCoherentUMA != 0; D3D12MA_ALLOCATOR_DESC allocatorDesc = default; allocatorDesc.pDevice = d3D12Device; allocatorDesc.pAdapter = dxgiAdapter; if (!IsCacheCoherentUMA) { fixed(D3D12MA_Allocator **allocator = this.allocator) { D3D12MemAlloc.D3D12MA_CreateAllocator(&allocatorDesc, allocator).Assert(); } } }
/// <summary> /// Creates a new <see cref="GraphicsDevice"/> instance for the input <see cref="ID3D12Device"/>. /// </summary> /// <param name="d3D12Device">The <see cref="ID3D12Device"/> to use for the new <see cref="GraphicsDevice"/> instance.</param> /// <param name="dxgiAdapter">The <see cref="IDXGIAdapter"/> that <paramref name="d3D12Device"/> was created from.</param> /// <param name="dxgiDescription1">The available info for the new <see cref="GraphicsDevice"/> instance.</param> internal GraphicsDevice(ID3D12Device *d3D12Device, IDXGIAdapter *dxgiAdapter, DXGI_ADAPTER_DESC1 *dxgiDescription1) { this.d3D12Device = new ComPtr <ID3D12Device>(d3D12Device); this.d3D12ComputeCommandQueue = d3D12Device->CreateCommandQueue(D3D12_COMMAND_LIST_TYPE_COMPUTE); this.d3D12CopyCommandQueue = d3D12Device->CreateCommandQueue(D3D12_COMMAND_LIST_TYPE_COPY); this.d3D12ComputeFence = d3D12Device->CreateFence(); this.d3D12CopyFence = d3D12Device->CreateFence(); this.shaderResourceViewDescriptorAllocator = new ID3D12DescriptorHandleAllocator(d3D12Device); this.computeCommandListPool = new ID3D12CommandListPool(D3D12_COMMAND_LIST_TYPE_COMPUTE); this.copyCommandListPool = new ID3D12CommandListPool(D3D12_COMMAND_LIST_TYPE_COPY); Luid = Luid.FromLUID(dxgiDescription1->AdapterLuid); Name = new string((char *)dxgiDescription1->Description); DedicatedMemorySize = dxgiDescription1->DedicatedVideoMemory; SharedMemorySize = dxgiDescription1->SharedSystemMemory; IsHardwareAccelerated = (dxgiDescription1->Flags & (uint)DXGI_ADAPTER_FLAG_SOFTWARE) == 0; var d3D12Options1Data = d3D12Device->CheckFeatureSupport <D3D12_FEATURE_DATA_D3D12_OPTIONS1>(D3D12_FEATURE_D3D12_OPTIONS1); ComputeUnits = d3D12Options1Data.TotalLaneCount; WavefrontSize = d3D12Options1Data.WaveLaneCountMin; var d3D12Architecture1Data = d3D12Device->CheckFeatureSupport <D3D12_FEATURE_DATA_ARCHITECTURE1>(D3D12_FEATURE_ARCHITECTURE1); IsCacheCoherentUMA = d3D12Architecture1Data.CacheCoherentUMA != 0; #if NET6_0_OR_GREATER this.allocator = d3D12Device->CreateAllocator(dxgiAdapter); if (IsCacheCoherentUMA) { this.pool = this.allocator.Get()->CreatePoolForCacheCoherentUMA(); } #endif }
// Load the rendering pipeline dependencies. private void LoadPipeline() { Guid iid; ID3D12Debug * debugController = null; IDXGIFactory4 * factory = null; IDXGIAdapter * adapter = null; IDXGISwapChain1 *swapChain = null; try { var dxgiFactoryFlags = 0u; #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. { iid = IID_ID3D12Debug; if (SUCCEEDED(D3D12GetDebugInterface(&iid, (void **)&debugController))) { debugController->EnableDebugLayer(); // Enable additional debug layers. dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; } } #endif iid = IID_IDXGIFactory4; ThrowIfFailed(nameof(CreateDXGIFactory2), CreateDXGIFactory2(dxgiFactoryFlags, &iid, (void **)&factory)); if (UseWarpDevice) { iid = IID_IDXGIAdapter; ThrowIfFailed(nameof(IDXGIFactory4.EnumWarpAdapter), factory->EnumWarpAdapter(&iid, (void **)&adapter)); } else { adapter = GetHardwareAdapter((IDXGIFactory1 *)factory); } fixed(ID3D12Device **device = &_device) { iid = IID_ID3D12Device; ThrowIfFailed(nameof(D3D12CreateDevice), D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_11_0, &iid, (void **)device)); } // Describe and create the command queue. var queueDesc = new D3D12_COMMAND_QUEUE_DESC(); fixed(ID3D12CommandQueue **commandQueue = &_commandQueue) { iid = IID_ID3D12CommandQueue; ThrowIfFailed(nameof(ID3D12Device.CreateCommandQueue), _device->CreateCommandQueue(&queueDesc, &iid, (void **)commandQueue)); } // Describe and create the swap chain. var swapChainDesc = new DXGI_SWAP_CHAIN_DESC1 { BufferCount = FrameCount, Width = Width, Height = Height, Format = DXGI_FORMAT_R8G8B8A8_UNORM, BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD, SampleDesc = new DXGI_SAMPLE_DESC(count: 1, quality: 0), }; ThrowIfFailed(nameof(IDXGIFactory4.CreateSwapChainForHwnd), factory->CreateSwapChainForHwnd( (IUnknown *)_commandQueue, // Swap chain needs the queue so that it can force a flush on it. Win32Application.Hwnd, &swapChainDesc, pFullscreenDesc: null, pRestrictToOutput: null, &swapChain )); // This sample does not support fullscreen transitions. ThrowIfFailed(nameof(IDXGIFactory4.MakeWindowAssociation), factory->MakeWindowAssociation(Win32Application.Hwnd, DXGI_MWA_NO_ALT_ENTER)); fixed(IDXGISwapChain3 **swapChain3 = &_swapChain) { iid = IID_IDXGISwapChain3; ThrowIfFailed(nameof(IDXGISwapChain1.QueryInterface), swapChain->QueryInterface(&iid, (void **)swapChain3)); _frameIndex = _swapChain->GetCurrentBackBufferIndex(); } // Create descriptor heaps. { // Describe and create a render target view (RTV) descriptor heap. var rtvHeapDesc = new D3D12_DESCRIPTOR_HEAP_DESC { NumDescriptors = FrameCount, Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV, }; fixed(ID3D12DescriptorHeap **rtvHeap = &_rtvHeap) { iid = IID_ID3D12DescriptorHeap; ThrowIfFailed(nameof(ID3D12Device.CreateDescriptorHeap), _device->CreateDescriptorHeap(&rtvHeapDesc, &iid, (void **)rtvHeap)); } _rtvDescriptorSize = _device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); } // Create frame resources. { var rtvHandle = _rtvHeap->GetCPUDescriptorHandleForHeapStart(); // Create a RTV for each frame. iid = IID_ID3D12Resource; for (var n = 0u; n < FrameCount; n++) { ID3D12Resource *renderTarget; { ThrowIfFailed(nameof(IDXGISwapChain3.GetBuffer), _swapChain->GetBuffer(n, &iid, (void **)&renderTarget)); _device->CreateRenderTargetView(renderTarget, pDesc: null, rtvHandle); rtvHandle.Offset(1, _rtvDescriptorSize); } _renderTargets[unchecked ((int)n)] = renderTarget; } } fixed(ID3D12CommandAllocator **commandAllocator = &_commandAllocator) { iid = IID_ID3D12CommandAllocator; ThrowIfFailed(nameof(ID3D12Device.CreateRenderTargetView), _device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, &iid, (void **)commandAllocator)); } fixed(ID3D12CommandAllocator **bundleAllocator = &_bundleAllocator) { iid = IID_ID3D12CommandAllocator; ThrowIfFailed(nameof(ID3D12Device.CreateRenderTargetView), _device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_BUNDLE, &iid, (void **)bundleAllocator)); } } finally { if (debugController != null) { debugController->Release(); } if (factory != null) { factory->Release(); } if (adapter != null) { adapter->Release(); } if (swapChain != null) { swapChain->Release(); } } }
public static extern int D3D10CreateDeviceAndSwapChain1(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, [NativeTypeName("HMODULE")] IntPtr Software, [NativeTypeName("UINT")] uint Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, [NativeTypeName("UINT")] uint SDKVersion, DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, IDXGISwapChain **ppSwapChain, ID3D10Device1 **ppDevice);
public static extern int D3D10CreateDevice1(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, [NativeTypeName("HMODULE")] IntPtr Software, [NativeTypeName("UINT")] uint Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, [NativeTypeName("UINT")] uint SDKVersion, ID3D10Device1 **ppDevice);
// Load the rendering pipeline dependencies. private void LoadPipeline() { Guid iid; ID3D12Debug * debugController = null; IDXGIFactory4 * factory = null; IDXGIAdapter * adapter = null; IDXGISwapChain1 *swapChain = null; try { var dxgiFactoryFlags = 0u; #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. { iid = IID_ID3D12Debug; if (SUCCEEDED(D3D12GetDebugInterface(&iid, (void **)&debugController))) { debugController->EnableDebugLayer(); // Enable additional debug layers. dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; } } #endif iid = IID_IDXGIFactory4; ThrowIfFailed(nameof(CreateDXGIFactory2), CreateDXGIFactory2(dxgiFactoryFlags, &iid, (void **)&factory)); if (UseWarpDevice) { iid = IID_IDXGIAdapter; ThrowIfFailed(nameof(IDXGIFactory4.EnumWarpAdapter), factory->EnumWarpAdapter(&iid, (void **)&adapter)); } else { adapter = GetHardwareAdapter((IDXGIFactory1 *)factory); } fixed(ID3D12Device **device = &_device) { iid = IID_ID3D12Device; ThrowIfFailed(nameof(D3D12CreateDevice), D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_11_0, &iid, (void **)device)); } // Describe and create the command queue. var queueDesc = new D3D12_COMMAND_QUEUE_DESC(); fixed(ID3D12CommandQueue **commandQueue = &_commandQueue) { iid = IID_ID3D12CommandQueue; ThrowIfFailed(nameof(ID3D12Device.CreateCommandQueue), _device->CreateCommandQueue(&queueDesc, &iid, (void **)commandQueue)); } // Describe and create the swap chain. var swapChainDesc = new DXGI_SWAP_CHAIN_DESC1 { BufferCount = FrameCount, Width = Width, Height = Height, Format = DXGI_FORMAT_B8G8R8A8_UNORM, BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD, // The swap chain could do multisampling for you in older versions of Direct3D // You might see this in tutorials for D3D11 // This is no longer supported, so the swapchain has no multisampling itself SampleDesc = new DXGI_SAMPLE_DESC(count: 1, quality: 0), }; ThrowIfFailed(nameof(IDXGIFactory4.CreateSwapChainForHwnd), factory->CreateSwapChainForHwnd( (IUnknown *)_commandQueue, // Swap chain needs the queue so that it can force a flush on it. Win32Application.Hwnd, &swapChainDesc, pFullscreenDesc: null, pRestrictToOutput: null, &swapChain )); // This sample does not support fullscreen transitions. ThrowIfFailed(nameof(IDXGIFactory4.MakeWindowAssociation), factory->MakeWindowAssociation(Win32Application.Hwnd, DXGI_MWA_NO_ALT_ENTER)); fixed(IDXGISwapChain3 **swapChain3 = &_swapChain) { iid = IID_IDXGISwapChain3; ThrowIfFailed(nameof(IDXGISwapChain1.QueryInterface), swapChain->QueryInterface(&iid, (void **)swapChain3)); _frameIndex = _swapChain->GetCurrentBackBufferIndex(); } // Check MSAA support CheckMultiSamplingSupport(); // Create descriptor heaps. { // Describe and create a render target view (RTV) descriptor heap. var rtvHeapDesc = new D3D12_DESCRIPTOR_HEAP_DESC { NumDescriptors = 1, // We only have 1 render target Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV, }; fixed(ID3D12DescriptorHeap **rtvHeap = &_rtvHeap) { iid = IID_ID3D12DescriptorHeap; ThrowIfFailed(nameof(ID3D12Device.CreateDescriptorHeap), _device->CreateDescriptorHeap(&rtvHeapDesc, &iid, (void **)rtvHeap)); } _rtvDescriptorSize = _device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); } // Create the render target // We do not use the back buffer as that cannot be multisampled { var desc = new D3D12_RESOURCE_DESC { Height = Height, Width = Width, DepthOrArraySize = 1, Alignment = 0, SampleDesc = _msaaDesc, Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D, Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, Format = DXGI_FORMAT_B8G8R8A8_UNORM, Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, MipLevels = 1 }; var heapProperties = new D3D12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); var clearColor = stackalloc float[4] { 0.0f, 0.2f, 0.4f, 1.0f }; var clearVal = new D3D12_CLEAR_VALUE(DXGI_FORMAT_B8G8R8A8_UNORM, clearColor); ID3D12Resource *multisampledRenderTarget; iid = IID_ID3D12Resource; ThrowIfFailed(nameof(ID3D12Device.CreateCommittedResource), _device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clearVal, &iid, (void **)&multisampledRenderTarget)); _multiSampledRenderTarget = multisampledRenderTarget; } // Create the render target for the multisampled render target { var rtvHandle = _rtvHeap->GetCPUDescriptorHandleForHeapStart(); _device->CreateRenderTargetView(_multiSampledRenderTarget, pDesc: null, rtvHandle); } // Create frame resources. { iid = IID_ID3D12Resource; for (var n = 0u; n < FrameCount; n++) { ID3D12Resource *renderTarget; { ThrowIfFailed(nameof(IDXGISwapChain3.GetBuffer), _swapChain->GetBuffer(n, &iid, (void **)&renderTarget)); } _renderTargets[unchecked ((int)n)] = renderTarget; } } fixed(ID3D12CommandAllocator **commandAllocator = &_commandAllocator) { iid = IID_ID3D12CommandAllocator; ThrowIfFailed(nameof(ID3D12Device.CreateRenderTargetView), _device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, &iid, (void **)commandAllocator)); } } finally { if (debugController != null) { debugController->Release(); } if (factory != null) { factory->Release(); } if (adapter != null) { adapter->Release(); } if (swapChain != null) { swapChain->Release(); } } }
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 extern int D3D10CreateDevice(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, [NativeTypeName("HMODULE")] IntPtr Software, [NativeTypeName("UINT")] uint Flags, [NativeTypeName("UINT")] uint SDKVersion, ID3D10Device **ppDevice);
public static extern HRESULT D3D11CreateDeviceAndSwapChain(IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, uint Flags, [NativeTypeName("const D3D_FEATURE_LEVEL *")] D3D_FEATURE_LEVEL *pFeatureLevels, uint FeatureLevels, uint SDKVersion, [NativeTypeName("const DXGI_SWAP_CHAIN_DESC *")] DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, IDXGISwapChain **ppSwapChain, ID3D11Device **ppDevice, D3D_FEATURE_LEVEL *pFeatureLevel, ID3D11DeviceContext **ppImmediateContext);
public static extern HRESULT D3D11CreateDevice(IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, uint Flags, [NativeTypeName("const D3D_FEATURE_LEVEL *")] D3D_FEATURE_LEVEL *pFeatureLevels, uint FeatureLevels, uint SDKVersion, ID3D11Device **ppDevice, D3D_FEATURE_LEVEL *pFeatureLevel, ID3D11DeviceContext **ppImmediateContext);
public static extern int D3D10CreateDeviceAndSwapChain([NativeTypeName("IDXGIAdapter *")] IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, [NativeTypeName("HMODULE")] IntPtr Software, [NativeTypeName("UINT")] uint Flags, [NativeTypeName("UINT")] uint SDKVersion, [NativeTypeName("DXGI_SWAP_CHAIN_DESC *")] DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, [NativeTypeName("IDXGISwapChain **")] IDXGISwapChain **ppSwapChain, [NativeTypeName("ID3D10Device **")] ID3D10Device **ppDevice);
public static extern HRESULT D3D10CreateDeviceAndSwapChain1(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, uint Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, uint SDKVersion, DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, IDXGISwapChain **ppSwapChain, ID3D10Device1 **ppDevice);
public static extern HRESULT D3D10CreateDevice1(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, uint Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, uint SDKVersion, ID3D10Device1 **ppDevice);
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(); } } }
public static extern HRESULT D3D10CreateDevice(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, uint Flags, uint SDKVersion, ID3D10Device **ppDevice);