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);
        }
Esempio n. 2
0
        internal IntPtr AllocateUploadBuffer(int size, out SharpDX.Direct3D12.Resource resource, out int offset, int alignment = 0)
        {
            // TODO D3D12 thread safety, should we simply use locks?

            // Align
            if (alignment > 0)
            {
                nativeUploadBufferOffset = (nativeUploadBufferOffset + alignment - 1) / alignment * alignment;
            }

            if (nativeUploadBuffer == null || nativeUploadBufferOffset + size > nativeUploadBuffer.Description.Width)
            {
                if (nativeUploadBuffer != null)
                {
                    nativeUploadBuffer.Unmap(0);
                    TemporaryResources.Enqueue(new KeyValuePair <long, object>(NextFenceValue, nativeUploadBuffer));
                }

                // Allocate new buffer
                // TODO D3D12 recycle old ones (using fences to know when GPU is done with them)
                // TODO D3D12 ResourceStates.CopySource not working?
                var bufferSize = Math.Max(4 * 1024 * 1024, size);
                nativeUploadBuffer       = NativeDevice.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(bufferSize), ResourceStates.GenericRead);
                nativeUploadBufferStart  = nativeUploadBuffer.Map(0, new SharpDX.Direct3D12.Range());
                nativeUploadBufferOffset = 0;
            }

            // Bump allocate
            resource = nativeUploadBuffer;
            offset   = nativeUploadBufferOffset;
            nativeUploadBufferOffset += size;
            return(nativeUploadBufferStart + offset);
        }
        public static MeshGeometry New <TIndex>(
            Device device,
            GraphicsCommandList commandList,
            IEnumerable <TIndex> indices,
            string name = "Default")
            where TIndex : struct
        {
            TIndex[] indexArray = indices.ToArray();

            int      indexBufferByteSize = Utilities.SizeOf(indexArray);
            Resource indexBuffer         = D3DUtil.CreateDefaultBuffer(
                device,
                commandList,
                indexArray,
                indexBufferByteSize,
                out Resource indexBufferUploader);

            return(new MeshGeometry
            {
                Name = name,
                IndexCount = indexArray.Length,
                IndexFormat = GetIndexFormat <TIndex>(),
                IndexBufferByteSize = indexBufferByteSize,
                IndexBufferGPU = indexBuffer,
                IndexBufferCPU = indexArray,
                _toDispose = { indexBuffer, indexBufferUploader }
            });
        }
Esempio n. 4
0
        private void BuildResources()
        {
            // Note, compressed formats cannot be used for UAV.  We get error like:
            // ERROR: ID3D11Device::CreateTexture2D: The format (0x4d, BC3_UNORM)
            // cannot be bound as an UnorderedAccessView, or cast to a format that
            // could be bound as an UnorderedAccessView.  Therefore this format
            // does not support D3D11_BIND_UNORDERED_ACCESS.

            var texDesc = new ResourceDescription
            {
                Dimension         = ResourceDimension.Texture2D,
                Alignment         = 0,
                Width             = _width,
                Height            = _height,
                DepthOrArraySize  = 1,
                MipLevels         = 1,
                Format            = _format,
                SampleDescription = new SampleDescription(1, 0),
                Layout            = TextureLayout.Unknown,
                Flags             = ResourceFlags.AllowUnorderedAccess
            };

            _blurMap0 = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.GenericRead);

            _blurMap1 = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.UnorderedAccess);
        }
Esempio n. 5
0
        public void BuildDescriptors(
            Resource depthStencilBuffer,
            CpuDescriptorHandle cpuSrv,
            GpuDescriptorHandle gpuSrv,
            CpuDescriptorHandle cpuRtv,
            int cbvSrvUavDescriptorSize,
            int rtvDescriptorSize)
        {
            // Save references to the descriptors. The Ssao reserves heap space
            // for 5 contiguous Srvs.

            _ambientMap0CpuSrv     = cpuSrv;
            _ambientMap1CpuSrv     = cpuSrv + cbvSrvUavDescriptorSize;
            _normalMapCpuSrv       = cpuSrv + 2 * cbvSrvUavDescriptorSize;
            _depthMapCpuSrv        = cpuSrv + 3 * cbvSrvUavDescriptorSize;
            _randomVectorMapCpuSrv = cpuSrv + 4 * cbvSrvUavDescriptorSize;

            _ambientMap0GpuSrv = gpuSrv;
            _ambientMap1GpuSrv = gpuSrv + cbvSrvUavDescriptorSize;
            _normalMapGpuSrv   = gpuSrv + 2 * cbvSrvUavDescriptorSize;
            // We skip a depth map gpu srv.
            _randomVectorMapGpuSrv = gpuSrv + 4 * cbvSrvUavDescriptorSize;

            _normalMapCpuRtv   = cpuRtv;
            _ambientMap0CpuRtv = cpuRtv + rtvDescriptorSize;
            _ambientMap1CpuRtv = cpuRtv + 2 * rtvDescriptorSize;

            // Create the descriptors
            RebuildDescriptors(depthStencilBuffer);
        }
        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);
            }
        }
        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);
        }
        private void BuildDescriptorHeaps()
        {
            //
            // Create the SRV heap.
            //
            var srvHeapDesc = new DescriptorHeapDescription
            {
                DescriptorCount = 4,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
                Flags           = DescriptorHeapFlags.ShaderVisible
            };

            _srvDescriptorHeap = Device.CreateDescriptorHeap(srvHeapDesc);
            _descriptorHeaps   = new[] { _srvDescriptorHeap };

            //
            // Fill out the heap with actual descriptors.
            //
            CpuDescriptorHandle hDescriptor = _srvDescriptorHeap.CPUDescriptorHandleForHeapStart;

            Resource[] tex2DList =
            {
                _textures["grassTex"].Resource,
                _textures["waterTex"].Resource,
                _textures["fenceTex"].Resource
            };
            Resource treeArrayTex = _textures["treeArrayTex"].Resource;

            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DUtil.DefaultShader4ComponentMapping,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D = new ShaderResourceViewDescription.Texture2DResource
                {
                    MostDetailedMip = 0,
                    MipLevels       = -1,
                }
            };

            foreach (Resource tex2D in tex2DList)
            {
                srvDesc.Format = tex2D.Description.Format;
                Device.CreateShaderResourceView(tex2D, srvDesc, hDescriptor);

                // Next descriptor.
                hDescriptor += CbvSrvUavDescriptorSize;
            }

            srvDesc.Format = treeArrayTex.Description.Format;
            srvDesc.Texture2DArray.MostDetailedMip = 0;
            srvDesc.Texture2DArray.MipLevels       = -1;
            srvDesc.Texture2DArray.FirstArraySlice = 0;
            srvDesc.Texture2DArray.ArraySize       = treeArrayTex.Description.DepthOrArraySize;
            Device.CreateShaderResourceView(treeArrayTex, srvDesc, hDescriptor);
        }
