Esempio n. 1
0
        protected override void Destroy()
        {
            RootSignature?.Dispose();
            RootSignature = null;

            base.Destroy();
        }
Esempio n. 2
0
 public void AddLocalRootSignature(RootSignature signature, ReadOnlyMemory <ReadOnlyMemory <char> > associations)
 {
     _localRootSigs.Add((signature, associations));
     _totalNumAssociations      += associations.Length;
     _totalNumAssocationObjects += associations.IsEmpty ? 0 : 1;
     _totalNumSubObjects        += associations.IsEmpty ? 1 : 2;
 }
Esempio n. 3
0
        private void BuildRootSignature()
        {
            var texTable = new DescriptorRange(DescriptorRangeType.ShaderResourceView, 1, 0);

            var descriptor1 = new RootDescriptor(0, 0);
            var descriptor2 = new RootDescriptor(1, 0);
            var descriptor3 = new RootDescriptor(2, 0);

            // Root parameter can be a table, root descriptor or root constants.
            // Perfomance TIP: Order from most frequent to least frequent.
            var slotRootParameters = new[]
            {
                new RootParameter(ShaderVisibility.Pixel, texTable),
                new RootParameter(ShaderVisibility.Vertex, descriptor1, RootParameterType.ConstantBufferView),
                new RootParameter(ShaderVisibility.All, descriptor2, RootParameterType.ConstantBufferView),
                new RootParameter(ShaderVisibility.All, descriptor3, RootParameterType.ConstantBufferView)
            };

            // A root signature is an array of root parameters.
            var rootSigDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                slotRootParameters,
                GetStaticSamplers());

            _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize());
        }
Esempio n. 4
0
        public D3DApp(IntPtr handleIntPtr)
        {
            this.handleIntPtr = handleIntPtr;

            this.m4XMsaaState     = false;
            this.swapChainBuffers = new Resource[SwapChainBufferCount];
            this.frameResources   = new List <FrameResource>(NumFrameResources);
            this.fenceEvents      = new List <AutoResetEvent>(NumFrameResources);
            this.mainPassCb       = PassConstants.Default;
            this.meshes           = new List <Mesh>();

            this.InitDirect3D();

            this.commandObjects        = new CommandObjects(device);
            this.swapChain             = SwapChainObject.New(this.handleIntPtr, this.factory, this.commandObjects.GetCommandQueue, BackBufferFormat, SwapChainBufferCount, MsaaCount, MsaaQuality);
            this.descriptorHeapObjects = new DescriptorHeapObjects(device, SwapChainBufferCount, 1);
            this.rootSignature         = RootSignatureObject.New(device);

            this.BuildMesh();
            this.BuildFrameResources();
            this.BuildConstantBuffers();
            this.pso = PipelinesStateObject.New(device, rootSignature, MsaaCount, MsaaQuality, DepthStencilFormat, BackBufferFormat);

            this.FlushCommandQueue();

            this.camera = new OrbitCamera();
        }
        public static PipelineState New(Device device, RootSignature rootSignature, int msaaCount, int msaaQuality, Format depthStencilFormat, Format backBufferFormat)
        {
            var graphicsPipelineStateDescription = BuildGraphicsPipelineStateDescription(rootSignature, msaaCount, msaaQuality, depthStencilFormat);

            graphicsPipelineStateDescription.RenderTargetFormats[0] = backBufferFormat;

            return(device.CreateGraphicsPipelineState(graphicsPipelineStateDescription));
        }
Esempio n. 6
0
        protected override void Destroy()
        {
            RootSignature?.Dispose();
            RootSignature = null;

            bufferUploader.Clear();

            base.Destroy();
        }
Esempio n. 7
0
        public void Initialize()
        {
            // Pipeline state.
            var testShaderPath = "../../../../../Resources/Engine/MipMap.hlsl";

            ComputeShader = ShaderBytecode.CompileFromFile(testShaderPath, "GenerateMipMaps", "cs_5_0");

            // Root parameters.
            var rootParameters = new RootParameter[]
            {
                new RootParameter(ShaderVisibility.All, new RootConstants(0, 0, 2)),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.ShaderResourceView,
                    DescriptorCount = 1,
                    OffsetInDescriptorsFromTableStart = int.MinValue,     // D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND
                    BaseShaderRegister = 0
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType          = DescriptorRangeType.UnorderedAccessView,
                    BaseShaderRegister = 0,
                    OffsetInDescriptorsFromTableStart = int.MinValue,     // D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND
                    DescriptorCount = 1
                }),
            };

            var staticSamplers = new StaticSamplerDescription[]
            {
                new StaticSamplerDescription()
                {
                    Filter           = Filter.MinMagLinearMipPoint,
                    AddressUVW       = TextureAddressMode.Clamp,
                    MipLODBias       = 0f,
                    ComparisonFunc   = Comparison.Never,
                    MinLOD           = 0f,
                    MaxLOD           = float.MaxValue,
                    MaxAnisotropy    = 0,
                    BorderColor      = StaticBorderColor.OpaqueBlack,
                    ShaderRegister   = 0,
                    RegisterSpace    = 0,
                    ShaderVisibility = ShaderVisibility.All
                }
            };

            var rootSignatureDescription = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, staticSamplers);

            RootSignature = RootSignature.Create(Device, rootSignatureDescription);

            Layout = new DescriptorLayout(
                DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView,
                DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView);
        }
        public virtual async Task <PipelineState> CreateComputePipelineStateAsync()
        {
            CompiledShader compiledShader = await CreateShaderAsync();

            RootSignature rootSignature = CreateRootSignature();

            PipelineState pipelineState = new PipelineState(GraphicsDevice, rootSignature, compiledShader.Shaders["compute"]);

            return(pipelineState);
        }
        public static PipelineState CreateComputePipelineState(Device device, RootSignature rootSignature, byte[] computeShader)
        {
            var computePipelineStateDesc = new ComputePipelineStateDescription()
            {
                RootSignature = rootSignature,
                ComputeShader = new ShaderBytecode(computeShader),
                Flags         = PipelineStateFlags.None
            };

            return(device.CreateComputePipelineState(computePipelineStateDesc));
        }
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
        //[MemberNotNull(nameof(_tex), nameof(_texMsaa8x))]
        public void CreatePipelines()
        {
            var rootParams = new[]
            {
                RootParameter.CreateDescriptor(RootParameterType.ConstantBufferView, 0, 0),
                RootParameter.CreateDescriptor(RootParameterType.ConstantBufferView, 1, 0),
                RootParameter.CreateDescriptor(RootParameterType.ConstantBufferView, 2, 0),
                RootParameter.CreateDescriptorTable(DescriptorRangeType.ShaderResourceView, 0, 1, 0)
            };

            var samplers = new[]
            {
                new StaticSampler(
                    TextureAddressMode.Clamp,
                    SamplerFilterType.Anistropic,
                    shaderRegister: 0,
                    registerSpace: 0,
                    ShaderVisibility.All,
                    StaticSampler.OpaqueWhite
                    )
            };

            _rootSig = _device.CreateRootSignature(rootParams, samplers);

            var compilationFlags = new[]
            {
                ShaderCompileFlag.PackMatricesInRowMajorOrder,
                ShaderCompileFlag.AllResourcesBound,
                ShaderCompileFlag.EnableDebugInformation,
                ShaderCompileFlag.WriteDebugInformationToFile()
                //ShaderCompileFlag.DefineMacro("NORMALS")
            };

            var vertexShader = ShaderManager.CompileShader("Shaders/SimpleTexture/TextureVertexShader.hlsl", ShaderModel.Vs_6_0, compilationFlags);
            var pixelShader  = ShaderManager.CompileShader("Shaders/SimpleTexture/TexturePixelShader.hlsl", ShaderModel.Ps_6_0, compilationFlags);

            var psoDesc = new GraphicsPipelineDesc
            {
                RootSignature       = _rootSig,
                RenderTargetFormats = RenderTargetFormat,
                DepthStencilFormat  = DepthStencilFormat,
                VertexShader        = vertexShader,
                PixelShader         = pixelShader,
                Topology            = TopologyClass.Triangle,
                Inputs = InputLayout.FromType <TexturedVertex>()
            };

            _tex = _device.PipelineManager.CreatePipelineStateObject(psoDesc, "Texture");

            //psoDesc.Msaa = MultisamplingDesc.X8;
            _texMsaa8x = _device.PipelineManager.CreatePipelineStateObject(psoDesc, "Texture_MSAA8X");
        }
Esempio n. 12
0
        public static RootSignature FromString(CommonContext context, string s)
        {
            RootSignature rootSignature;

            if (context.rootSignatures.TryGetValue(s, out rootSignature))
            {
                return(rootSignature);
            }


            rootSignature             = new RootSignature();
            context.rootSignatures[s] = rootSignature;
            RootSignatureParamP[] desc = new RootSignatureParamP[s.Length];

            for (int i = 0; i < s.Length; i++)
            {
                char c = s[i];
                switch (c)
                {
                case 'C':
                    desc[i] = RootSignatureParamP.CBV;
                    break;

                case 'c':
                    desc[i] = RootSignatureParamP.CBVTable;
                    break;

                case 'S':
                    desc[i] = RootSignatureParamP.SRV;
                    break;

                case 's':
                    desc[i] = RootSignatureParamP.SRVTable;
                    break;

                case 'U':
                    desc[i] = RootSignatureParamP.UAV;
                    break;

                case 'u':
                    desc[i] = RootSignatureParamP.UAVTable;
                    break;

                default:
                    throw new NotImplementedException("error root signature desc.");
                    break;
                }
            }
            context.device.CreateRootSignature(rootSignature, desc);
            return(rootSignature);
        }
