protected virtual ID3D12Resource *CreateVertexBuffer(out D3D12_VERTEX_BUFFER_VIEW vertexBufferView) { // Define the geometry for a triangle. const int TriangleVerticesCount = 3; var triangleVertices = stackalloc Vertex[TriangleVerticesCount] { new Vertex { Position = new Vector3(0.0f, 0.25f * AspectRatio, 0.0f), Color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f) }, new Vertex { Position = new Vector3(0.25f, -0.25f * AspectRatio, 0.0f), Color = new Vector4(0.0f, 1.0f, 0.0f, 1.0f) }, 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) * 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 D3D12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD); var bufferDesc = D3D12_RESOURCE_DESC.Buffer(vertexBufferSize); var iid = IID_ID3D12Resource; ThrowIfFailed(nameof(ID3D12Device.CreateCommittedResource), D3DDevice->CreateCommittedResource( &heapProperties, D3D12_HEAP_FLAG_NONE, &bufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ, pOptimizedClearValue: null, &iid, (void **)&vertexBuffer )); // Copy the triangle data to the vertex buffer. var readRange = new D3D12_RANGE(); byte *pVertexDataBegin; ThrowIfFailed(nameof(ID3D12Resource.Map), 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); }
/// <inheritdoc cref="Draw(GraphicsPrimitive)" /> public void Draw(D3D12GraphicsPrimitive graphicsPrimitive) { ThrowIfNull(graphicsPrimitive, nameof(graphicsPrimitive)); var graphicsCommandList = D3D12GraphicsCommandList; var graphicsPipeline = graphicsPrimitive.D3D12GraphicsPipeline; var vertexBuffer = graphicsPrimitive.D3D12VertexBuffer; graphicsCommandList->SetGraphicsRootSignature(graphicsPipeline.D3D12Signature.D3D12RootSignature); graphicsCommandList->SetPipelineState(graphicsPipeline.D3D12PipelineState); var vertexBufferView = new D3D12_VERTEX_BUFFER_VIEW { BufferLocation = vertexBuffer.D3D12Resource->GetGPUVirtualAddress(), StrideInBytes = (uint)vertexBuffer.Stride, SizeInBytes = (uint)vertexBuffer.Size, }; graphicsCommandList->IASetVertexBuffers(StartSlot: 0, NumViews: 1, &vertexBufferView); var constantBuffers = graphicsPrimitive.ConstantBuffers; var constantBuffersLength = constantBuffers.Length; for (var index = 0; index < constantBuffersLength; index++) { var constantBuffer = (D3D12GraphicsBuffer)constantBuffers[index]; graphicsCommandList->SetGraphicsRootConstantBufferView(unchecked ((uint)index), constantBuffer.D3D12Resource->GetGPUVirtualAddress()); } var indexBuffer = graphicsPrimitive.D3D12IndexBuffer; if (indexBuffer != null) { var indexBufferStride = indexBuffer.Stride; var indexFormat = DXGI_FORMAT_R16_UINT; if (indexBufferStride != 2) { Assert(indexBufferStride == 4, "Index Buffer has an unsupported stride."); indexFormat = DXGI_FORMAT_R32_UINT; } var indexBufferView = new D3D12_INDEX_BUFFER_VIEW { BufferLocation = indexBuffer.D3D12Resource->GetGPUVirtualAddress(), SizeInBytes = (uint)indexBuffer.Size, Format = indexFormat, }; graphicsCommandList->IASetIndexBuffer(&indexBufferView); graphicsCommandList->DrawIndexedInstanced(IndexCountPerInstance: (uint)(indexBuffer.Size / indexBufferStride), InstanceCount: 1, StartIndexLocation: 0, BaseVertexLocation: 0, StartInstanceLocation: 0); } else { graphicsCommandList->DrawInstanced(VertexCountPerInstance: (uint)(vertexBuffer.Size / vertexBuffer.Stride), InstanceCount: 1, StartVertexLocation: 0, StartInstanceLocation: 0); } }
/// <summary>Binds a vertex buffer view to the context.</summary> /// <param name="vertexBufferView">The vertex buffer view to bind.</param> /// <param name="bindingSlot">The binding slot to which <paramref name="vertexBufferView" /> should be bound.</param> /// <exception cref="ArgumentNullException"><paramref name="vertexBufferView" /> is <c>null</c>.</exception> public void BindVertexBufferView(GraphicsBufferView vertexBufferView, uint bindingSlot = 0) { ThrowIfNull(vertexBufferView); var d3d12VertexBufferView = new D3D12_VERTEX_BUFFER_VIEW { BufferLocation = vertexBufferView.D3D12GpuVirtualAddress, StrideInBytes = vertexBufferView.BytesPerElement, SizeInBytes = checked ((uint)vertexBufferView.ByteLength), }; D3D12GraphicsCommandList->IASetVertexBuffers(bindingSlot, NumViews: 1, &d3d12VertexBufferView); }
public virtual void IASetVertexBuffers( uint StartSlot, uint NumViews, ref D3D12_VERTEX_BUFFER_VIEW pViews ) { var fp = GetFunctionPointer(44); if (m_IASetVertexBuffersFunc == null) { m_IASetVertexBuffersFunc = (IASetVertexBuffersFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(IASetVertexBuffersFunc)); } m_IASetVertexBuffersFunc(m_ptr, StartSlot, NumViews, ref pViews); }
/// <summary>Binds vertex buffer views to the context.</summary> /// <param name="vertexBufferViews">The vertex buffer views to bind.</param> /// <param name="firstBindingSlot">The first binding slot to which <paramref name="vertexBufferViews" /> should be bound.</param> /// <exception cref="ArgumentNullException">One of the items in <paramref name="vertexBufferViews" /> is <c>null</c>.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="vertexBufferViews" /> is <c>empty</c> or greater than <see cref="MaxBoundVertexBufferViewCount" />.</exception> public void BindVertexBufferViews(ReadOnlySpan <GraphicsBufferView> vertexBufferViews, uint firstBindingSlot) { ThrowIfZero(vertexBufferViews.Length); ThrowIfNotInInsertBounds(vertexBufferViews.Length, D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT); var d3d12VertexBufferViews = stackalloc D3D12_VERTEX_BUFFER_VIEW[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; for (var index = 0; index < vertexBufferViews.Length; index++) { var vertexBufferView = (GraphicsBufferView)vertexBufferViews[index]; ThrowIfNull(vertexBufferView); d3d12VertexBufferViews[index] = new D3D12_VERTEX_BUFFER_VIEW { BufferLocation = vertexBufferView.D3D12GpuVirtualAddress, StrideInBytes = vertexBufferView.BytesPerElement, SizeInBytes = checked ((uint)vertexBufferView.ByteLength), }; } D3D12GraphicsCommandList->IASetVertexBuffers(firstBindingSlot, NumViews: (uint)vertexBufferViews.Length, d3d12VertexBufferViews); }
public unsafe bool Render() { if (!_loadingComplete) { return(false); } ThrowIfFailed(_deviceResources.CommandAllocator->Reset()); ThrowIfFailed(_commandList.Ptr->Reset(_deviceResources.CommandAllocator, _pipelineState.Ptr)); { _commandList.Ptr->SetGraphicsRootSignature(_rootSignature.Ptr); const uint ppHeapsCount = 1; ID3D12DescriptorHeap **ppHeaps = stackalloc ID3D12DescriptorHeap *[(int)ppHeapsCount] { _cbvHeap.Ptr }; _commandList.Ptr->SetDescriptorHeaps(ppHeapsCount, ppHeaps); D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle; _cbvHeap.Ptr->GetGPUDescriptorHandleForHeapStart(&gpuHandle); gpuHandle.ptr += _deviceResources.CurrentFrameIndex * _cbvDescriptorSize; _commandList.Ptr->SetGraphicsRootDescriptorTable(0, gpuHandle); D3D12_VIEWPORT viewport = _deviceResources.ScreenViewport; _commandList.Ptr->RSSetViewports(1, &viewport); D3D12_RECT rect = _scissorRect; _commandList.Ptr->RSSetScissorRects(1, &rect); D3D12_RESOURCE_BARRIER renderTargetResourceBarrier = CD3DX12_RESOURCE_BARRIER.Transition( _deviceResources.RenderTarget, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET ); _commandList.Ptr->ResourceBarrier(1, &renderTargetResourceBarrier); D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView = _deviceResources.RenderTargetView; D3D12_CPU_DESCRIPTOR_HANDLE depthStencilView = _deviceResources.DepthStencilView; _commandList.Ptr->ClearRenderTargetView(renderTargetView, CornflowerBlue, 0, null); _commandList.Ptr->ClearDepthStencilView(depthStencilView, D3D12_CLEAR_FLAG_DEPTH, 1, 0, 0, null); _commandList.Ptr->OMSetRenderTargets(1, &renderTargetView, FALSE, &depthStencilView); _commandList.Ptr->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D12_VERTEX_BUFFER_VIEW vertexBufferView = _vertexBufferView; D3D12_INDEX_BUFFER_VIEW indexBufferView = _indexBufferView; _commandList.Ptr->IASetVertexBuffers(0, 1, &vertexBufferView); _commandList.Ptr->IASetIndexBuffer(&indexBufferView); _commandList.Ptr->DrawIndexedInstanced(36, 1, 0, 0, 0); D3D12_RESOURCE_BARRIER presentResourceBarrier = CD3DX12_RESOURCE_BARRIER.Transition( _deviceResources.RenderTarget, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); _commandList.Ptr->ResourceBarrier(1, &presentResourceBarrier); } ThrowIfFailed(_commandList.Ptr->Close()); const uint ppCommandListsCount = 1; ID3D12CommandList **ppCommandLists = stackalloc ID3D12CommandList *[(int)ppCommandListsCount] { (ID3D12CommandList *)_commandList.Ptr }; _deviceResources.CommandQueue->ExecuteCommandLists(ppCommandListsCount, ppCommandLists); return(true); }