Esempio n. 9
0
        private void BuildResources()
        {
            var texDesc = new ResourceDescription
            {
                Dimension         = ResourceDimension.Texture2D,
                Alignment         = 0,
                Width             = _renderTargetWidth,
                Height            = _renderTargetHeight,
                DepthOrArraySize  = 1,
                MipLevels         = 1,
                Format            = NormalMapFormat,
                SampleDescription = new SampleDescription(1, 0),
                Layout            = TextureLayout.Unknown,
                Flags             = ResourceFlags.AllowRenderTarget
            };

            var optClear = new ClearValue
            {
                Format = NormalMapFormat,
                Color  = Vector4.UnitZ
            };

            _normalMap = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.GenericRead,
                optClear);

            // Ambient occlusion maps are at half resolution.
            texDesc.Width  = SsaoMapWidth;
            texDesc.Height = SsaoMapHeight;
            texDesc.Format = AmbientMapFormat;

            optClear = new ClearValue
            {
                Format = AmbientMapFormat,
                Color  = Vector4.One
            };

            _ambientMap0 = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.GenericRead,
                optClear);

            _ambientMap1 = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.GenericRead,
                optClear);
        }
Esempio n. 10
0
        public void Update(GameTimer gt, GraphicsCommandList cmdList, RootSignature rootSig, PipelineState pso)
        {
            // Accumulate time.
            _t += gt.DeltaTime;

            cmdList.PipelineState = pso;
            cmdList.SetComputeRootSignature(rootSig);

            // Only update the simulation at the specified time step.
            if (_t >= _timeStep)
            {
                // Set the update constants.
                Utilities.Pin(_k, ptr => cmdList.SetComputeRoot32BitConstants(0, 3, ptr, 0));

                cmdList.SetComputeRootDescriptorTable(1, _prevSolUav);
                cmdList.SetComputeRootDescriptorTable(2, _currSolUav);
                cmdList.SetComputeRootDescriptorTable(3, _nextSolUav);

                // How many groups do we need to dispatch to cover the wave grid.
                // Note that RowCount and ColumnCount should be divisible by 16
                // so there is no remainder.
                int numGroupsX = ColumnCount / 16;
                int numGroupsY = RowCount / 16;
                cmdList.Dispatch(numGroupsX, numGroupsY, 1);

                //
                // Ping-pong buffers in preparation for the next update.
                // The previous solution is no longer needed and becomes the target of the next solution in the next update.
                // The current solution becomes the previous solution.
                // The next solution becomes the current solution.
                //

                Resource resTemp = _prevSol;
                _prevSol = _currSol;
                _currSol = _nextSol;
                _nextSol = resTemp;

                GpuDescriptorHandle srvTemp = _prevSolSrv;
                _prevSolSrv = _currSolSrv;
                _currSolSrv = _nextSolSrv;
                _nextSolSrv = srvTemp;

                GpuDescriptorHandle uavTemp = _prevSolUav;
                _prevSolUav = _currSolUav;
                _currSolUav = _nextSolUav;
                _nextSolUav = uavTemp;

                // Reset time.
                _t = 0.0f;

                // The current solution needs to be able to be read by the vertex shader, so change its state to GENERIC_READ.
                cmdList.ResourceBarrierTransition(_currSol, ResourceStates.UnorderedAccess, ResourceStates.GenericRead);
            }
        }
Esempio n. 11
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);
            }
        }
        public void EndFrame()
        {
            commandQueue.ExecuteCommandList(commandList);

            swapChain.Present(1, PresentFlags.None);
            indexLastSwapBuf = (indexLastSwapBuf + 1) % SwapBufferCount;
            Utilities.Dispose(ref renderTarget);
            renderTarget = swapChain.GetBackBuffer <Resource>(indexLastSwapBuf);
            device.CreateRenderTargetView(renderTarget, null, descriptorHeap.CPUDescriptorHandleForHeapStart);

            WaitForPrevFrame();
        }
Esempio n. 13
0
        /// <summary>
        /// Initializes from a native SharpDX.Texture
        /// </summary>
        /// <param name="texture">The texture.</param>
        internal Texture InitializeFromImpl(SharpDX.Direct3D12.Resource texture, bool isSrgb)
        {
            NativeDeviceChild = texture;
            var newTextureDescription = ConvertFromNativeDescription(texture.Description);

            // We might have created the swapchain as a non-srgb format (esp on Win10&RT) but we want it to behave like it is (esp. for the view and render target)
            if (isSrgb)
            {
                newTextureDescription.Format = newTextureDescription.Format.ToSRgb();
            }

            return(InitializeFrom(newTextureDescription));
        }
Esempio n. 14
0
        private void PlatformCreateShaders()
        {
            var inputElementDescs = new[]
            {
                new InputElement("POSITION", 0, Format.R32G32_Float, 0, 0),
                new InputElement("COLOR", 0, Format.B8G8R8A8_UNorm, 8, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 8 + 4, 0)
            };

            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(inputElementDescs),
                RootSignature      = graphicsHost.RootSignature,
                VertexShader       = DXHelper.CompileShader(vertexShaderSource, "main", "vs_5_0"),
                PixelShader        = DXHelper.CompileShader(pixelShaderSource, "main", "ps_5_0"),
                RasterizerState    = RasterizerStateDescription.Default(),
                BlendState         = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState  = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = false, IsStencilEnabled = false
                },
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };

            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            pipelineState = graphicsHost.Device.CreateGraphicsPipelineState(psoDesc);

            // TODO: Move buffer
            var constantBufferDesc = ResourceDescription.Buffer(1024 * 64);

            constantBuffer      = graphicsHost.Device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, constantBufferDesc, ResourceStates.GenericRead);
            constantBuffer.Name = "[SpriteRenderer] Constant Buffer";

            var cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (SharpDX.Utilities.SizeOf <ConstantBuffer>() + 255) & ~255,
            };

            graphicsHost.Device.CreateConstantBufferView(cbvDesc, graphicsHost.CBVHeap.CPUDescriptorHandleForHeapStart);

            mappedConstantBuffer = constantBuffer.Map(0);
            SharpDX.Utilities.Write(mappedConstantBuffer, ref constantBufferData);
        }