Esempio n. 13
0
        public void LoadShaders(string path)
        {
            BuildDescriptorHeaps();
            BuildConstantBuffers <Simple2DConst>();
            if (RootMake == null)
            {
                BuildRootSignature();
                Root = _rootSignature;
            }

            else
            {
                RootMake?.Invoke();
            }



            VertexCode = LoadVertex(path);
            FragCode   = LoadFrag(path);
            SetupShader();

            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(Input),
                RootSignature      = Root,
                VertexShader       = VertexCode,
                PixelShader        = FragCode,
                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;
            //psoDesc.

            pipelineState = DXGlobal.device.CreateGraphicsPipelineState(psoDesc);
            _pip          = pipelineState;
            // commandList = DXGlobal.device.CreateCommandList(CommandListType.Direct, DXGlobal.Display.DirectCmdListAlloc, pipelineState);
        }
        public async Task <PipelineState> CreateGraphicsPipelineStateAsync(InputElementDescription[] inputElements)
        {
            CompiledShader compiledShader = await CreateShaderAsync();

            RootSignature rootSignature = CreateRootSignature();

            PipelineState pipelineState = new PipelineState(GraphicsDevice, rootSignature, inputElements,
                                                            compiledShader.Shaders["vertex"],
                                                            compiledShader.Shaders["pixel"],
                                                            compiledShader.Shaders.ContainsKey("geometry") ? compiledShader.Shaders["geometry"] : null,
                                                            compiledShader.Shaders.ContainsKey("hull") ? compiledShader.Shaders["hull"] : null,
                                                            compiledShader.Shaders.ContainsKey("domain") ? compiledShader.Shaders["domain"] : null);

            return(pipelineState);
        }
        private void BuildRootSignature()
        {
            // Root parameter can be a table, root descriptor or root constants.
            // Perfomance TIP: Order from most frequent to least frequent.
            var slotRootParameters = new[]
            {
                new RootParameter(ShaderVisibility.All, new RootDescriptor(0, 0), RootParameterType.ShaderResourceView),
                new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ShaderResourceView),
                new RootParameter(ShaderVisibility.All, new RootDescriptor(0, 0), RootParameterType.UnorderedAccessView)
            };

            // A root signature is an array of root parameters.
            var rootSigDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                slotRootParameters);

            _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize());
        }
Esempio n. 16
0
        private void BuildRootSignature()
        {
            // Root parameter can be a table, root descriptor or root constants.
            var slotRootParameters = new[]
            {
                // TODO: API suggestion: RootDescriptor register space default value = 0.
                new RootParameter(ShaderVisibility.Vertex, new RootDescriptor(0, 0), RootParameterType.ConstantBufferView),
                new RootParameter(ShaderVisibility.Vertex, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView)
            };

            // A root signature is an array of root parameters.
            var rootSigDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                slotRootParameters);

            // Create a root signature with a single slot which points to a descriptor range consisting of a single constant buffer.
            _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize());
        }
Esempio n. 17
0
        public void Initialize()
        {
            // Pipeline state.
            var testShaderPath = "../../../../../Resources/Engine/Forward/Standard.hlsl";

            VertexShader = ShaderBytecode.CompileFromFile(testShaderPath, "VSMain", "vs_5_0");
            PixelShader  = ShaderBytecode.CompileFromFile(testShaderPath, "PSMain", "ps_5_0");

            // Root parameters.
            var rootParameters = new RootParameter[]
            {
                new RootParameter(ShaderVisibility.All,
                                  new DescriptorRange()
                {
                    RangeType          = DescriptorRangeType.ConstantBufferView,
                    BaseShaderRegister = 0,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    DescriptorCount = 1,
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.ShaderResourceView,
                    DescriptorCount = 1,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    BaseShaderRegister = 0
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType          = DescriptorRangeType.Sampler,
                    BaseShaderRegister = 0,
                    DescriptorCount    = 1
                }),
            };
            var rootSignatureDescription = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters);

            RootSignature = RootSignature.Create(Device, rootSignatureDescription);

            Layout = new DescriptorLayout(
                DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView,
                DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView,
                DescriptorLayout.EntryType.SamplerState);
        }
Esempio n. 18
0
        public void Execute(GraphicsCommandList cmdList, RootSignature rootSig, PipelineState pso, GpuDescriptorHandle input)
        {
            cmdList.SetComputeRootSignature(rootSig);
            cmdList.PipelineState = pso;

            cmdList.SetComputeRootDescriptorTable(0, input);
            cmdList.SetComputeRootDescriptorTable(2, _gpuUav);

            cmdList.ResourceBarrierTransition(_output, ResourceStates.GenericRead, ResourceStates.UnorderedAccess);

            // How many groups do we need to dispatch to cover image, where each
            // group covers 16x16 pixels.
            int numGroupsX = (int)Math.Ceiling(_width / 16.0);
            int numGroupsY = (int)Math.Ceiling(_height / 16.0);

            cmdList.Dispatch(numGroupsX, numGroupsY, 1);

            cmdList.ResourceBarrierTransition(_output, ResourceStates.UnorderedAccess, ResourceStates.GenericRead);
        }
Esempio n. 19
0
        private static async Task ExecuteOnGpu(GraphicsDevice device, StructuredBuffer <float> sourceBufferView, WriteableStructuredBuffer <float> destinationBufferView)
        {
            bool generateWithDelegate = false;

            DescriptorSet descriptorSet = new DescriptorSet(device, 2);

            descriptorSet.AddResourceViews(destinationBufferView);
            descriptorSet.AddResourceViews(sourceBufferView);

            // Generate computer shader
            ShaderGenerator shaderGenerator = generateWithDelegate
                ? CreateShaderGeneratorWithDelegate(sourceBufferView, destinationBufferView)
                : CreateShaderGeneratorWithClass();

            ShaderGeneratorResult result = shaderGenerator.GenerateShader();

            // Compile shader

            byte[] shaderBytecode = ShaderCompiler.Compile(ShaderStage.ComputeShader, result.ShaderSource, result.EntryPoints["compute"]);

            DescriptorRange[] descriptorRanges = new DescriptorRange[]
            {
                new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 0),
                new DescriptorRange(DescriptorRangeType.ShaderResourceView, 1, 0)
            };

            RootParameter rootParameter = new RootParameter(new RootDescriptorTable(descriptorRanges), ShaderVisibility.All);

            RootSignatureDescription rootSignatureDescription = new RootSignatureDescription(RootSignatureFlags.None, new[] { rootParameter });
            RootSignature            rootSignature            = new RootSignature(device, rootSignatureDescription);
            PipelineState            pipelineState            = new PipelineState(device, rootSignature, shaderBytecode);

            // Execute computer shader

            using (CommandList commandList = new CommandList(device, CommandListType.Compute))
            {
                commandList.SetPipelineState(pipelineState);
                commandList.SetComputeRootDescriptorTable(0, descriptorSet);

                commandList.Dispatch(1, 1, 1);
                await commandList.FlushAsync();
            }
        }
Esempio n. 20
0
        private void BuildRootSignature()
        {
            var cbvTable0 = new DescriptorRange(DescriptorRangeType.ConstantBufferView, 1, 0);
            var cbvTable1 = new DescriptorRange(DescriptorRangeType.ConstantBufferView, 1, 1);

            // Root parameter can be a table, root descriptor or root constants.
            var slotRootParameters = new[]
            {
                new RootParameter(ShaderVisibility.Vertex, cbvTable0),
                new RootParameter(ShaderVisibility.Vertex, cbvTable1)
            };

            // A root signature is an array of root parameters.
            var rootSigDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                slotRootParameters);

            // Create a root signature with a single slot which points to a descriptor range consisting of a single constant buffer.
            _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize());
        }
