private void DrawRenderItems(GraphicsCommandList cmdList, List <RenderItem> ritems)
        {
            int objCBByteSize = D3DUtil.CalcConstantBufferByteSize <ObjectConstants>();
            int matCBByteSize = D3DUtil.CalcConstantBufferByteSize <MaterialConstants>();

            Resource objectCB = CurrFrameResource.ObjectCB.Resource;
            Resource matCB    = CurrFrameResource.MaterialCB.Resource;

            foreach (RenderItem ri in ritems)
            {
                cmdList.SetVertexBuffer(0, ri.Geo.VertexBufferView);
                cmdList.SetIndexBuffer(ri.Geo.IndexBufferView);
                cmdList.PrimitiveTopology = ri.PrimitiveType;

                GpuDescriptorHandle tex = _srvDescriptorHeap.GPUDescriptorHandleForHeapStart + ri.Mat.DiffuseSrvHeapIndex * CbvSrvUavDescriptorSize;

                long objCBAddress = objectCB.GPUVirtualAddress + ri.ObjCBIndex * objCBByteSize;
                long matCBAddress = matCB.GPUVirtualAddress + ri.Mat.MatCBIndex * matCBByteSize;

                cmdList.SetGraphicsRootDescriptorTable(0, tex);
                cmdList.SetGraphicsRootConstantBufferView(1, objCBAddress);
                cmdList.SetGraphicsRootConstantBufferView(3, matCBAddress);

                cmdList.DrawIndexedInstanced(ri.IndexCount, 1, ri.StartIndexLocation, ri.BaseVertexLocation, 0);
            }
        }
        private void DrawSceneToShadowMap()
        {
            CommandList.SetViewport(_shadowMap.Viewport);
            CommandList.SetScissorRectangles(_shadowMap.ScissorRectangle);

            // Change to DEPTH_WRITE.
            CommandList.ResourceBarrierTransition(_shadowMap.Resource, ResourceStates.GenericRead, ResourceStates.DepthWrite);

            int passCBByteSize = D3DUtil.CalcConstantBufferByteSize <PassConstants>();

            // Clear the depth buffer.
            CommandList.ClearDepthStencilView(_shadowMap.Dsv, ClearFlags.FlagsDepth | ClearFlags.FlagsStencil, 1.0f, 0);

            // Set null render target because we are only going to draw to
            // depth buffer. Setting a null render target will disable color writes.
            // Note the active PSO also must specify a render target count of 0.
            CommandList.SetRenderTargets((CpuDescriptorHandle?)null, _shadowMap.Dsv);

            // Bind the pass constant buffer for shadow map pass.
            Resource passCB        = CurrFrameResource.PassCB.Resource;
            long     passCBAddress = passCB.GPUVirtualAddress + passCBByteSize;

            CommandList.SetGraphicsRootConstantBufferView(1, passCBAddress);

            CommandList.PipelineState = _psos["shadow_opaque"];
            DrawRenderItems(CommandList, _ritemLayers[RenderLayer.Opaque]);

            // Change back to GENERIC_READ so we can read the texture in a shader.
            CommandList.ResourceBarrierTransition(_shadowMap.Resource, ResourceStates.DepthWrite, ResourceStates.GenericRead);
        }
        protected override void Draw(GameTimer gt)
        {
            CommandAllocator cmdListAlloc = CurrFrameResource.CmdListAlloc;

            // Reuse the memory associated with command recording.
            // We can only reset when the associated command lists have finished execution on the GPU.
            cmdListAlloc.Reset();

            // A command list can be reset after it has been added to the command queue via ExecuteCommandList.
            // Reusing the command list reuses memory.
            CommandList.Reset(cmdListAlloc, _psos["opaque"]);

            CommandList.SetViewport(Viewport);
            CommandList.SetScissorRectangles(ScissorRectangle);

            // Indicate a state transition on the resource usage.
            CommandList.ResourceBarrierTransition(CurrentBackBuffer, ResourceStates.Present, ResourceStates.RenderTarget);

            // Clear the back buffer and depth buffer.
            CommandList.ClearRenderTargetView(CurrentBackBufferView, new Color(_mainPassCB.FogColor));
            CommandList.ClearDepthStencilView(DepthStencilView, ClearFlags.FlagsDepth | ClearFlags.FlagsStencil, 1.0f, 0);

            // Specify the buffers we are going to render to.
            CommandList.SetRenderTargets(CurrentBackBufferView, DepthStencilView);

            CommandList.SetDescriptorHeaps(_descriptorHeaps.Length, _descriptorHeaps);

            CommandList.SetGraphicsRootSignature(_rootSignature);

            var passCBByteSize = D3DUtil.CalcConstantBufferByteSize <PassConstants>();

            // Draw opaque items--floors, walls, skull.
            Resource passCB = CurrFrameResource.PassCB.Resource;

            CommandList.SetGraphicsRootConstantBufferView(2, passCB.GPUVirtualAddress);

            DrawRenderItems(CommandList, _ritemLayers[RenderLayer.Opaque]);

            // Indicate a state transition on the resource usage.
            CommandList.ResourceBarrierTransition(CurrentBackBuffer, ResourceStates.RenderTarget, ResourceStates.Present);

            // Done recording commands.
            CommandList.Close();

            // Add the command list to the queue for execution.
            CommandQueue.ExecuteCommandList(CommandList);

            // Present the buffer to the screen. Presenting will automatically swap the back and front buffers.
            SwapChain.Present(0, PresentFlags.None);

            // Advance the fence value to mark commands up to this fence point.
            CurrFrameResource.Fence = ++CurrentFence;

            // Add an instruction to the command queue to set a new fence point.
            // Because we are on the GPU timeline, the new fence point won't be
            // set until the GPU finishes processing all the commands prior to this Signal().
            CommandQueue.Signal(Fence, CurrentFence);
        }