Esempio n. 15
0
        static void FillInitData(Resource texture, int width, int height, int depth, int mipCount, int arraySize, Format format, int maxsize, int bitSize, byte[] bitData, int offset)
        {
            int NumBytes = 0;
            int RowBytes = 0;
            int NumRows  = 0;

            byte[] pSrcBits = bitData;
            byte[] pEndBits = bitData;// + bitSize;

            int index = 0;
            int k     = offset;


            for (int j = 0; j < arraySize; j++)
            {
                int w = width;
                int h = height;
                int d = depth;
                for (int i = 0; i < mipCount; i++)
                {
                    GetSurfaceInfo(w, h, format, out NumBytes, out RowBytes, out NumRows);

                    GCHandle handle = GCHandle.Alloc(bitData, GCHandleType.Pinned);
                    IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(bitData, k);
                    texture.WriteToSubresource(index, null, ptr, RowBytes, NumBytes);
                    handle.Free();

                    index++;

                    k += NumBytes * d;

                    w = w >> 1;
                    h = h >> 1;
                    d = d >> 1;
                    if (w == 0)
                    {
                        w = 1;
                    }
                    if (h == 0)
                    {
                        h = 1;
                    }
                    if (d == 0)
                    {
                        d = 1;
                    }
                }
            }
        }
Esempio n. 16
0
        private void DrawRenderItems(GraphicsCommandList cmdList, List <RenderItem> ritems)
        {
            foreach (RenderItem ri in ritems)
            {
                cmdList.SetVertexBuffer(0, ri.Geo.VertexBufferView);
                cmdList.SetIndexBuffer(ri.Geo.IndexBufferView);
                cmdList.PrimitiveTopology = ri.PrimitiveType;

                // Set the instance buffer to use for this render-item. For structured buffers, we can bypass
                // the heap and set as a root descriptor.
                Resource instanceBuffer = CurrFrameResource.InstanceBuffer.Resource;
                cmdList.SetGraphicsRootShaderResourceView(0, instanceBuffer.GPUVirtualAddress);

                cmdList.DrawIndexedInstanced(ri.IndexCount, ri.InstanceCount, ri.StartIndexLocation, ri.BaseVertexLocation, 0);
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Render scene
        /// </summary>
        public void Render()
        {
            // record all the commands we need to render the scene into the command list
            PopulateCommandLists();

            // execute the command list
            commandQueue.ExecuteCommandList(commandList);

            // swap the back and front buffers
            swapChain.Present(1, 0);

            // wait and reset EVERYTHING
            WaitForPrevFrame();

            RemoveAndDispose(ref renderTarget);
            if (width != newWidth || height != newHeight)
            {
                width  = newWidth;
                height = newHeight;
                swapChain.ResizeBuffers(SwapBufferCount, width, height, Format.Unknown, SwapChainFlags.None);
#if USE_DEPTH
                RemoveAndDispose(ref depthBuffer);
                depthBuffer = Collect(device.CreateCommittedResource(
                                          new HeapProperties(HeapType.Default),
                                          HeapFlags.None,
                                          new ResourceDescription(ResourceDimension.Texture2D, 0, width, height, 1, 1, Format.D32_Float, 1, 0, TextureLayout.Unknown, ResourceFlags.AllowDepthStencil),
                                          ResourceStates.Common,
                                          new ClearValue
                {
                    Format       = Format.D32_Float,
                    DepthStencil = new DepthStencilValue
                    {
                        Depth   = 1,
                        Stencil = 0,
                    }
                }));
                device.CreateDepthStencilView(depthBuffer, null, descriptorHeapDS.CPUDescriptorHandleForHeapStart);
#endif
                // Create the viewport
                viewPort = new ViewportF(0, 0, width, height);

                // Create the scissor
                scissorRectangle = new Rectangle(0, 0, width, height);
            }
            renderTarget = Collect(swapChain.GetBackBuffer <Resource>(swapChain.CurrentBackBufferIndex));
            device.CreateRenderTargetView(renderTarget, null, descriptorHeapRT.CPUDescriptorHandleForHeapStart);
        }
Esempio n. 18
0
        private void BuildRandomVectorTexture(GraphicsCommandList cmdList)
        {
            var texDesc = new ResourceDescription
            {
                Dimension         = ResourceDimension.Texture2D,
                Width             = 256,
                Height            = 256,
                DepthOrArraySize  = 1,
                MipLevels         = 1,
                Format            = Format.R8G8B8A8_UNorm,
                SampleDescription = new SampleDescription(1, 0),
                Layout            = TextureLayout.Unknown,
                Flags             = ResourceFlags.None
            };

            _randomVectorMap = _device.CreateCommittedResource(
                new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0),
                HeapFlags.None,
                texDesc,
                ResourceStates.GenericRead);

            //
            // In order to copy CPU memory data into our default buffer, we need to create
            // an intermediate upload heap.
            //

            var initData = new Color[256 * 256];

            for (int i = 0; i < 256; i++)
            {
                for (int j = 0; j < 256; j++)
                {
                    // Random vector in [0,1]. We will decompress in shader to [-1,1].
                    initData[i * 256 + j] = new Color(
                        MathHelper.Randf(),
                        MathHelper.Randf(),
                        MathHelper.Randf(),
                        0.0f);
                }
            }

            int rowPitch   = Utilities.SizeOf <Color>() * 256;
            int slicePitch = rowPitch * 256;

            Utilities.Pin(initData, ptr => _randomVectorMap.WriteToSubresource(0, null, ptr, rowPitch, slicePitch));
        }
 public static DescriptorHeap CreateRenderTargetViewHeap(Config config, SwapChain3 swapchain, out Resource[] renderTargets)
 {
     var Heap = Engine.Instance.Core.Device.CreateDescriptorHeap(new DescriptorHeapDescription()
     {
         DescriptorCount = config.FrameCount,
         Flags = DescriptorHeapFlags.None,
         Type = DescriptorHeapType.RenderTargetView
     });
     renderTargets = new Resource[config.FrameCount];
     int Step = Engine.Instance.Core.Device.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView);
     for (int n = 0; n < config.FrameCount; n++)
     {
         renderTargets[n] = swapchain.GetBackBuffer<Resource>(n);
         Engine.Instance.Core.Device.CreateRenderTargetView(renderTargets[n], null, Heap.CPUDescriptorHandleForHeapStart + n* Step);
     }
     return Heap;
 }