Esempio n. 21
0
        /// <summary>
        /// Compiles or recompiles the effect if necesssary.
        /// </summary>
        /// <param name="graphicsDevice"></param>
        /// <returns>True if the effect was recompiled, false otherwise.</returns>
        public bool UpdateEffect(GraphicsDevice graphicsDevice)
        {
            if (effect == null || permutationCounter != Parameters.PermutationCounter || (effect != null && effect.SourceChanged))
            {
                permutationCounter = Parameters.PermutationCounter;

                var oldEffect = effect;
                ChooseEffect(graphicsDevice);

                // Early exit: same effect, and already initialized
                if (oldEffect == effect && descriptorReflection != null)
                {
                    return(false);
                }

                // Update reflection and rearrange buffers/resources
                var layoutNames = effect.Bytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList();
                descriptorReflection = EffectDescriptorSetReflection.New(graphicsDevice, effect.Bytecode, layoutNames, "Globals");

                RootSignature?.Dispose();
                RootSignature = RootSignature.New(graphicsDevice, descriptorReflection);

                bufferUploader.Clear();
                bufferUploader.Compile(graphicsDevice, descriptorReflection, effect.Bytecode);

                // Create parameter updater
                var layouts = new DescriptorSetLayoutBuilder[descriptorReflection.Layouts.Count];
                for (int i = 0; i < descriptorReflection.Layouts.Count; ++i)
                {
                    layouts[i] = descriptorReflection.Layouts[i].Layout;
                }
                var parameterUpdaterLayout = new EffectParameterUpdaterLayout(graphicsDevice, effect, layouts);
                parameterUpdater = new EffectParameterUpdater(parameterUpdaterLayout, Parameters);

                descriptorSets = new DescriptorSet[parameterUpdater.ResourceGroups.Length];

                return(true);
            }

            return(false);
        }
Esempio n. 22
0
        public void Disturb(GraphicsCommandList cmdList, RootSignature rootSig, PipelineState pso, int i, int j, float magnitude)
        {
            cmdList.PipelineState = pso;
            cmdList.SetComputeRootSignature(rootSig);

            // Set the disturb constants.
            int[] disturbIndex = { j, i };
            Utilities.Pin(ref magnitude, ptr => cmdList.SetComputeRoot32BitConstants(0, 1, ptr, 3));
            Utilities.Pin(disturbIndex, ptr => cmdList.SetComputeRoot32BitConstants(0, 2, ptr, 4));

            cmdList.SetComputeRootDescriptorTable(3, _currSolUav);

            // The current solution is in the GENERIC_READ state so it can be read by the vertex shader.
            // Change it to UNORDERED_ACCESS for the compute shader. Note that a UAV can still be
            // read in a compute shader.
            cmdList.ResourceBarrierTransition(_currSol, ResourceStates.GenericRead, ResourceStates.UnorderedAccess);

            // One thread group kicks off one thread, which displaces the height of one
            // vertex and its neighbors.
            cmdList.Dispatch(1, 1, 1);
        }
Esempio n. 23
0
        private void BuildRootSignature()
        {
            // Shader programs typically require resources as input (constant buffers,
            // textures, samplers). The root signature defines the resources the shader
            // programs expect. If we think of the shader programs as a function, and
            // the input resources as function parameters, then the root signature can be
            // thought of as defining the function signature.

            // Root parameter can be a table, root descriptor or root constants.

            // Create a single descriptor table of CBVs.
            var cbvTable = new DescriptorRange(DescriptorRangeType.ConstantBufferView, 1, 0);

            // A root signature is an array of root parameters.
            var rootSigDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new[]
            {
                new RootParameter(ShaderVisibility.Vertex, cbvTable)
            });

            _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize());
        }
        private void BuildWavesRootSignature()
        {
            var uavTable0 = new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 0);
            var uavTable1 = new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 1);
            var uavTable2 = new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 2);

            // Root parameter can be a table, root descriptor or root constants.
            // Perfomance TIP: Order from most frequent to least frequent.
            var slotRootParameters = new[]
            {
                new RootParameter(ShaderVisibility.All, new RootConstants(0, 0, 6)),
                new RootParameter(ShaderVisibility.All, uavTable0),
                new RootParameter(ShaderVisibility.All, uavTable1),
                new RootParameter(ShaderVisibility.All, uavTable2),
            };

            // A root signature is an array of root parameters.
            var rootSigDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                slotRootParameters);

            _wavesRootSignature = Device.CreateRootSignature(rootSigDesc.Serialize());
        }
        private void BuildRootSignature()
        {
            // Perfomance TIP: Order from most frequent to least frequent.
            var descriptor1 = new RootDescriptor(0, 0);
            var descriptor2 = new RootDescriptor(1, 0);
            var descriptor3 = new RootDescriptor(2, 0);

            // Root parameter can be a table, root descriptor or root constants.
            var slotRootParameters = new[]
            {
                new RootParameter(ShaderVisibility.Vertex, descriptor1, RootParameterType.ConstantBufferView),
                new RootParameter(ShaderVisibility.Pixel, descriptor2, RootParameterType.ConstantBufferView),
                new RootParameter(ShaderVisibility.All, descriptor3, RootParameterType.ConstantBufferView)
            };

            // A root signature is an array of root parameters.
            var rootSigDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                slotRootParameters);

            // Create a root signature with a single slot which points to a descriptor range consisting of a single constant buffer.
            _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize());
        }
Esempio n. 26
0
        private void LoadAssets()
        {
            RootParameter parameter1 = new RootParameter(ShaderVisibility.All, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, DescriptorCount = 1 });
            RootParameter parameter2 = new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, BaseShaderRegister = 0, DescriptorCount = 1 });
            RootParameter parameter3 = new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, BaseShaderRegister = 0, DescriptorCount = 1 });

            // Create a root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter1, parameter2, parameter3 });
            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

            #if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
            #endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                    new InputElement("POSITION",0,Format.R32G32B32_Float,0,0),
                    new InputElement("NORMAL",0,Format.R32G32B32_Float,12,0),
                    new InputElement("TEXCOORD",0,Format.R32G32B32_Float,24,0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout = new InputLayoutDescription(inputElementDescs),
                RootSignature = rootSignature,
                VertexShader = vertexShader,
                PixelShader = pixelShader,
                RasterizerState = RasterizerStateDescription.Default(),
                BlendState = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState = DepthStencilStateDescription.Default(),
                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 = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            //constant Buffer
            int constantBufferSize = (Utilities.SizeOf<Transform>() + 255) & ~255;
            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(constantBufferSize), ResourceStates.GenericRead);
            constantBufferDescriptorSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            //constant buffer
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes = constantBufferSize
            };

            CpuDescriptorHandle cbHandleHeapStart = constantBufferViewHeap.CPUDescriptorHandleForHeapStart;
            device.CreateConstantBufferView(cbvDesc, cbHandleHeapStart);
            cbvDesc.BufferLocation += Utilities.SizeOf<Transform>();

            cbHandleHeapStart += constantBufferDescriptorSize;
            LoadMesh(cbHandleHeapStart);

            // Create synchronization objects.
            {
                fence = device.CreateFence(0, FenceFlags.None);
                fenceValue = 1;

                // Create an event handle to use for frame synchronization.
                fenceEvent = new AutoResetEvent(false);
            }

            InitBundles();
        }
