Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        /// <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);
            }
        }
Ejemplo n.º 3
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);
    }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
    /// <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);
        }