Esempio n. 20
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 BuildBuffers()
        {
            // Generate some data.
            var dataA = new Data[NumDataElements];
            var dataB = new Data[NumDataElements];

            for (int i = 0; i < NumDataElements; i++)
            {
                dataA[i].V1 = new Vector3(i, i, i);
                dataA[i].V2 = new Vector2(i, 0);

                dataB[i].V1 = new Vector3(-i, i, 0.0f);
                dataB[i].V2 = new Vector2(0, -i);
            }

            long byteSize = dataA.Length * Utilities.SizeOf <Data>();

            // Create some buffers to be used as SRVs.
            _inputBufferA = D3DUtil.CreateDefaultBuffer(
                Device,
                CommandList,
                dataA,
                byteSize,
                out _inputUploadBufferA);

            _inputBufferB = D3DUtil.CreateDefaultBuffer(
                Device,
                CommandList,
                dataB,
                byteSize,
                out _inputUploadBufferB);

            // Create the buffer that will be a UAV.
            _outputBuffer = Device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                ResourceDescription.Buffer(byteSize, ResourceFlags.AllowUnorderedAccess),
                ResourceStates.UnorderedAccess);

            _readBackBuffer = Device.CreateCommittedResource(
                new HeapProperties(HeapType.Readback),
                HeapFlags.None,
                ResourceDescription.Buffer(byteSize),
                ResourceStates.CopyDestination);
        }
Esempio n. 22
0
        public void RebuildDescriptors(Resource depthStencilBuffer)
        {
            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DUtil.DefaultShader4ComponentMapping,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Format    = NormalMapFormat,
                Texture2D = new ShaderResourceViewDescription.Texture2DResource
                {
                    MostDetailedMip = 0,
                    MipLevels       = 1
                }
            };

            _device.CreateShaderResourceView(_normalMap, srvDesc, _normalMapCpuSrv);

            srvDesc.Format = Format.R24_UNorm_X8_Typeless;
            _device.CreateShaderResourceView(depthStencilBuffer, srvDesc, _depthMapCpuSrv);

            srvDesc.Format = Format.R8G8B8A8_UNorm;
            _device.CreateShaderResourceView(_randomVectorMap, srvDesc, _randomVectorMapCpuSrv);

            srvDesc.Format = AmbientMapFormat;
            _device.CreateShaderResourceView(_ambientMap0, srvDesc, _ambientMap0CpuSrv);
            _device.CreateShaderResourceView(_ambientMap1, srvDesc, _ambientMap1CpuSrv);

            var rtvDesc = new RenderTargetViewDescription
            {
                Dimension = RenderTargetViewDimension.Texture2D,
                Format    = NormalMapFormat,
                Texture2D = new RenderTargetViewDescription.Texture2DResource
                {
                    MipSlice   = 0,
                    PlaneSlice = 0
                }
            };

            _device.CreateRenderTargetView(_normalMap, rtvDesc, _normalMapCpuRtv);

            rtvDesc.Format = AmbientMapFormat;
            _device.CreateRenderTargetView(_ambientMap0, rtvDesc, _ambientMap0CpuRtv);
            _device.CreateRenderTargetView(_ambientMap1, rtvDesc, _ambientMap1CpuRtv);
        }
        private void BuildCubeDepthStencil()
        {
            _cubeDSV = DsvHeap.CPUDescriptorHandleForHeapStart + DsvDescriptorSize;

            // Create the depth/stencil buffer and view.
            var depthStencilDesc = new ResourceDescription
            {
                Dimension         = ResourceDimension.Texture2D,
                Alignment         = 0,
                Width             = CubeMapSize,
                Height            = CubeMapSize,
                DepthOrArraySize  = 1,
                MipLevels         = 1,
                Format            = DepthStencilFormat,
                SampleDescription = new SampleDescription(1, 0),
                Layout            = TextureLayout.Unknown,
                Flags             = ResourceFlags.AllowDepthStencil
            };

            var optClear = new ClearValue
            {
                Format       = DepthStencilFormat,
                DepthStencil = new DepthStencilValue
                {
                    Depth   = 1.0f,
                    Stencil = 0
                }
            };

            _cubeDepthStencilBuffer = Device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                depthStencilDesc,
                ResourceStates.Common,
                optClear);

            // Create descriptor to mip level 0 of entire resource using the format of the resource.
            Device.CreateDepthStencilView(_cubeDepthStencilBuffer, null, _cubeDSV);

            // Transition the resource from its initial state to be used as a depth buffer.
            CommandList.ResourceBarrierTransition(_cubeDepthStencilBuffer, ResourceStates.Common, ResourceStates.DepthWrite);
        }
        public static Resource CreateDefaultBuffer <T>(
            Device device,
            GraphicsCommandList cmdList,
            T[] initData,
            long byteSize,
            out Resource uploadBuffer) where T : struct
        {
            // Create the actual default buffer resource.
            Resource defaultBuffer = device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                ResourceDescription.Buffer(byteSize),
                ResourceStates.Common);

            // In order to copy CPU memory data into our default buffer, we need to create
            // an intermediate upload heap.
            uploadBuffer = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(byteSize),
                ResourceStates.GenericRead);

            // Copy the data to the upload buffer.
            IntPtr ptr = uploadBuffer.Map(0);

            Utilities.Write(ptr, initData, 0, initData.Length);
            uploadBuffer.Unmap(0);

            // Schedule to copy the data to the default buffer resource.
            cmdList.ResourceBarrierTransition(defaultBuffer, ResourceStates.Common, ResourceStates.CopyDestination);
            cmdList.CopyResource(defaultBuffer, uploadBuffer);
            cmdList.ResourceBarrierTransition(defaultBuffer, ResourceStates.CopyDestination, ResourceStates.GenericRead);

            // Note: uploadBuffer has to be kept alive after the above function calls because
            // the command list has not been executed yet that performs the actual copy.
            // The caller can Release the uploadBuffer after it knows the copy has been executed.

            return(defaultBuffer);
        }