Esempio n. 27
0
        /// <param name="context"></param>
        /// <inheritdoc/>
        public override void PrepareEffectPermutations(RenderDrawContext context)
        {
            base.PrepareEffectPermutations(context);

            // TODO: Temporary until we have a better system for handling permutations
            var renderEffects   = RenderData.GetData(RenderEffectKey);
            int effectSlotCount = EffectPermutationSlotCount;

            Dispatcher.ForEach(RenderSystem.Views, view =>
            {
                var viewFeature = view.Features[Index];
                Dispatcher.ForEach(viewFeature.RenderNodes, renderNodeReference =>
                {
                    var renderNode   = this.GetRenderNode(renderNodeReference);
                    var renderObject = renderNode.RenderObject;

                    // Get RenderEffect
                    var staticObjectNode       = renderObject.StaticObjectNode;
                    var staticEffectObjectNode = staticObjectNode * effectSlotCount + effectSlots[renderNode.RenderStage.Index].Index;
                    var renderEffect           = renderEffects[staticEffectObjectNode];

                    var effectSelector = renderObject.ActiveRenderStages[renderNode.RenderStage.Index].EffectSelector;

                    // Create it (first time) or regenerate it if effect changed
                    if (renderEffect == null || effectSelector != renderEffect.EffectSelector)
                    {
                        renderEffect = new RenderEffect(renderObject.ActiveRenderStages[renderNode.RenderStage.Index].EffectSelector);
                        renderEffects[staticEffectObjectNode] = renderEffect;
                    }

                    // Is it the first time this frame that we check this RenderEffect?
                    if (renderEffect.MarkAsUsed(RenderSystem))
                    {
                        renderEffect.EffectValidator.BeginEffectValidation();
                    }
                });
            });

            // Step1: Perform permutations
            PrepareEffectPermutationsImpl(context);

            PrepareRenderTargetExtensionsMixins(context);

            var currentTime = DateTime.UtcNow;

            // Step2: Compile effects
            Dispatcher.ForEach(RenderObjects, renderObject =>
            {
                //var renderObject = RenderObjects[index];
                var staticObjectNode = renderObject.StaticObjectNode;

                for (int i = 0; i < effectSlotCount; ++i)
                {
                    var staticEffectObjectNode = staticObjectNode * effectSlotCount + i;
                    var renderEffect           = renderEffects[staticEffectObjectNode];

                    // Skip if not used
                    if (renderEffect == null)
                    {
                        continue;
                    }

                    // Skip reflection update unless a state change requires it
                    renderEffect.IsReflectionUpdateRequired = false;

                    if (!renderEffect.IsUsedDuringThisFrame(RenderSystem))
                    {
                        continue;
                    }

                    // Skip if nothing changed
                    if (renderEffect.EffectValidator.ShouldSkip)
                    {
                        // Reset pending effect, as it is now obsolete anyway
                        renderEffect.Effect = null;
                        renderEffect.State  = RenderEffectState.Skip;
                    }
                    else if (renderEffect.EffectValidator.EndEffectValidation() && (renderEffect.Effect == null || !renderEffect.Effect.SourceChanged) && !(renderEffect.State == RenderEffectState.Error && currentTime >= renderEffect.RetryTime))
                    {
                        InvalidateEffectPermutation(renderObject, renderEffect);

                        // Still, let's check if there is a pending effect compiling
                        var pendingEffect = renderEffect.PendingEffect;
                        if (pendingEffect == null || !pendingEffect.IsCompleted)
                        {
                            continue;
                        }

                        renderEffect.ClearFallbackParameters();
                        if (pendingEffect.IsFaulted)
                        {
                            // The effect can fail compilation asynchronously
                            renderEffect.State  = RenderEffectState.Error;
                            renderEffect.Effect = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Error);
                        }
                        else
                        {
                            renderEffect.State  = RenderEffectState.Normal;
                            renderEffect.Effect = pendingEffect.Result;
                        }
                        renderEffect.PendingEffect = null;
                    }
                    else
                    {
                        // Reset pending effect, as it is now obsolete anyway
                        renderEffect.PendingEffect = null;
                        renderEffect.State         = RenderEffectState.Normal;

                        // CompilerParameters are ThreadStatic
                        if (staticCompilerParameters == null)
                        {
                            staticCompilerParameters = new CompilerParameters();
                        }

                        foreach (var effectValue in renderEffect.EffectValidator.EffectValues)
                        {
                            staticCompilerParameters.SetObject(effectValue.Key, effectValue.Value);
                        }

                        TaskOrResult <Effect> asyncEffect;
                        try
                        {
                            // The effect can fail compilation synchronously
                            asyncEffect = RenderSystem.EffectSystem.LoadEffect(renderEffect.EffectSelector.EffectName, staticCompilerParameters);
                            staticCompilerParameters.Clear();
                        }
                        catch
                        {
                            staticCompilerParameters.Clear();
                            renderEffect.ClearFallbackParameters();
                            renderEffect.State  = RenderEffectState.Error;
                            renderEffect.Effect = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Error);
                            continue;
                        }

                        renderEffect.Effect = asyncEffect.Result;
                        if (renderEffect.Effect == null)
                        {
                            // Effect still compiling, let's find if there is a fallback
                            renderEffect.ClearFallbackParameters();
                            renderEffect.PendingEffect = asyncEffect.Task;
                            renderEffect.State         = RenderEffectState.Compiling;
                            renderEffect.Effect        = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Compiling);
                        }
                    }

                    renderEffect.IsReflectionUpdateRequired = true;
                }
            });

            // Step3: Uupdate reflection infos (offset, etc...)
            foreach (var renderObject in RenderObjects)
            {
                var staticObjectNode = renderObject.StaticObjectNode;

                for (int i = 0; i < effectSlotCount; ++i)
                {
                    var staticEffectObjectNode = staticObjectNode * effectSlotCount + i;
                    var renderEffect           = renderEffects[staticEffectObjectNode];

                    // Skip if not used
                    if (renderEffect == null || !renderEffect.IsReflectionUpdateRequired)
                    {
                        continue;
                    }

                    var effect = renderEffect.Effect;
                    if (effect == null && renderEffect.State == RenderEffectState.Compiling)
                    {
                        // Need to wait for completion because we have nothing else
                        renderEffect.PendingEffect.Wait();

                        if (!renderEffect.PendingEffect.IsFaulted)
                        {
                            renderEffect.Effect = effect = renderEffect.PendingEffect.Result;
                            renderEffect.State  = RenderEffectState.Normal;
                        }
                        else
                        {
                            renderEffect.ClearFallbackParameters();
                            renderEffect.State  = RenderEffectState.Error;
                            renderEffect.Effect = effect = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Error);
                        }
                    }

                    var effectHashCode = effect != null ? (uint)effect.GetHashCode() : 0;

                    // Effect is last 16 bits
                    renderObject.StateSortKey = (renderObject.StateSortKey & 0xFFFF0000) | (effectHashCode & 0x0000FFFF);

                    if (effect != null)
                    {
                        RenderEffectReflection renderEffectReflection;
                        if (!InstantiatedEffects.TryGetValue(effect, out renderEffectReflection))
                        {
                            renderEffectReflection = new RenderEffectReflection();

                            // Build root signature automatically from reflection
                            renderEffectReflection.DescriptorReflection      = EffectDescriptorSetReflection.New(RenderSystem.GraphicsDevice, effect.Bytecode, effectDescriptorSetSlots, "PerFrame");
                            renderEffectReflection.ResourceGroupDescriptions = new ResourceGroupDescription[renderEffectReflection.DescriptorReflection.Layouts.Count];

                            // Compute ResourceGroup hashes
                            for (int index = 0; index < renderEffectReflection.DescriptorReflection.Layouts.Count; index++)
                            {
                                var descriptorSet = renderEffectReflection.DescriptorReflection.Layouts[index];
                                if (descriptorSet.Layout == null)
                                {
                                    continue;
                                }

                                var constantBufferReflection = effect.Bytecode.Reflection.ConstantBuffers.FirstOrDefault(x => x.Name == descriptorSet.Name);

                                renderEffectReflection.ResourceGroupDescriptions[index] = new ResourceGroupDescription(descriptorSet.Layout, constantBufferReflection);
                            }

                            renderEffectReflection.RootSignature = RootSignature.New(RenderSystem.GraphicsDevice, renderEffectReflection.DescriptorReflection);
                            renderEffectReflection.BufferUploader.Compile(RenderSystem.GraphicsDevice, renderEffectReflection.DescriptorReflection, effect.Bytecode);

                            // Prepare well-known descriptor set layouts
                            renderEffectReflection.PerDrawLayout  = CreateDrawResourceGroupLayout(renderEffectReflection.ResourceGroupDescriptions[perDrawDescriptorSetSlot.Index], renderEffect.State);
                            renderEffectReflection.PerFrameLayout = CreateFrameResourceGroupLayout(renderEffectReflection.ResourceGroupDescriptions[perFrameDescriptorSetSlot.Index], renderEffect.State);
                            renderEffectReflection.PerViewLayout  = CreateViewResourceGroupLayout(renderEffectReflection.ResourceGroupDescriptions[perViewDescriptorSetSlot.Index], renderEffect.State);

                            InstantiatedEffects.Add(effect, renderEffectReflection);

                            // Notify a new effect has been compiled
                            EffectCompiled?.Invoke(RenderSystem, effect, renderEffectReflection);
                        }

                        // Setup fallback parameters
                        if (renderEffect.State != RenderEffectState.Normal && renderEffectReflection.FallbackUpdaterLayout == null)
                        {
                            // Process all "non standard" layouts
                            var layoutMapping      = new int[renderEffectReflection.DescriptorReflection.Layouts.Count - 3];
                            var layouts            = new DescriptorSetLayoutBuilder[renderEffectReflection.DescriptorReflection.Layouts.Count - 3];
                            int layoutMappingIndex = 0;
                            for (int index = 0; index < renderEffectReflection.DescriptorReflection.Layouts.Count; index++)
                            {
                                var layout = renderEffectReflection.DescriptorReflection.Layouts[index];

                                // Skip well-known layouts (already handled)
                                if (layout.Name == "PerDraw" || layout.Name == "PerFrame" || layout.Name == "PerView")
                                {
                                    continue;
                                }

                                layouts[layoutMappingIndex]         = layout.Layout;
                                layoutMapping[layoutMappingIndex++] = index;
                            }

                            renderEffectReflection.FallbackUpdaterLayout        = new EffectParameterUpdaterLayout(RenderSystem.GraphicsDevice, effect, layouts);
                            renderEffectReflection.FallbackResourceGroupMapping = layoutMapping;
                        }

                        // Update effect
                        renderEffect.Effect     = effect;
                        renderEffect.Reflection = renderEffectReflection;

                        // Invalidate pipeline state (new effect)
                        renderEffect.PipelineState = null;

                        renderEffects[staticEffectObjectNode] = renderEffect;
                    }
                    else
                    {
                        renderEffect.Reflection    = RenderEffectReflection.Empty;
                        renderEffect.PipelineState = null;
                    }
                }
            }
        }
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, DescriptorCount = 1 } };
            RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges);

            // Create a root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter });
            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

            #if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
            #endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                    new InputElement("POSITION",0,Format.R32G32B32_Float,0,0),
                    new InputElement("COLOR",0,Format.R32G32B32A32_Float,12,0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout = new InputLayoutDescription(inputElementDescs),
                RootSignature = rootSignature,
                VertexShader = vertexShader,
                PixelShader = pixelShader,
                RasterizerState = RasterizerStateDescription.Default(),
                BlendState = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState = DepthStencilStateDescription.Default(),
                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 = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a cube.

            Vertex[] vertices = new[]
            {
                ////TOP
                new Vertex(new Vector3(-5,5,5),new Vector4(0,1,0,0)),
                new Vertex(new Vector3(5,5,5),new Vector4(0,1,0,0)),
                new Vertex(new Vector3(5,5,-5),new Vector4(0,1,0,0)),
                new Vertex(new Vector3(-5,5,-5),new Vector4(0,1,0,0)),
                //BOTTOM
                new Vertex(new Vector3(-5,-5,5),new Vector4(1,0,1,1)),
                new Vertex(new Vector3(5,-5,5),new Vector4(1,0,1,1)),
                new Vertex(new Vector3(5,-5,-5),new Vector4(1,0,1,1)),
                new Vertex(new Vector3(-5,-5,-5),new Vector4(1,0,1,1)),
                //LEFT
                new Vertex(new Vector3(-5,-5,5),new Vector4(1,0,0,1)),
                new Vertex(new Vector3(-5,5,5),new Vector4(1,0,0,1)),
                new Vertex(new Vector3(-5,5,-5),new Vector4(1,0,0,1)),
                new Vertex(new Vector3(-5,-5,-5),new Vector4(1,0,0,1)),
                //RIGHT
                new Vertex(new Vector3(5,-5,5),new Vector4(1,1,0,1)),
                new Vertex(new Vector3(5,5,5),new Vector4(1,1,0,1)),
                new Vertex(new Vector3(5,5,-5),new Vector4(1,1,0,1)),
                new Vertex(new Vector3(5,-5,-5),new Vector4(1,1,0,1)),
                //FRONT
                new Vertex(new Vector3(-5,5,5),new Vector4(0,1,1,1)),
                new Vertex(new Vector3(5,5,5),new Vector4(0,1,1,1)),
                new Vertex(new Vector3(5,-5,5),new Vector4(0,1,1,1)),
                new Vertex(new Vector3(-5,-5,5),new Vector4(0,1,1,1)),
                //BACK
                new Vertex(new Vector3(-5,5,-5),new Vector4(0,0,1,1)),
                new Vertex(new Vector3(5,5,-5),new Vector4(0,0,1,1)),
                new Vertex(new Vector3(5,-5,-5),new Vector4(0,0,1,1)),
                new Vertex(new Vector3(-5,-5,-5),new Vector4(0,0,1,1))
            };

            int vertexBufferSize = Utilities.SizeOf(vertices);

            // 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.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, vertices, 0, vertices.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>();
            vertexBufferView.SizeInBytes = vertexBufferSize;

            //Create Index Buffer
            //Indices
            int[] indices = new int[]
            {
                0,1,2,0,2,3,
                4,6,5,4,7,6,
                8,9,10,8,10,11,
                12,14,13,12,15,14,
                16,18,17,16,19,18,
                20,21,22,20,22,23
            };
            int indexBufferSize = Utilities.SizeOf(indices);

            indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pIndexDataBegin = indexBuffer.Map(0);
            Utilities.Write(pIndexDataBegin, indices, 0, indices.Length);
            indexBuffer.Unmap(0);

            // Initialize the index buffer view.
            indexBufferView = new IndexBufferView();
            indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress;
            indexBufferView.Format = Format.R32_UInt;
            indexBufferView.SizeInBytes = indexBufferSize;

            //constant Buffer for each cubes
            constantBufferViewHeap = device.CreateDescriptorHeap(new DescriptorHeapDescription()
            {
                DescriptorCount = NumCubes,
                Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
                Flags = DescriptorHeapFlags.ShaderVisible
            });

            int constantBufferSize = (Utilities.SizeOf<Transform>() + 255) & ~255;
            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(constantBufferSize * NumCubes), ResourceStates.GenericRead);
            constantBufferDescriptorSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            //First cube
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes = constantBufferSize
            };

            CpuDescriptorHandle cbHandleHeapStart = constantBufferViewHeap.CPUDescriptorHandleForHeapStart;

            for (int i = 0; i < NumCubes; i++)
            {
                device.CreateConstantBufferView(cbvDesc, cbHandleHeapStart);
                cbvDesc.BufferLocation += Utilities.SizeOf<Transform>();
                cbHandleHeapStart += constantBufferDescriptorSize;
            }

            InitBundles();
        }