Esempio n. 4
0
        private void BuildConstantBufferViews()
        {
            int objCBByteSize = D3DUtil.CalcConstantBufferByteSize <ObjectConstants>();

            int objCount = _allRitems.Count;

            // Need a CBV descriptor for each object for each frame resource.
            for (int frameIndex = 0; frameIndex < NumFrameResources; frameIndex++)
            {
                Resource objectCB = _frameResources[frameIndex].ObjectCB.Resource;
                for (int i = 0; i < objCount; i++)
                {
                    long cbAddress = objectCB.GPUVirtualAddress;

                    // Offset to the ith object constant buffer in the buffer.
                    cbAddress += i * objCBByteSize;

                    // Offset to the object cbv in the descriptor heap.
                    int heapIndex = frameIndex * objCount + i;
                    CpuDescriptorHandle handle = _cbvHeap.CPUDescriptorHandleForHeapStart;
                    handle += heapIndex * CbvSrvUavDescriptorSize;

                    var cbvDesc = new ConstantBufferViewDescription
                    {
                        BufferLocation = cbAddress,
                        SizeInBytes    = objCBByteSize
                    };

                    Device.CreateConstantBufferView(cbvDesc, handle);
                }
            }

            int passCBByteSize = D3DUtil.CalcConstantBufferByteSize <PassConstants>();

            // Last three descriptors are the pass CBVs for each frame resource.
            for (int frameIndex = 0; frameIndex < NumFrameResources; frameIndex++)
            {
                Resource passCB    = _frameResources[frameIndex].PassCB.Resource;
                long     cbAddress = passCB.GPUVirtualAddress;

                // Offset to the pass cbv in the descriptor heap.
                int heapIndex = _passCbvOffset + frameIndex;
                CpuDescriptorHandle handle = _cbvHeap.CPUDescriptorHandleForHeapStart;
                handle += heapIndex * CbvSrvUavDescriptorSize;

                var cbvDesc = new ConstantBufferViewDescription
                {
                    BufferLocation = cbAddress,
                    SizeInBytes    = passCBByteSize
                };

                Device.CreateConstantBufferView(cbvDesc, handle);
            }
        }
Esempio n. 5
0
        private void BuildConstantBuffers()
        {
            int sizeInBytes = D3DUtil.CalcConstantBufferByteSize <ObjectConstants>();

            _objectCB = new UploadBuffer <ObjectConstants>(Device, 1, true);

            var cbvDesc = new ConstantBufferViewDescription
            {
                BufferLocation = _objectCB.Resource.GPUVirtualAddress,
                SizeInBytes    = sizeInBytes
            };
            CpuDescriptorHandle cbvHeapHandle = _cbvHeap.CPUDescriptorHandleForHeapStart;

            Device.CreateConstantBufferView(cbvDesc, cbvHeapHandle);
        }