Esempio n. 25
0
        private void BuildDescriptorHeaps()
        {
            //
            // Create the SRV heap.
            //
            var srvHeapDesc = new DescriptorHeapDescription
            {
                DescriptorCount = 1,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
                Flags           = DescriptorHeapFlags.ShaderVisible
            };

            _srvDescriptorHeap = Device.CreateDescriptorHeap(srvHeapDesc);
            _descriptorHeaps   = new[] { _srvDescriptorHeap };

            //
            // Fill out the heap with actual descriptors.
            //
            var hDescriptor = _srvDescriptorHeap.CPUDescriptorHandleForHeapStart;

            Resource woodCrateTexture = _textures["woodCrateTex"].Resource;

            var srvDesc = new ShaderResourceViewDescription
            {
                // TODO: API suggestion: Expose DefaultShader4ComponentMapping through ShaderComponentMapping enumeration.
                // TODO: Turn from int to ShaderComponentMapping enum.
                Shader4ComponentMapping = D3DUtil.DefaultShader4ComponentMapping,
                Format    = woodCrateTexture.Description.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D = new ShaderResourceViewDescription.Texture2DResource
                {
                    MostDetailedMip     = 0,
                    MipLevels           = woodCrateTexture.Description.MipLevels,
                    ResourceMinLODClamp = 0.0f
                }
            };

            Device.CreateShaderResourceView(woodCrateTexture, srvDesc, hDescriptor);
        }
        private void BuildDescriptorHeaps()
        {
            //
            // Create the SRV heap.
            //
            var srvHeapDesc = new DescriptorHeapDescription
            {
                DescriptorCount = 1,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
                Flags           = DescriptorHeapFlags.ShaderVisible
            };

            _srvDescriptorHeap = Device.CreateDescriptorHeap(srvHeapDesc);
            _descriptorHeaps   = new[] { _srvDescriptorHeap };

            //
            // Fill out the heap with actual descriptors.
            //
            CpuDescriptorHandle hDescriptor = _srvDescriptorHeap.CPUDescriptorHandleForHeapStart;

            Resource defaultDiffuseTex = _textures["defaultDiffuseTex"].Resource;

            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DUtil.DefaultShader4ComponentMapping,
                Format    = defaultDiffuseTex.Description.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D = new ShaderResourceViewDescription.Texture2DResource
                {
                    MostDetailedMip     = 0,
                    MipLevels           = defaultDiffuseTex.Description.MipLevels,
                    ResourceMinLODClamp = 0.0f
                }
            };

            Device.CreateShaderResourceView(defaultDiffuseTex, srvDesc, hDescriptor);
        }
        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);
        }