Esempio n. 29
0
        public void BuildPSO(Device3 device, GraphicsCommandList commandList)
        {
            World        = Matrix.Translation(-2.5f, -2.5f, -2.5f);
            buffer.World = World;
            light        = new Lighting
            {
                GlobalAmbientX = 1,
                GlobalAmbientY = 1,
                GlobalAmbientZ = 1,
                KaX            = .1f,
                KaY            = .1f,
                KaZ            = .1f,
                KdX            = .5f,
                KdY            = .5f,
                KdZ            = .5f,
                KeX            = .25f,
                KeY            = .25f,
                KeZ            = .25f,
                KsX            = .1f,
                KsY            = .1f,
                KsZ            = .1f,
                LightColorX    = 1,
                LightColorY    = 1,
                LightColorZ    = 1,
                LightPositionX = 10,
                LightPositionY = 10,
                LightPositionZ = 10,
                shininess      = 5
            };

            DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc);

            //setup descriptor ranges
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange()
                                                               {
                                                                   RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0
                                                               } };

            //Get sampler state setup
            StaticSamplerDescription sampler = new StaticSamplerDescription()
            {
                Filter           = Filter.MinimumMinMagMipPoint,
                AddressU         = TextureAddressMode.Border,
                AddressV         = TextureAddressMode.Border,
                AddressW         = TextureAddressMode.Border,
                MipLODBias       = 0,
                MaxAnisotropy    = 0,
                ComparisonFunc   = Comparison.Never,
                BorderColor      = StaticBorderColor.TransparentBlack,
                MinLOD           = 0.0f,
                MaxLOD           = float.MaxValue,
                ShaderRegister   = 0,
                RegisterSpace    = 0,
                ShaderVisibility = ShaderVisibility.Pixel,
            };

            Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000);
            View       = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY);
            World      = Matrix.Translation(-2.5f, -2.5f, -2.5f);

            DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _objectViewHeap   = device.CreateDescriptorHeap(cbvHeapDesc);
            _lightingViewHeap = device.CreateDescriptorHeap(cbvHeapDesc);

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges),
                                                                   new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView),
                                                                   new RootParameter(ShaderVisibility.All, new RootDescriptor(2, 0), RootParameterType.ConstantBufferView) };


            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler });

            _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout           = new InputLayoutDescription(inputElementDescs),
                RootSignature         = _rootSignature,
                VertexShader          = vertexShader,
                PixelShader           = pixelShader,
                RasterizerState       = RasterizerStateDescription.Default(),
                BlendState            = BlendStateDescription.Default(),
                DepthStencilFormat    = SharpDX.DXGI.Format.D24_UNorm_S8_UInt,
                DepthStencilState     = DepthStencilStateDescription.Default(),
                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 = device.CreateGraphicsPipelineState(psoDesc);

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                //Front
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitZ
                },

                //Back
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitZ
                },

                //Left
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitX
                },

                //Right
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitX
                },

                //Top
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitY
                },

                //Bottom
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitY
                }
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // 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.
            _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = _vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            _vertexBuffer.Unmap(0);

            _indicies = new int[] { 0, 1, 2,
                                    3, 2, 1,
                                    6, 5, 4,
                                    5, 6, 7,

                                    10, 9, 8,
                                    9, 10, 11,
                                    12, 13, 14,
                                    15, 14, 13,

                                    18, 17, 16,
                                    17, 18, 19,
                                    20, 21, 22,
                                    23, 22, 21 };

            int indBufferSize = Utilities.SizeOf(_indicies);

            _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead);

            IntPtr pIndBegin = _indexBuffer.Map(0);
            Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length);
            _indexBuffer.Unmap(0);

            _indexBufferView = new IndexBufferView()
            {
                BufferLocation = _indexBuffer.GPUVirtualAddress,
                Format         = Format.R32_UInt,
                SizeInBytes    = indBufferSize
            };

            // Initialize the vertex buffer view.
            _vertexBufferView = new VertexBufferView
            {
                BufferLocation = _vertexBuffer.GPUVirtualAddress,
                StrideInBytes  = Utilities.SizeOf <Vertex>(),
                SizeInBytes    = vertexBufferSize
            };

            _objectBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <ObjectData>()), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = _objectBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ObjectData>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc, _objectViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _objectPointer = _objectBuffer.Map(0);
            Utilities.Write(_objectPointer, ref buffer);

            _lightingBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <Lighting>()), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc2 = new ConstantBufferViewDescription()
            {
                BufferLocation = _objectBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <Lighting>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc2, _lightingViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _lightingPointer = _lightingBuffer.Map(0);
            Utilities.Write(_lightingPointer, ref light);

            Resource textureUploadHeap;

            // Create the texture.
            // Describe and create a Texture2D.
            ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight);
            _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1);

            // Create the GPU upload buffer.
            textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
            {
                Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
            };
            srvDesc.Texture2D.MipLevels = 1;

            device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart);

            _resources = new[] { new GraphicsResource()
                                 {
                                     Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable
                                 },
                                 new GraphicsResource()
                                 {
                                     Resource = _objectBuffer, Register = 2, type = ResourceType.ConstantBufferView
                                 },
                                 new GraphicsResource()
                                 {
                                     Resource = _lightingBuffer, Register = 1, type = ResourceType.ConstantBufferView
                                 } };
        }
