protected virtual void CreateDescriptorHeaps() { _rtvHeap = CreateRTVHeap(out _rtvDescriptorSize); _dsvHeap = CreateDSVHeap(); ID3D12DescriptorHeap *CreateDSVHeap() { var dsvHeapDesc = new D3D12_DESCRIPTOR_HEAP_DESC { NumDescriptors = 1, Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV, }; ID3D12DescriptorHeap *dsvHeap; ThrowIfFailed(D3DDevice->CreateDescriptorHeap(&dsvHeapDesc, __uuidof <ID3D12DescriptorHeap>(), (void **)&dsvHeap)); return(dsvHeap); } ID3D12DescriptorHeap *CreateRTVHeap(out uint rtvDescriptorSize) { var rtvHeapDesc = new D3D12_DESCRIPTOR_HEAP_DESC { NumDescriptors = FrameCount, Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV, }; ID3D12DescriptorHeap *rtvHeap; ThrowIfFailed(D3DDevice->CreateDescriptorHeap(&rtvHeapDesc, __uuidof <ID3D12DescriptorHeap>(), (void **)&rtvHeap)); rtvDescriptorSize = D3DDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); return(rtvHeap); } }
public virtual int CreateDescriptorHeap( ref D3D12_DESCRIPTOR_HEAP_DESC pDescriptorHeapDesc, ref Guid riid, out IntPtr ppvHeap ) { var fp = GetFunctionPointer(14); if (m_CreateDescriptorHeapFunc == null) { m_CreateDescriptorHeapFunc = (CreateDescriptorHeapFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(CreateDescriptorHeapFunc)); } return(m_CreateDescriptorHeapFunc(m_ptr, ref pDescriptorHeapDesc, ref riid, out ppvHeap)); }
private static D3D12_DESCRIPTOR_HEAP_DESC CreateDesc( D3D12_DESCRIPTOR_HEAP_TYPE type, uint numDescriptors, bool shaderVisible ) { var desc = new D3D12_DESCRIPTOR_HEAP_DESC { Flags = shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE, NodeMask = 0, // TODO: MULTI-GPU NumDescriptors = numDescriptors, Type = type }; return(desc); }
private IntPtr CreateRenderTargetsHeap() { ID3D12DescriptorHeap *renderTargetDescriptorHeap; var renderTargetDescriptorHeapDesc = new D3D12_DESCRIPTOR_HEAP_DESC { Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV, NumDescriptors = (uint)_graphicsSurface.BufferCount, Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE, NodeMask = 0, }; var iid = IID_ID3D12DescriptorHeap; ThrowExternalExceptionIfFailed(nameof(ID3D12Device.CreateDescriptorHeap), Device->CreateDescriptorHeap(&renderTargetDescriptorHeapDesc, &iid, (void **)&renderTargetDescriptorHeap)); return((IntPtr)renderTargetDescriptorHeap); }
private DescriptorHeap(ID3D12Device *device, D3D12_DESCRIPTOR_HEAP_DESC desc) { ComPtr <ID3D12DescriptorHeap> heap = default; Guard.ThrowIfFailed(device->CreateDescriptorHeap(&desc, heap.Guid, (void **)&heap)); _heap = heap.Move(); var cpu = _heap.Get()->GetCPUDescriptorHandleForHeapStart(); var gpu = _heap.Get()->GetGPUDescriptorHandleForHeapStart(); FirstDescriptor = new DescriptorHandle(cpu, gpu, desc.Type); Type = desc.Type; NumDescriptors = desc.NumDescriptors; DirectXHelpers.SetObjectName(_heap.Get(), nameof(ID3D12DescriptorHeap)); }
protected override void CreateDescriptorHeaps() { base.CreateDescriptorHeaps(); _srvHeap = CreateSRVHeap(); ID3D12DescriptorHeap *CreateSRVHeap() { var srvHeapDesc = new D3D12_DESCRIPTOR_HEAP_DESC { NumDescriptors = 1, Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, }; ID3D12DescriptorHeap *srvHeap; ThrowIfFailed(D3DDevice->CreateDescriptorHeap(&srvHeapDesc, __uuidof <ID3D12DescriptorHeap>(), (void **)&srvHeap)); return(srvHeap); } }
protected override void CreateDescriptorHeaps() { _cbvHeap = CreateCBVHeap(); base.CreateDescriptorHeaps(); ID3D12DescriptorHeap *CreateCBVHeap() { var cbvHeapDesc = new D3D12_DESCRIPTOR_HEAP_DESC { NumDescriptors = 1, Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, }; ID3D12DescriptorHeap *cbvHeap; var iid = IID_ID3D12DescriptorHeap; ThrowIfFailed(nameof(ID3D12Device.CreateDescriptorHeap), D3DDevice->CreateDescriptorHeap(&cbvHeapDesc, &iid, (void **)&cbvHeap)); return(cbvHeap); } }
// 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(); } } }
// 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(); } } }