Esempio n. 28
0
        protected virtual void OnResize()
        {
            Debug.Assert(Device != null);
            Debug.Assert(SwapChain != null);
            Debug.Assert(DirectCmdListAlloc != null);

            // Flush before changing any resources.
            FlushCommandQueue();

            CommandList.Reset(DirectCmdListAlloc, null);

            // Release the previous resources we will be recreating.
            foreach (Resource buffer in _swapChainBuffers)
            {
                buffer?.Dispose();
            }
            DepthStencilBuffer?.Dispose();

            // Resize the swap chain.
            SwapChain.ResizeBuffers(
                SwapChainBufferCount,
                ClientWidth, ClientHeight,
                BackBufferFormat,
                SwapChainFlags.AllowModeSwitch);

            CpuDescriptorHandle rtvHeapHandle = RtvHeap.CPUDescriptorHandleForHeapStart;

            for (int i = 0; i < SwapChainBufferCount; i++)
            {
                Resource backBuffer = SwapChain.GetBackBuffer <Resource>(i);
                _swapChainBuffers[i] = backBuffer;
                Device.CreateRenderTargetView(backBuffer, null, rtvHeapHandle);
                rtvHeapHandle += RtvDescriptorSize;
            }

            // Create the depth/stencil buffer and view.
            var depthStencilDesc = new ResourceDescription
            {
                Dimension         = ResourceDimension.Texture2D,
                Alignment         = 0,
                Width             = ClientWidth,
                Height            = ClientHeight,
                DepthOrArraySize  = 1,
                MipLevels         = 1,
                Format            = Format.R24G8_Typeless,
                SampleDescription = new SampleDescription
                {
                    Count   = MsaaCount,
                    Quality = MsaaQuality
                },
                Layout = TextureLayout.Unknown,
                Flags  = ResourceFlags.AllowDepthStencil
            };
            var optClear = new ClearValue
            {
                Format       = DepthStencilFormat,
                DepthStencil = new DepthStencilValue
                {
                    Depth   = 1.0f,
                    Stencil = 0
                }
            };

            DepthStencilBuffer = Device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                depthStencilDesc,
                ResourceStates.Common,
                optClear);

            var depthStencilViewDesc = new DepthStencilViewDescription
            {
                Dimension = DepthStencilViewDimension.Texture2D,
                Format    = DepthStencilFormat
            };
            // Create descriptor to mip level 0 of entire resource using a depth stencil format.
            CpuDescriptorHandle dsvHeapHandle = DsvHeap.CPUDescriptorHandleForHeapStart;

            Device.CreateDepthStencilView(DepthStencilBuffer, depthStencilViewDesc, dsvHeapHandle);

            // Transition the resource from its initial state to be used as a depth buffer.
            CommandList.ResourceBarrierTransition(DepthStencilBuffer, ResourceStates.Common, ResourceStates.DepthWrite);

            // Execute the resize commands.
            CommandList.Close();
            CommandQueue.ExecuteCommandList(CommandList);

            // Wait until resize is complete.
            FlushCommandQueue();

            Viewport         = new ViewportF(0, 0, ClientWidth, ClientHeight, 0.0f, 1.0f);
            ScissorRectangle = new RectangleF(0, 0, ClientWidth, ClientHeight);
        }
        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.SetDescriptorHeaps(_descriptorHeaps.Length, _descriptorHeaps);

            UpdateWavesGPU(gt);

            CommandList.PipelineState = _psos["opaque"];

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

            // Change offscreen texture to be used as a a render target output.
            CommandList.ResourceBarrierTransition(_offscreenRT.Resource, ResourceStates.GenericRead, ResourceStates.RenderTarget);

            // Clear the back buffer and depth buffer.
            CommandList.ClearRenderTargetView(_offscreenRT.Rtv, 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(_offscreenRT.Rtv, DepthStencilView);

            CommandList.SetGraphicsRootSignature(_rootSignature);

            Resource passCB = CurrFrameResource.PassCB.Resource;

            CommandList.SetGraphicsRootConstantBufferView(2, passCB.GPUVirtualAddress);

            CommandList.SetGraphicsRootDescriptorTable(4, _waves.DisplacementMap);

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

            CommandList.PipelineState = _psos["alphaTested"];
            DrawRenderItems(CommandList, _ritemLayers[RenderLayer.AlphaTested]);

            CommandList.PipelineState = _psos["transparent"];
            DrawRenderItems(CommandList, _ritemLayers[RenderLayer.Transparent]);

            CommandList.PipelineState = _psos["wavesRender"];
            DrawRenderItems(CommandList, _ritemLayers[RenderLayer.GpuWaves]);

            // Change offscreen texture to be used as an input.
            CommandList.ResourceBarrierTransition(_offscreenRT.Resource, ResourceStates.RenderTarget, ResourceStates.GenericRead);

            _sobelFilter.Execute(CommandList, _postProcessRootSignature, _psos["sobel"], _offscreenRT.Srv);

            //
            // Switching back to back buffer rendering.
            //

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

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

            CommandList.SetGraphicsRootSignature(_postProcessRootSignature);
            CommandList.PipelineState = _psos["composite"];
            CommandList.SetGraphicsRootDescriptorTable(0, _offscreenRT.Srv);
            CommandList.SetGraphicsRootDescriptorTable(1, _sobelFilter.OutputSrv);
            DrawFullscreenQuad(CommandList);

            // 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. 30
0
        /// <summary>
        /// Setup resources for rendering
        /// </summary>
        void LoadAssets()
        {
            // Create the main command list
            commandList = Collect(device.CreateCommandList(CommandListType.Direct, commandListAllocator, pipelineState));

            // Create the descriptor heap for the render target view
            descriptorHeapRT = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription()
            {
                Type            = DescriptorHeapType.RenderTargetView,
                DescriptorCount = 1
            }));
#if USE_DEPTH
            descriptorHeapDS = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription()
            {
                Type            = DescriptorHeapType.DepthStencilView,
                DescriptorCount = 1
            }));
#endif
#if USE_TEXTURE
            descriptorHeapCB = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription()
            {
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
                DescriptorCount = 2,
                Flags           = DescriptorHeapFlags.ShaderVisible,
            }));
            descriptorHeapS = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription()
            {
                Type            = DescriptorHeapType.Sampler,
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
            }));
            descriptorsHeaps[0] = descriptorHeapCB;
            descriptorsHeaps[1] = descriptorHeapS;
#else
            descriptorHeapCB = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription()
            {
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
            }));
            descriptorsHeaps[0] = descriptorHeapCB;
#endif
#if true // root signature in code
            var rsparams = new RootParameter[]
            {
                new RootParameter(ShaderVisibility.Vertex, new RootDescriptor(), RootParameterType.ConstantBufferView),
                new RootParameter(ShaderVisibility.Vertex,
                                  new DescriptorRange
                {
                    RangeType          = DescriptorRangeType.ConstantBufferView,
                    BaseShaderRegister = 1,
                    DescriptorCount    = 1,
                }),
#if USE_TEXTURE
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange
                {
                    RangeType          = DescriptorRangeType.ShaderResourceView,
                    BaseShaderRegister = 0,
                    DescriptorCount    = 1,
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange
                {
                    RangeType          = DescriptorRangeType.Sampler,
                    BaseShaderRegister = 0,
                    DescriptorCount    = 1,
                }),
#endif
            };
            var rs = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rsparams);
            rootSignature = Collect(device.CreateRootSignature(rs.Serialize()));
#else
            var rootSignatureByteCode = Utilities.ReadStream(assembly.GetManifestResourceStream("Shaders.Cube" + shaderNameSuffix + ".rs"));
            using (var bufferRootSignature = DataBuffer.Create(rootSignatureByteCode))
                rootSignature = Collect(device.CreateRootSignature(bufferRootSignature));
#endif
            byte[] vertexShaderByteCode = GetResourceBytes("Cube" + shaderNameSuffix + ".vso");
            byte[] pixelShaderByteCode  = GetResourceBytes("Cube" + shaderNameSuffix + ".pso");

            var layout = new InputLayoutDescription(new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0),
                new InputElement("NORMAL", 0, Format.R32G32B32_Float, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 0),
#if USE_INSTANCES
                new InputElement("OFFSET", 0, Format.R32G32B32_Float, 0, 1, InputClassification.PerInstanceData, 1),
#endif
            });

            #region pipeline state
            var psd = new GraphicsPipelineStateDescription
            {
                InputLayout           = layout,
                VertexShader          = vertexShaderByteCode,
                PixelShader           = pixelShaderByteCode,
                RootSignature         = rootSignature,
                DepthStencilState     = DepthStencilStateDescription.Default(),
                DepthStencilFormat    = Format.Unknown,
                BlendState            = BlendStateDescription.Default(),
                RasterizerState       = RasterizerStateDescription.Default(),
                SampleDescription     = new SampleDescription(1, 0),
                RenderTargetCount     = 1,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                SampleMask            = -1,
                StreamOutput          = new StreamOutputDescription()
            };
            psd.RenderTargetFormats[0] = Format.R8G8B8A8_UNorm;