Esempio n. 30
0
        private void CreateDeviceResources()
        {
#if DEBUG
            Configuration.EnableObjectTracking      = true;
            Configuration.ThrowOnShaderCompileError = false;

            // Enable the D3D12 debug layer.
            DebugInterface.Get().EnableDebugLayer();
#endif

            using (var factory = new Factory4())
            {
                // Create the Direct3D 12 API device object
                device = new Device(null, SharpDX.Direct3D.FeatureLevel.Level_11_0);
                if (device == null)
                {
                    // TODO: We want to be able to specify adaptor
                    var adapter = factory.Adapters[0];
                    device = new Device(adapter, SharpDX.Direct3D.FeatureLevel.Level_11_0);
                }

                // Create the command queue.
                var queueDesc = new CommandQueueDescription(CommandListType.Direct);
                commandQueue      = device.CreateCommandQueue(queueDesc);
                commandQueue.Name = $"CommandQueue";

                // Create Command Allocator buffers.
                for (int i = 0; i < FrameCount; i++)
                {
                    commandAllocators[i]      = device.CreateCommandAllocator(CommandListType.Direct);
                    commandAllocators[i].Name = $"CommandAllocator F{i}";
                }
            }

            // Create RootSignature.
            var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout,
                                                                 new[]
            {
                new RootParameter(ShaderVisibility.Vertex,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.ConstantBufferView,
                    DescriptorCount = 1,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    BaseShaderRegister = 0,
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.ShaderResourceView,
                    DescriptorCount = 1,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    BaseShaderRegister = 0
                })
            },
                                                                 new[]
            {
                new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0)
                {
                    Filter     = Filter.MinimumMinMagMipPoint,
                    AddressUVW = TextureAddressMode.Border,
                }
            });

            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create Constant Buffer View Heap.
            var cbvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
            };
            cbvHeap      = device.CreateDescriptorHeap(cbvHeapDesc);
            cbvHeap.Name = "CBV Heap";

            // Create Shader Render View Heap.
            var srvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
            };
            srvHeap      = device.CreateDescriptorHeap(srvHeapDesc);
            srvHeap.Name = "SRV Heap";

            // Create synchronization objects.
            fence      = device.CreateFence(fenceValues[currentFrame], FenceFlags.None);
            fence.Name = $"Fence";
            fenceValues[currentFrame]++;

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);
        }
Esempio n. 31
0
        //创建资源
        private void LoadAssets()
        {
            //创建一个空的根签名
            var rootSignatureDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                //根常量
                new[] {
                new RootParameter(ShaderVisibility.All,    //指定可以访问根签名绑定的内容的着色器,这里设置为顶点着色器
                                  new DescriptorRange()
                {
                    RangeType          = DescriptorRangeType.ConstantBufferView, //指定描述符范围,这里的参数是CBV
                    BaseShaderRegister = 0,                                      //指定描述符范围内的基本着色器
                    OffsetInDescriptorsFromTableStart = int.MinValue,            //描述符从根签名开始的偏移量
                    DescriptorCount = 1                                          //描述符范围内的描述符数
                })
            });

            //表示该根签名需要一组顶点缓冲区来绑定
            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            //创建流水线状态,负责编译和加载着色器
#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VS", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VS", "vs_5_0"));
#endif