Esempio n. 6
0
        private void DrawRenderItems(GraphicsCommandList cmdList, List <RenderItem> ritems)
        {
            int      objCBByteSize = D3DUtil.CalcConstantBufferByteSize <ObjectConstants>();
            Resource objectCB      = CurrFrameResource.ObjectCB.Resource;

            foreach (RenderItem ri in ritems)
            {
                cmdList.SetVertexBuffer(0, ri.Geo.VertexBufferView);
                cmdList.SetIndexBuffer(ri.Geo.IndexBufferView);
                cmdList.PrimitiveTopology = ri.PrimitiveType;

                long objCBAddress = objectCB.GPUVirtualAddress + ri.ObjCBIndex * objCBByteSize;
                cmdList.SetGraphicsRootConstantBufferView(0, objCBAddress);

                cmdList.DrawIndexedInstanced(ri.IndexCount, 1, ri.StartIndexLocation, ri.BaseVertexLocation, 0);
            }
        }
        private void DrawSceneToCubeMap()
        {
            CommandList.SetViewport(_dynamicCubeMap.Viewport);
            CommandList.SetScissorRectangles(_dynamicCubeMap.ScissorRectangle);

            // Change to RENDER_TARGET.
            CommandList.ResourceBarrierTransition(_dynamicCubeMap.Resource, ResourceStates.GenericRead, ResourceStates.RenderTarget);

            int passCBByteSize = D3DUtil.CalcConstantBufferByteSize <PassConstants>();

            // For each cube map face.
            for (int i = 0; i < 6; i++)
            {
                // Clear the back buffer and depth buffer.
                CommandList.ClearRenderTargetView(_dynamicCubeMap.Rtvs[i], Color.LightSteelBlue);
                CommandList.ClearDepthStencilView(_cubeDSV, ClearFlags.FlagsDepth | ClearFlags.FlagsStencil, 1.0f, 0);

                // Specify the buffers we are going to render to.
                CommandList.SetRenderTargets(_dynamicCubeMap.Rtvs[i], _cubeDSV);

                // Bind the pass constant buffer for this cube map face so we use
                // the right view/proj matrix for this cube face.
                Resource passCB        = CurrFrameResource.PassCB.Resource;
                long     passCBAddress = passCB.GPUVirtualAddress + (1 + i) * passCBByteSize;
                CommandList.SetGraphicsRootConstantBufferView(1, passCBAddress);

                CommandList.PipelineState = _psos["opaque"];
                DrawRenderItems(CommandList, _ritemLayers[RenderLayer.Opaque]);

                CommandList.PipelineState = _psos["sky"];
                DrawRenderItems(CommandList, _ritemLayers[RenderLayer.Sky]);
            }

            // Change back to GENERIC_READ so we can read the texture in a shader.
            CommandList.ResourceBarrierTransition(_dynamicCubeMap.Resource, ResourceStates.RenderTarget, ResourceStates.GenericRead);
        }
        public UploadBuffer(Device device, int elementCount, bool isConstantBuffer)
        {
            // Constant buffer elements need to be multiples of 256 bytes.
            // This is because the hardware can only view constant data
            // at m*256 byte offsets and of n*256 byte lengths.
            // typedef struct D3D12_CONSTANT_BUFFER_VIEW_DESC {
            // UINT64 OffsetInBytes; // multiple of 256
            // UINT   SizeInBytes;   // multiple of 256
            // } D3D12_CONSTANT_BUFFER_VIEW_DESC;
            _elementByteSize = isConstantBuffer
                ? D3DUtil.CalcConstantBufferByteSize <T>()
                : Marshal.SizeOf(typeof(T));

            Resource = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(_elementByteSize * elementCount),
                ResourceStates.GenericRead);

            _resourcePointer = Resource.Map(0);

            // We do not need to unmap until we are done with the resource. However, we must not write to
            // the resource while it is in use by the GPU (so we must use synchronization techniques).
        }