#if USE_DEPTH
            psd.DepthStencilFormat = Format.D32_Float;
#else
            psd.DepthStencilState.IsDepthEnabled = false;
#endif
            //psd.RasterizerState.CullMode = CullMode.None;
            pipelineState = Collect(device.CreateGraphicsPipelineState(psd));
            #endregion pipeline state

            #region vertices
            var vertices = new[]
            {
                -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                       // Front
                -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,

                -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                        // BACK
                -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                        // BACK
                1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,

                -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                        // Top
                -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                        // Top
                -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,

                -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                       // Bottom
                -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                       // Bottom
                1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,

                -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                       // Left
                -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                       // Left
                -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,

                1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                        // Right
                1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,                        // Right
                1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
            };
            #endregion vertices
            #region vertex buffer
            // Instantiate Vertex buiffer from vertex data
            int sizeOfFloat = sizeof(float);
            int sizeInBytes = vertices.Length * sizeOfFloat;
            vertexBuffer = Collect(device.CreateCommittedResource(
                                       new HeapProperties(HeapType.Upload),
                                       HeapFlags.None,
                                       new ResourceDescription(ResourceDimension.Buffer, 0, sizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None),
                                       ResourceStates.GenericRead));
            vertexBufferView = new[]
            {
                new VertexBufferView
                {
                    BufferLocation = vertexBuffer.GPUVirtualAddress,
                    SizeInBytes    = sizeInBytes,
                    StrideInBytes  = sizeOfFloat * 8,
                }
            };
            var ptr = vertexBuffer.Map(0);
            Utilities.Write(ptr, vertices, 0, vertices.Length);
            vertexBuffer.Unmap(0);
            #endregion vertex buffer
            #region instances
#if USE_INSTANCES
            int instanceSizeInBytes = sizeOfFloat * instances.Length;
            instancesBuffer = Collect(device.CreateCommittedResource(
                                          new HeapProperties(HeapType.Upload),
                                          HeapFlags.None,
                                          new ResourceDescription(ResourceDimension.Buffer, 0, instanceSizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None),
                                          ResourceStates.GenericRead));
            instancesBufferView = new[]
            {
                new VertexBufferView
                {
                    BufferLocation = instancesBuffer.GPUVirtualAddress,
                    SizeInBytes    = instanceSizeInBytes,
                    StrideInBytes  = sizeOfFloat * 3,
                }
            };
            ptr = instancesBuffer.Map(0);
            Utilities.Write(ptr, instances, 0, instances.Length);
            instancesBuffer.Unmap(0);
#endif
            #endregion instances

            #region indices
#if USE_INDICES
            var indexData = new[]
            {
                0, 1, 2, 3, 4,
                5, 6, 7, 8, 9, 10,
                11, 12, 13, 14, 15, 16,
                17, 18, 19, 20, 21, 22,
                23, 24, 25, 26, 27, 28,
                29, 30, 31, 32, 33
            };
            sizeInBytes = indexData.Length * sizeof(int);
            indexBuffer = Collect(device.CreateCommittedResource(
                                      new HeapProperties(HeapType.Upload),
                                      HeapFlags.None,
                                      new ResourceDescription(ResourceDimension.Buffer, 0, sizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None),
                                      ResourceStates.GenericRead));
            ptr = indexBuffer.Map(0);
            Utilities.Write(ptr, indexData, 0, indexData.Length);
            indexBuffer.Unmap(0);
            indexBufferView = new IndexBufferView
            {
                BufferLocation = indexBuffer.GPUVirtualAddress,
                SizeInBytes    = sizeInBytes,
                Format         = Format.R32_UInt
            };
#endif
            #endregion indices

            #region transform
            transWorld = Collect(device.CreateCommittedResource(
                                     new HeapProperties(HeapType.Upload),
                                     HeapFlags.None,
                                     new ResourceDescription(ResourceDimension.Buffer, 0, 16 * sizeOfMatrix, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None),
                                     ResourceStates.GenericRead));
            transWorldPtr = transWorld.Map(0);
            transViewProj = Collect(device.CreateCommittedResource(
                                        new HeapProperties(HeapType.Upload),
                                        HeapFlags.None,
                                        new ResourceDescription(ResourceDimension.Buffer, 0, sizeOfMatrix, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None),
                                        ResourceStates.GenericRead));
            device.CreateConstantBufferView(new ConstantBufferViewDescription
            {
                BufferLocation = transViewProj.GPUVirtualAddress,
                SizeInBytes    = sizeOfMatrix,
            }, descriptorHeapCB.CPUDescriptorHandleForHeapStart);

            var view = Matrix.LookAtLH(new Vector3(5, 5, -5), Vector3.Zero, Vector3.UnitY);
            var proj = Matrix.PerspectiveFovLH(MathUtil.Pi / 4, (float)width / height, 0.1f, 100);
            var vpT  = view * proj;
            vpT.Transpose();
            ptr = transViewProj.Map(0);
            Utilities.Write(ptr, ref vpT);
            transViewProj.Unmap(0);
            #endregion transform