//#if DEBUG
//            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PS", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
//#else
//            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PS", "ps_5_0"));
//#endif

            //描述输入装配器阶段的输入元素,这里定义顶点输入布局
            var inputElementDescs = new[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
            };

            //创建流水线状态对象(PSO)
            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout   = new InputLayoutDescription(inputElementDescs),  //描述输入缓冲器
                RootSignature = rootSignature,                                  //根签名
                VertexShader  = vertexShader,                                   //顶点着色器
                //PixelShader = pixelShader,//像素着色器
                RasterizerState       = RasterizerStateDescription.Default(),   //描述光栅器状态
                BlendState            = BlendStateDescription.Default(),        //描述混合状态
                DepthStencilFormat    = SharpDX.DXGI.Format.D32_Float,          //描述深度/模板格式(纹理资源)
                DepthStencilState     = DepthStencilStateDescription.Default(), //描述深度模板状态
                SampleMask            = int.MaxValue,                           //混合状态的样本掩码
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,         //定义该管道的几何或外壳着色器的输入类型,这里是三角
                RenderTargetCount     = 1,                                      //RTVFormat成员中的渲染目标格式数
                Flags             = PipelineStateFlags.None,                    //用于控制管道状态的标志,这里表示没有标志
                SampleDescription = new SampleDescription(1, 0),                //描述资源的多采样参数
                StreamOutput      = new StreamOutputDescription()               //描述输出缓冲器
            };
            psoDesc.RenderTargetFormats[0] = Format.R8G8B8A8_UNorm;             //描述渲染目标格式的数组

            //设置管道
            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            //创建命令列表
            commandList = device.CreateCommandList(
                CommandListType.Direct, //指定命令列表的创建类型,Direct命令列表不会继承任何GPU状态
                commandAllocator,       //指向设备创建的命令列表对象的指针
                pipelineState);         //指向(管道)内存块的指针

            commandList.Close();

            float aspectRatio = viewPort.Width / viewPort.Height;

            //定义待绘制图形的几何形状
            string bitmapPath = @"C:\Users\yulanli\Desktop\TerrainForm\heightMap.BMP";
            Bitmap bitmap     = new Bitmap(bitmapPath);
            xCount     = (bitmap.Width - 1) / 2;
            yCount     = (bitmap.Height - 1) / 2;
            cellWidth  = bitmap.Width / xCount;
            cellHeight = bitmap.Height / yCount;

            var vertices = new PositionTextured[(xCount + 1) * (yCount + 1)];//定义顶点
            for (int i = 0; i < yCount + 1; i++)
            {
                for (int j = 0; j < xCount + 1; j++)
                {
                    System.Drawing.Color color = bitmap.GetPixel((int)(j * cellWidth), (int)(i * cellHeight));
                    float height = float.Parse(color.R.ToString()) + float.Parse(color.G.ToString()) + float.Parse(color.B.ToString());
                    height /= 10;
                    vertices[j + i * (xCount + 1)].Position = new Vector3(j * cellWidth, height, i * cellHeight);
                    vertices[j + i * (xCount + 1)].Texcoord = new Vector2((float)j / (xCount + 1), (float)i / (yCount + 1));
                }
            }
            texture = TextureLoader.TextureLoader.CreateTextureFromDDS(device, @"C:\Users\yulanli\Desktop\TerrainForm\colorMapDDS.DDS");
            //创建待绘制图形的顶点索引
            indices = new int[6 * xCount * yCount];
            for (int i = 0; i < yCount; i++)
            {
                for (int j = 0; j < xCount; j++)
                {
                    indices[6 * (j + i * xCount)]     = j + i * (xCount + 1);
                    indices[6 * (j + i * xCount) + 1] = j + (i + 1) * (xCount + 1);
                    indices[6 * (j + i * xCount) + 2] = j + i * (xCount + 1) + 1;
                    indices[6 * (j + i * xCount) + 3] = j + i * (xCount + 1) + 1;
                    indices[6 * (j + i * xCount) + 4] = j + (i + 1) * (xCount + 1);
                    indices[6 * (j + i * xCount) + 5] = j + (i + 1) * (xCount + 1) + 1;
                }
            }
            //创建视锥体
            //创建摄像机
            CamTarget = new Vector3(bitmap.Width / 2, 0f, bitmap.Height / 2);
            view      = Matrix.LookAtLH(
                CamPostion,     //摄像机原点
                CamTarget,      //摄像机观察目标点
                Vector3.UnitY); //当前世界的向上方向的向量,通常为(0,1,0),即这里的UnitY参数
            proj = Matrix.Identity;
            proj = Matrix.PerspectiveFovLH(
                (float)Math.PI / 4.0f, //用弧度制表示垂直视场角,这里是45°角
                aspectRatio,           //纵横比
                0.3f,                  //到近平面的距离
                500.0f                 //到远平面的距离
                );
            var worldViewProj = Matrix.Multiply(proj, view);

            //使用上传堆来传递顶点缓冲区的数据

            /*--------------------------------------------------*
            * 不推荐使用上传堆来传递像顶点缓冲区这样的静态数据 *
            * 这里使用上载堆是为了代码的简洁性,并且还因为需要 *
            * 传递的资源很少                                   *
            *--------------------------------------------------*/
            var vertexBufferSize = Utilities.SizeOf(vertices);
            vertexBuffer = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(vertexBufferSize),
                ResourceStates.GenericRead);

            //将顶点的数据复制到顶点缓冲区
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(
                pVertexDataBegin,
                vertices,
                0,
                vertices.Length);
            vertexBuffer.Unmap(0);

            //初始化顶点缓冲区视图
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes  = Utilities.SizeOf <PositionTextured>();
            vertexBufferView.SizeInBytes    = vertexBufferSize;


            //使用上传堆来传递索引缓冲区的数据
            int indexBufferSize = Utilities.SizeOf(indices);
            indexBuffer = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(indexBufferSize),
                ResourceStates.GenericRead);

            //将索引的数据复制到索引缓冲区
            IntPtr pIndexDataBegin = indexBuffer.Map(0);
            Utilities.Write(
                pIndexDataBegin,
                indices,
                0,
                indices.Length);
            indexBuffer.Unmap(0);

            //初始化索引缓冲区视图
            indexBufferView = new IndexBufferView();
            indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress;
            indexBufferView.SizeInBytes    = indexBufferSize;
            indexBufferView.Format         = Format.R32_UInt;

            //创建bundle
            bundle = device.CreateCommandList(
                0,
                CommandListType.Bundle,
                bundleAllocator,
                pipelineState);
            bundle.SetGraphicsRootSignature(rootSignature);
            bundle.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
            bundle.SetVertexBuffer(0, vertexBufferView);
            bundle.SetIndexBuffer(indexBufferView);

            //bundle.DrawInstanced(
            //   vertices.Length,//VertexCountPerInstance,要绘制的顶点数
            //    1,//InstanceCount,要绘制的实例数,这里是1个
            //    0,//StartVertexLocation,第一个顶点的索引,这里是0
            //    0);//StartInstanceLocation,在从顶点缓冲区读取每个实例数据之前添加到每个索引的值

            bundle.DrawIndexedInstanced(
                indices.Length, //IndexCountPerInstance,要绘制的索引数
                1,              //InstanceCount,要绘制的实例数,这里是1个
                0,              //StartIndexLocation,第一个顶点的索引,这里是0
                0,              //BaseVertexLocation,,从顶点缓冲区读取顶点之前添加到每个索引的值
                0);             //StartInstanceLocation,在从顶点缓冲区读取每个实例数据之前添加到每个索引的值
            bundle.Close();

            //使用上传堆来传递常量缓冲区的数据

            /*--------------------------------------------------*
            * 不推荐使用上传堆来传递像垂直缓冲区这样的静态数据 *
            * 这里使用上载堆是为了代码的简洁性,并且还因为需要 *
            * 传递的资源很少                                   *
            *--------------------------------------------------*/
            constantBuffer = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(1024 * 64),
                ResourceStates.GenericRead);

            //创建SRV视图
            var srvDesc = new ShaderResourceViewDescription();
            srvDesc.Texture2D.MostDetailedMip     = 0;
            srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
            device.CreateShaderResourceView(texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            //创建常量缓冲区视图(CBV)
            var cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBuffer>() + 255) & ~255
            };
            device.CreateConstantBufferView(
                cbvDesc,
                constantBufferViewHeap.CPUDescriptorHandleForHeapStart);

            //初始化并映射常量缓冲区

            /*--------------------------------------------------*
            * 直到应用程序关闭,我们才会取消映射,因此在资源的 *
            * 生命周期中保持映射是可以的                       *
            *------------------------------------------------- */
            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref worldViewProj);

            //创建同步对象
            //创建围栏
            fence = device.CreateFence(
                0,                //围栏的初始值
                FenceFlags.None); //指定围栏的类型,None表示没有指定的类型
            fenceValue = 1;
            //创建用于帧同步的事件句柄
            fenceEvent = new AutoResetEvent(false);
        }
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = int.MinValue, DescriptorCount = 1 } };
            RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges);

            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter });
            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

            #if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
            #endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                    new InputElement("POSITION",0,Format.R32G32B32_Float,0,0),
                    new InputElement("COLOR",0,Format.R32G32B32A32_Float,12,0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout = new InputLayoutDescription(inputElementDescs),
                RootSignature = rootSignature,
                VertexShader = vertexShader,
                PixelShader = pixelShader,
                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 = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                    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 ) },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // 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.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>();
            vertexBufferView.SizeInBytes = vertexBufferSize;

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes = (Utilities.SizeOf<ConstantBuffer>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc, constantBufferViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            // Create synchronization objects.
            fence = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);
        }
        private void LoadAssets()
        {
            // Create the root signature description.
            var rootSignatureDesc = new RootSignatureDescription(
                RootSignatureFlags.AllowInputAssemblerInputLayout,
                // Root Parameters
                new[]
                {
                    new RootParameter(ShaderVisibility.All,
                        new []
                        {
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ConstantBufferView,
                                DescriptorCount = 1,
                                OffsetInDescriptorsFromTableStart = 0,
                                BaseShaderRegister = 0
                            }
                        }),
                    new RootParameter(ShaderVisibility.All,
                        new RootConstants() {
                            ShaderRegister = 1,
                            Value32BitCount = 1
                        }),
                    new RootParameter(ShaderVisibility.All,
                        new []
                        {
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ShaderResourceView,
                                DescriptorCount = 2,
                                OffsetInDescriptorsFromTableStart = 0,
                                BaseShaderRegister = 0
                            }
                        }),
                    new RootParameter(ShaderVisibility.Pixel,
                        new DescriptorRange()
                        {
                            RangeType = DescriptorRangeType.Sampler,
                            DescriptorCount = 1,
                            OffsetInDescriptorsFromTableStart = 0,
                            BaseShaderRegister = 0
                        }),
                });

            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));

            // Define the vertex input layout.
            var inputElementDescs = new[]
            {
                    new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                    new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                    new InputElement("TANGENT", 0, Format.R32G32B32_Float, 24, 0),
                    new InputElement("BITANGENT", 0, Format.R32G32B32_Float, 36, 0),
                    new InputElement("DIFFUSE", 0, Format.R32G32B32_Float, 48, 0),
                    new InputElement("EMISSIVE", 0, Format.R32G32B32_Float, 64, 0),
                    new InputElement("SPECULAR", 0, Format.R32G32B32_Float, 80, 0),
                    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 96, 0)
            };

            CreatePSO(inputElementDescs, vertexShader, pixelShader);

            // build model resources
            BuildModelResources();

            // build depth buffer
            BuildDepthBuffer();

            CreateTerrainBind();
            BuildTerrainResouces();

            fence = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;
            fenceEvent = new AutoResetEvent(false);
        }
        private void CreateTerrainBind()
        {
            var rootSignatureDesc = new RootSignatureDescription(
               RootSignatureFlags.AllowInputAssemblerInputLayout,
               // Root Parameters
               new[]
               {
                   new RootParameter(ShaderVisibility.All,
                        new []
                        {
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ConstantBufferView,
                                DescriptorCount = 1,
                                OffsetInDescriptorsFromTableStart = 0,
                                BaseShaderRegister = 0
                            }
                        }),
                    new RootParameter(ShaderVisibility.All,
                        new []
                        {
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ShaderResourceView,
                                DescriptorCount = 2,
                                OffsetInDescriptorsFromTableStart = 0,
                                BaseShaderRegister = 0
                            }
                        }),
                    new RootParameter(ShaderVisibility.Pixel,
                        new DescriptorRange()
                        {
                            RangeType = DescriptorRangeType.Sampler,
                            DescriptorCount = 1,
                            OffsetInDescriptorsFromTableStart = 0,
                            BaseShaderRegister = 0
                        }),
               });

            terrainRootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());
            var inputElementDescs = new[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                    new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                    new InputElement("TANGENT", 0, Format.R32G32B32_Float, 24, 0),
                    new InputElement("BITANGENT", 0, Format.R32G32B32_Float, 36, 0),
                    new InputElement("DIFFUSE", 0, Format.R32G32B32_Float, 48, 0),
                    new InputElement("EMISSIVE", 0, Format.R32G32B32_Float, 64, 0),
                    new InputElement("SPECULAR", 0, Format.R32G32B32_Float, 80, 0),
                    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 96, 0)
            };
            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout = new InputLayoutDescription(inputElementDescs),
                RootSignature = terrainRootSignature,
                VertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../Terrain.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)),
                PixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../Terrain.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)),
                RasterizerState = RasterizerStateDescription.Default(),
                BlendState = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = true,
                    DepthComparison = Comparison.LessEqual,
                    DepthWriteMask = DepthWriteMask.All,
                    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;

            pipelineState2 = device.CreateGraphicsPipelineState(psoDesc);
        }
        private void LoadAssets()
        {
            // Create an empty root signature.
            var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout);
            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

            #if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
            #endif

            // Define the vertex input layout.
            var inputElementDescs = new []
            {
                    new InputElement("POSITION",0,Format.R32G32B32_Float,0,0),
                    new InputElement("COLOR",0,Format.R32G32B32A32_Float,12,0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout = new InputLayoutDescription(inputElementDescs),
                RootSignature = rootSignature,
                VertexShader = vertexShader,
                PixelShader = pixelShader,
                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 = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            var triangleVertices = new []
            {
                    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 ) },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // 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.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>();
            vertexBufferView.SizeInBytes = vertexBufferSize;

            // Create and record the bundle.
            bundle = device.CreateCommandList(0, CommandListType.Bundle, bundleAllocator, pipelineState);
            bundle.SetGraphicsRootSignature(rootSignature);
            bundle.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
            bundle.SetVertexBuffer(0, vertexBufferView);
            bundle.DrawInstanced(3, 1, 0, 0);
            bundle.Close();

            // Create synchronization objects.
            {
                fence = device.CreateFence(0, FenceFlags.None);
                fenceValue = 1;

                // Create an event handle to use for frame synchronization.
                fenceEvent = new AutoResetEvent(false);
            }
        }