#if USE_TEXTURE
            #region texture
            Resource buf;
            using (var tl = new TextureLoader("GeneticaMortarlessBlocks.jpg"))
            {
                int w = tl.Width, h = tl.Height;
                var descrs = new[]
                {
                    new ResourceDescription(ResourceDimension.Texture2D,
                                            0, w, h, 1, 1,
                                            Format.B8G8R8A8_UNorm, 1, 0,
                                            TextureLayout.Unknown,
                                            ResourceFlags.None),
                };
                texture = Collect(device.CreateCommittedResource(
                                      new HeapProperties(HeapType.Default),
                                      HeapFlags.None,
                                      descrs[0],
                                      ResourceStates.CopyDestination)
                                  );
                var resAllocInfo = device.GetResourceAllocationInfo(1, 1, descrs);
                buf = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    new ResourceDescription(
                        ResourceDimension.Buffer,
                        0,
                        resAllocInfo.SizeInBytes,
                        1, 1, 1,
                        Format.Unknown,
                        1, 0,
                        TextureLayout.RowMajor,
                        ResourceFlags.None),
                    ResourceStates.GenericRead);

                var ptrBuf   = buf.Map(0);
                int rowPitch = tl.CopyImageData(ptrBuf);
                buf.Unmap(0);

                var src = new TextureCopyLocation(buf,
                                                  new PlacedSubResourceFootprint
                {
                    Offset    = 0,
                    Footprint = new SubResourceFootprint
                    {
                        Format   = Format.B8G8R8A8_UNorm_SRgb,
                        Width    = w,
                        Height   = h,
                        Depth    = 1,
                        RowPitch = rowPitch
                    }
                }
                                                  );
                var dst = new TextureCopyLocation(texture, 0);
                // record copy
                commandList.CopyTextureRegion(dst, 0, 0, 0, src, null);

                commandList.ResourceBarrierTransition(texture, ResourceStates.CopyDestination, ResourceStates.GenericRead);
            }
            descrOffsetCB = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            device.CreateShaderResourceView(texture, null, descriptorHeapCB.CPUDescriptorHandleForHeapStart + descrOffsetCB);
            #endregion texture

            #region sampler
            device.CreateSampler(new SamplerStateDescription
            {
                AddressU = TextureAddressMode.Wrap,
                AddressV = TextureAddressMode.Wrap,
                AddressW = TextureAddressMode.Wrap,
                Filter   = Filter.MaximumMinMagMipLinear,
            }, descriptorHeapS.CPUDescriptorHandleForHeapStart);
            #endregion sampler
#endif
            // Get the backbuffer and creates the render target view
            renderTarget = Collect(swapChain.GetBackBuffer <Resource>(0));
            device.CreateRenderTargetView(renderTarget, null, descriptorHeapRT.CPUDescriptorHandleForHeapStart);

#if USE_DEPTH
            depthBuffer = Collect(device.CreateCommittedResource(
                                      new HeapProperties(HeapType.Default),
                                      HeapFlags.None,
                                      new ResourceDescription(ResourceDimension.Texture2D, 0, width, height, 1, 1, Format.D32_Float, 1, 0, TextureLayout.Unknown, ResourceFlags.AllowDepthStencil),
                                      ResourceStates.Present,
                                      new ClearValue
            {
                Format       = Format.D32_Float,
                DepthStencil = new DepthStencilValue
                {
                    Depth   = 1,
                    Stencil = 0,
                }
            }));
            device.CreateDepthStencilView(depthBuffer, null, descriptorHeapDS.CPUDescriptorHandleForHeapStart);
#endif

            // Create the viewport
            viewPort = new ViewportF(0, 0, width, height);

            // Create the scissor
            scissorRectangle = new Rectangle(0, 0, width, height);

            // Create a fence to wait for next frame
            fence        = Collect(device.CreateFence(0, FenceFlags.None));
            currentFence = 1;

            // Close command list
            commandList.Close();
            commandQueue.ExecuteCommandList(commandList);

            // Create an event handle use for VTBL
            CreateWaitEvent();

            // Wait the command list to complete
            WaitForPrevFrame();
#if USE_TEXTURE
            buf.Dispose();
#endif
        }
Esempio n. 31
0
        public void Execute(
            GraphicsCommandList cmdList,
            RootSignature rootSig,
            PipelineState horzBlurPso,
            PipelineState vertBlurPso,
            Resource input,
            int blurCount)
        {
            float[] weights    = CalcGaussWeights(2.5f);
            int     blurRadius = weights.Length / 2;

            cmdList.SetComputeRootSignature(rootSig);

            Utilities.Pin(ref blurRadius, ptr => cmdList.SetComputeRoot32BitConstants(0, 1, ptr, 0));
            Utilities.Pin(weights, ptr => cmdList.SetComputeRoot32BitConstants(0, weights.Length, ptr, 1));

            cmdList.ResourceBarrierTransition(input, ResourceStates.RenderTarget, ResourceStates.CopySource);
            cmdList.ResourceBarrierTransition(_blurMap0, ResourceStates.GenericRead, ResourceStates.CopyDestination);

            // Copy the input (back-buffer in this example) to BlurMap0.
            cmdList.CopyResource(_blurMap0, input);

            cmdList.ResourceBarrierTransition(_blurMap0, ResourceStates.CopyDestination, ResourceStates.GenericRead);

            for (int i = 0; i < blurCount; i++)
            {
                //
                // Horizontal Blur pass.
                //

                cmdList.PipelineState = horzBlurPso;

                cmdList.SetComputeRootDescriptorTable(1, _blur0GpuSrv);
                cmdList.SetComputeRootDescriptorTable(2, _blur1GpuUav);

                // How many groups do we need to dispatch to cover a row of pixels, where each
                // group covers 256 pixels (the 256 is defined in the ComputeShader).
                int numGroupsX = (int)Math.Ceiling(_width / 256.0f);
                cmdList.Dispatch(numGroupsX, _height, 1);

                cmdList.ResourceBarrierTransition(_blurMap0, ResourceStates.GenericRead, ResourceStates.UnorderedAccess);
                cmdList.ResourceBarrierTransition(_blurMap1, ResourceStates.UnorderedAccess, ResourceStates.GenericRead);

                //
                // Vertical Blur pass.
                //

                cmdList.PipelineState = vertBlurPso;

                cmdList.SetComputeRootDescriptorTable(1, _blur1GpuSrv);
                cmdList.SetComputeRootDescriptorTable(2, _blur0GpuUav);

                // How many groups do we need to dispatch to cover a column of pixels, where each
                // group covers 256 pixels  (the 256 is defined in the ComputeShader).
                int numGroupsY = (int)Math.Ceiling(_height / 256.0f);
                cmdList.Dispatch(_width, numGroupsY, 1);

                cmdList.ResourceBarrierTransition(_blurMap0, ResourceStates.UnorderedAccess, ResourceStates.GenericRead);
                cmdList.ResourceBarrierTransition(_blurMap1, ResourceStates.GenericRead, ResourceStates.UnorderedAccess);
            }
        }