Esempio n. 36
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
        }
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } };

            StaticSamplerDescription sampler = new StaticSamplerDescription()
            {
                Filter = Filter.MinimumMinMagMipPoint,
                AddressU = TextureAddressMode.Border,
                AddressV = TextureAddressMode.Border,
                AddressW = TextureAddressMode.Border,
                MipLODBias = 0,
                MaxAnisotropy = 0,
                ComparisonFunc = Comparison.Never,
                BorderColor = StaticBorderColor.TransparentBlack,
                MinLOD = 0.0f,
                MaxLOD = float.MaxValue,
                ShaderRegister = 0,
                RegisterSpace = 0,
                ShaderVisibility = ShaderVisibility.Pixel,
            };

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges) };

            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler });
            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

            #if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
            #endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                    new InputElement("POSITION",0,Format.R32G32B32_Float,0,0),
                    new InputElement("TEXCOORD",0,Format.R32G32_Float,12,0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout = new InputLayoutDescription(inputElementDescs),
                RootSignature = rootSignature,
                VertexShader = vertexShader,
                PixelShader = pixelShader,
                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 = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                    new Vertex() {position=new Vector3(0.0f, 0.25f * aspectRatio, 0.0f ),uv=new Vector2(0.5f, 0.0f) },
                    new Vertex() {position=new Vector3(0.25f, -0.25f * aspectRatio, 0.0f),uv=new Vector2(1.0f, 1.0f) },
                    new Vertex() {position=new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f),uv=new Vector2(0.0f, 1.0f) },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // 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.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>();
            vertexBufferView.SizeInBytes = vertexBufferSize;

            Resource textureUploadHeap;

            // Create the texture.
            // Describe and create a Texture2D.
            ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1);

            // Create the GPU upload buffer.
            textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, TexturePixelSize * TextureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
            };
            srvDesc.Texture2D.MipLevels = 1;

            device.CreateShaderResourceView(this.texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            commandQueue.ExecuteCommandList(commandList);

            // Create synchronization objects.
            fence = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);

            WaitForPreviousFrame();

            //release temp texture
            textureUploadHeap.Dispose();
        }
        private void LoadAssets()
        {
            // Create the root signature description.
            var rootSignatureDesc = new RootSignatureDescription(

                RootSignatureFlags.AllowInputAssemblerInputLayout,
                // Root Parameters
                new[]
                {
                    new RootParameter(ShaderVisibility.All,
                        new []
                        {
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ShaderResourceView,
                                DescriptorCount = 1,
                                OffsetInDescriptorsFromTableStart = int.MinValue,
                                BaseShaderRegister = 0
                            },
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ConstantBufferView,
                                DescriptorCount = 1,
                                OffsetInDescriptorsFromTableStart = int.MinValue + 1,
                                BaseShaderRegister = 0
                            }
                        }),
                    new RootParameter(ShaderVisibility.Pixel,
                        new DescriptorRange()
                        {
                            RangeType = DescriptorRangeType.Sampler,
                            DescriptorCount = 1,
                            OffsetInDescriptorsFromTableStart = int.MinValue,
                            BaseShaderRegister = 0
                        }),
                });
                //// Samplers
                //new[]
                //{
                //    new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0)
                //    {
                //        Filter = Filter.MinimumMinMagMipPoint,
                //        AddressUVW = TextureAddressMode.Border,
                //    }
                //});

            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

            #if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
            #endif

            #if DEBUG
            //var result = SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "GSMain", "gs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug);
            var geometryShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "GSMain", "gs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
            #endif

            // Define the vertex input layout.
            var inputElementDescs = new[]
            {
                    new InputElement("POSITION",0,Format.R32G32B32_Float,0,0),
                    new InputElement("TEXCOORD",0,Format.R32G32_Float,12,0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout = new InputLayoutDescription(inputElementDescs),
                RootSignature = rootSignature,
                VertexShader = vertexShader,
                GeometryShader = geometryShader,
                PixelShader = pixelShader,
                RasterizerState = RasterizerStateDescription.Default(),
                BlendState = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = true,
                    DepthComparison = Comparison.LessEqual,
                    DepthWriteMask = DepthWriteMask.All,
                    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 = device.CreateGraphicsPipelineState(psoDesc);

            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);
            commandList.Close();

            // build vertex buffer

            var triangleVertices = new[]
            {
                //TOP
                new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                //BOTTOM
                new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                //LEFT
                new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,1f)} ,
                //RIGHT
                new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,1f)} ,
                //FRONT
                new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                //BACK
                new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,1f)}
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>();
            vertexBufferView.SizeInBytes = vertexBufferSize;

            // build index buffer

            var triangleIndexes = new uint[]
            {
                0,1,2,
                0,2,3,

                4,6,5,
                4,7,6,

                8,9,10,
                8,10,11,

                12,14,13,
                12,15,14,

                16,18,17,
                16,19,18,

                20,21,22,
                20,22,23
            };

            int indexBufferSize = Utilities.SizeOf(triangleIndexes);

            indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead);
            IntPtr pIndexDataBegin = indexBuffer.Map(0);
            Utilities.Write(pIndexDataBegin, triangleIndexes, 0, triangleIndexes.Length);
            indexBuffer.Unmap(0);

            indexBufferView = new IndexBufferView();
            indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress;
            indexBufferView.SizeInBytes = indexBufferSize;
            indexBufferView.Format = Format.R32_UInt;

            // Create the texture.
            // Describe and create a Texture2D.
            var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, textureDesc, ResourceStates.GenericRead, null);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = Utilities.ReadStream(new FileStream("../../texture1.dds", FileMode.Open));

            texture.Name = "Texture";

            var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            texture.WriteToSubresource(0, null, ptr, TextureWidth * 4, textureData.Length);
            handle.Free();

            // Describe and create a SRV for the texture.
            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) |(((1) & 0x7) << 3) |(((2) & 0x7) << (3 * 2)) |(((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),

                Format = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels = 1,
                    MostDetailedMip = 0,
                    PlaneSlice = 0,
                    ResourceMinLODClamp = 0.0f
                },
            };

            device.CreateShaderResourceView(texture, srvDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart);

            SamplerStateDescription samplerDesc = new SamplerStateDescription
            {
                Filter = Filter.MinMagMipLinear,
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
                MaximumAnisotropy = 0,
                MaximumLod = float.MaxValue,
                MinimumLod = -float.MaxValue,
                MipLodBias = 0,
                ComparisonFunction = Comparison.Never
            };

            device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart);

            // build constant buffer

            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            var cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes = (Utilities.SizeOf<ConstantBufferData>() + 255) & ~255
            };
            var srvCbvStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            device.CreateConstantBufferView(cbDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart + srvCbvStep);

            constantBufferData = new ConstantBufferData
            {
                Project = Matrix.Identity
            };

            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            // build depth buffer

            DescriptorHeapDescription descDescriptorHeapDSB = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Type = DescriptorHeapType.DepthStencilView,
                Flags = DescriptorHeapFlags.None
            };

            DescriptorHeap descriptorHeapDSB = device.CreateDescriptorHeap(descDescriptorHeapDSB);
            ResourceDescription descDepth = new ResourceDescription()
            {
                Dimension = ResourceDimension.Texture2D,
                DepthOrArraySize = 1,
                MipLevels = 0,
                Flags = ResourceFlags.AllowDepthStencil,
                Width = (int)viewport.Width,
                Height = (int)viewport.Height,
                Format = Format.R32_Typeless,
                Layout = TextureLayout.Unknown,
                SampleDescription = new SampleDescription() { Count = 1 }
            };

            ClearValue dsvClearValue = new ClearValue()
            {
                Format = Format.D32_Float,
                DepthStencil = new DepthStencilValue()
                {
                    Depth = 1.0f,
                    Stencil = 0
                }
            };

            Resource renderTargetDepth = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, descDepth, ResourceStates.GenericRead, dsvClearValue);

            DepthStencilViewDescription depthDSV = new DepthStencilViewDescription()
            {
                Dimension = DepthStencilViewDimension.Texture2D,
                Format = Format.D32_Float,
                Texture2D = new DepthStencilViewDescription.Texture2DResource()
                {
                    MipSlice = 0
                }
            };

            device.CreateDepthStencilView(renderTargetDepth, depthDSV, descriptorHeapDSB.CPUDescriptorHandleForHeapStart);
            handleDSV = descriptorHeapDSB.CPUDescriptorHandleForHeapStart;

            fence = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;
            fenceEvent = new AutoResetEvent(false);
        }