public ID3D12PipelineState LoadComputePipeline(string name, ComputePipelineStateDescription description) { Guard.NotNullOrEmpty(name, nameof(name)); Guard.NotNull(description, nameof(description)); return(LoadComputePipeline(name, description, typeof(ID3D12PipelineState).GUID)); }
ComputePipelineState makeCompute(ResourceCreateContext ctx) { var code = UniqueCreator.Graphics.Gpu.Shaders.compute_cs.Factory.Create(); var description = new ComputePipelineStateDescription(); description.CS = code; return(new ComputePipelineState(m_ctx, description)); }
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)); }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat, StreamOutput = new StreamOutputDescription() //find out how this should actually be done later }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for transparent objects. // GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy(); var transparencyBlendDesc = new RenderTargetBlendDescription { IsBlendEnabled = true, LogicOpEnable = false, SourceBlend = BlendOption.SourceAlpha, DestinationBlend = BlendOption.InverseSourceAlpha, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, LogicOp = LogicOperation.Noop, RenderTargetWriteMask = ColorWriteMaskFlags.All }; transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc; _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc); // // PSO for alpha tested objects. // GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy(); alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"]; alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None; _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc); // // PSO for drawing waves. // GraphicsPipelineStateDescription wavesRenderPSO = transparentPsoDesc.Copy(); wavesRenderPSO.VertexShader = _shaders["wavesVS"]; _psos["wavesRender"] = Device.CreateGraphicsPipelineState(wavesRenderPSO); // // PSO for compositing post process. // GraphicsPipelineStateDescription compositePSO = opaquePsoDesc.Copy(); compositePSO.RootSignature = _postProcessRootSignature; // Disable depth test. compositePSO.DepthStencilState.IsDepthEnabled = false; compositePSO.DepthStencilState.DepthWriteMask = DepthWriteMask.Zero; compositePSO.DepthStencilState.DepthComparison = Comparison.Always; compositePSO.VertexShader = _shaders["compositeVS"]; compositePSO.PixelShader = _shaders["compositePS"]; _psos["composite"] = Device.CreateGraphicsPipelineState(compositePSO); // // PSO for disturbing waves. // var wavesDisturbPSO = new ComputePipelineStateDescription { RootSignaturePointer = _wavesRootSignature, ComputeShader = _shaders["wavesDisturbCS"], Flags = PipelineStateFlags.None }; _psos["wavesDisturb"] = Device.CreateComputePipelineState(wavesDisturbPSO); // // PSO for updating waves. // var wavesUpdatePSO = new ComputePipelineStateDescription { RootSignaturePointer = _wavesRootSignature, ComputeShader = _shaders["wavesUpdateCS"], Flags = PipelineStateFlags.None }; _psos["wavesUpdate"] = Device.CreateComputePipelineState(wavesUpdatePSO); // // PSO for sobel. // var sobelPSO = new ComputePipelineStateDescription { RootSignaturePointer = _postProcessRootSignature, ComputeShader = _shaders["sobelCS"], Flags = PipelineStateFlags.None }; _psos["sobel"] = Device.CreateComputePipelineState(sobelPSO); }
internal void Prepare(PipelineStateDescription pipelineStateDescription) { if (pipelineStateDescription.RootSignature != null) { var effectReflection = pipelineStateDescription.EffectBytecode.Reflection; var computeShader = pipelineStateDescription.EffectBytecode.Stages.FirstOrDefault(e => e.Stage == ShaderStage.Compute); IsCompute = computeShader != null; var rootSignatureParameters = new List <RootParameter>(); var immutableSamplers = new List <StaticSamplerDescription>(); SrvBindCounts = new int[pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts.Count]; SamplerBindCounts = new int[pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts.Count]; for (int layoutIndex = 0; layoutIndex < pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts.Count; layoutIndex++) { var layout = pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts[layoutIndex]; if (layout.Layout == null) { continue; } // TODO D3D12 for now, we don't control register so we simply generate one resource table per shader stage and per descriptor set layout // we should switch to a model where we make sure VS/PS don't overlap for common descriptors so that they can be shared var srvDescriptorRanges = new Dictionary <ShaderStage, List <DescriptorRange> >(); var samplerDescriptorRanges = new Dictionary <ShaderStage, List <DescriptorRange> >(); int descriptorSrvOffset = 0; int descriptorSamplerOffset = 0; foreach (var item in layout.Layout.Entries) { var isSampler = item.Class == EffectParameterClass.Sampler; // Find matching resource bindings foreach (var binding in effectReflection.ResourceBindings) { if (binding.Stage == ShaderStage.None || binding.KeyInfo.Key != item.Key) { continue; } List <DescriptorRange> descriptorRanges; { var dictionary = isSampler ? samplerDescriptorRanges : srvDescriptorRanges; if (dictionary.TryGetValue(binding.Stage, out descriptorRanges) == false) { descriptorRanges = dictionary[binding.Stage] = new List <DescriptorRange>(); } } if (isSampler) { if (item.ImmutableSampler != null) { immutableSamplers.Add(new StaticSamplerDescription(ShaderStage2ShaderVisibility(binding.Stage), binding.SlotStart, 0) { // TODO D3D12 ImmutableSampler should only be a state description instead of a GPU object? Filter = (Filter)item.ImmutableSampler.Description.Filter, ComparisonFunc = (Comparison)item.ImmutableSampler.Description.CompareFunction, BorderColor = ColorHelper.ConvertStatic(item.ImmutableSampler.Description.BorderColor), AddressU = (SharpDX.Direct3D12.TextureAddressMode)item.ImmutableSampler.Description.AddressU, AddressV = (SharpDX.Direct3D12.TextureAddressMode)item.ImmutableSampler.Description.AddressV, AddressW = (SharpDX.Direct3D12.TextureAddressMode)item.ImmutableSampler.Description.AddressW, MinLOD = item.ImmutableSampler.Description.MinMipLevel, MaxLOD = item.ImmutableSampler.Description.MaxMipLevel, MipLODBias = item.ImmutableSampler.Description.MipMapLevelOfDetailBias, MaxAnisotropy = item.ImmutableSampler.Description.MaxAnisotropy, }); } else { // Add descriptor range descriptorRanges.Add(new DescriptorRange(DescriptorRangeType.Sampler, item.ArraySize, binding.SlotStart, 0, descriptorSamplerOffset)); } } else { DescriptorRangeType descriptorRangeType; switch (binding.Class) { case EffectParameterClass.ConstantBuffer: descriptorRangeType = DescriptorRangeType.ConstantBufferView; break; case EffectParameterClass.ShaderResourceView: descriptorRangeType = DescriptorRangeType.ShaderResourceView; break; case EffectParameterClass.UnorderedAccessView: descriptorRangeType = DescriptorRangeType.UnorderedAccessView; break; default: throw new NotImplementedException(); } // Add descriptor range descriptorRanges.Add(new DescriptorRange(descriptorRangeType, item.ArraySize, binding.SlotStart, 0, descriptorSrvOffset)); } } // Move to next element (mirror what is done in DescriptorSetLayout) if (isSampler) { if (item.ImmutableSampler == null) { descriptorSamplerOffset += item.ArraySize; } } else { descriptorSrvOffset += item.ArraySize; } } foreach (var stage in srvDescriptorRanges) { if (stage.Value.Count > 0) { rootSignatureParameters.Add(new RootParameter(ShaderStage2ShaderVisibility(stage.Key), stage.Value.ToArray())); SrvBindCounts[layoutIndex]++; } } foreach (var stage in samplerDescriptorRanges) { if (stage.Value.Count > 0) { rootSignatureParameters.Add(new RootParameter(ShaderStage2ShaderVisibility(stage.Key), stage.Value.ToArray())); SamplerBindCounts[layoutIndex]++; } } } var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootSignatureParameters.ToArray(), immutableSamplers.ToArray()); var rootSignature = NativeDevice.CreateRootSignature(0, rootSignatureDesc.Serialize()); InputElement[] inputElements = null; if (pipelineStateDescription.InputElements != null) { inputElements = new InputElement[pipelineStateDescription.InputElements.Length]; for (int i = 0; i < inputElements.Length; ++i) { var inputElement = pipelineStateDescription.InputElements[i]; inputElements[i] = new InputElement { Format = (SharpDX.DXGI.Format)inputElement.Format, AlignedByteOffset = inputElement.AlignedByteOffset, SemanticName = inputElement.SemanticName, SemanticIndex = inputElement.SemanticIndex, Slot = inputElement.InputSlot, Classification = (SharpDX.Direct3D12.InputClassification)inputElement.InputSlotClass, InstanceDataStepRate = inputElement.InstanceDataStepRate, }; } } PrimitiveTopologyType primitiveTopologyType; switch (pipelineStateDescription.PrimitiveType) { case PrimitiveType.Undefined: primitiveTopologyType = PrimitiveTopologyType.Undefined; break; case PrimitiveType.PointList: primitiveTopologyType = PrimitiveTopologyType.Point; break; case PrimitiveType.LineList: case PrimitiveType.LineStrip: case PrimitiveType.LineListWithAdjacency: case PrimitiveType.LineStripWithAdjacency: primitiveTopologyType = PrimitiveTopologyType.Line; break; case PrimitiveType.TriangleList: case PrimitiveType.TriangleStrip: case PrimitiveType.TriangleListWithAdjacency: case PrimitiveType.TriangleStripWithAdjacency: primitiveTopologyType = PrimitiveTopologyType.Triangle; break; default: if (pipelineStateDescription.PrimitiveType >= PrimitiveType.PatchList && pipelineStateDescription.PrimitiveType < PrimitiveType.PatchList + 32) { primitiveTopologyType = PrimitiveTopologyType.Patch; } else { throw new ArgumentOutOfRangeException("pipelineStateDescription.PrimitiveType"); } break; } // Check if it should use compute pipeline state if (IsCompute) { var nativePipelineStateDescription = new ComputePipelineStateDescription { ComputeShader = computeShader.Data, Flags = PipelineStateFlags.None, RootSignaturePointer = rootSignature, }; CompiledState = NativeDevice.CreateComputePipelineState(nativePipelineStateDescription); } else { var nativePipelineStateDescription = new GraphicsPipelineStateDescription { InputLayout = new InputLayoutDescription(inputElements), RootSignature = rootSignature, RasterizerState = CreateRasterizerState(pipelineStateDescription.RasterizerState), BlendState = CreateBlendState(pipelineStateDescription.BlendState), SampleMask = (int)pipelineStateDescription.SampleMask, DepthStencilFormat = (SharpDX.DXGI.Format)pipelineStateDescription.Output.DepthStencilFormat, DepthStencilState = CreateDepthStencilState(pipelineStateDescription.DepthStencilState), RenderTargetCount = pipelineStateDescription.Output.RenderTargetCount, // TODO D3D12 hardcoded StreamOutput = new StreamOutputDescription(), PrimitiveTopologyType = primitiveTopologyType, // TODO D3D12 hardcoded SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }; // Disable depth buffer if no format specified if (nativePipelineStateDescription.DepthStencilFormat == Format.Unknown) nativePipelineStateDescription.DepthStencilState.IsDepthEnabled = false; fixed(PixelFormat *renderTargetFormats = &pipelineStateDescription.Output.RenderTargetFormat0) { for (int i = 0; i < pipelineStateDescription.Output.RenderTargetCount; ++i) { nativePipelineStateDescription.RenderTargetFormats[i] = (SharpDX.DXGI.Format)renderTargetFormats[i]; } } foreach (var stage in pipelineStateDescription.EffectBytecode.Stages) { switch (stage.Stage) { case ShaderStage.Vertex: nativePipelineStateDescription.VertexShader = stage.Data; break; case ShaderStage.Hull: nativePipelineStateDescription.HullShader = stage.Data; break; case ShaderStage.Domain: nativePipelineStateDescription.DomainShader = stage.Data; break; case ShaderStage.Geometry: nativePipelineStateDescription.GeometryShader = stage.Data; break; case ShaderStage.Pixel: nativePipelineStateDescription.PixelShader = stage.Data; break; default: throw new ArgumentOutOfRangeException(); } } CompiledState = NativeDevice.CreateGraphicsPipelineState(nativePipelineStateDescription); } RootSignature = rootSignature; PrimitiveTopology = (PrimitiveTopology)pipelineStateDescription.PrimitiveType; HasScissorEnabled = pipelineStateDescription.RasterizerState.ScissorTestEnable; } }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for transparent objects. // GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy(); var transparencyBlendDesc = new RenderTargetBlendDescription { IsBlendEnabled = true, LogicOpEnable = false, // TODO: rename to IsLogicOpEnabled SourceBlend = BlendOption.SourceAlpha, DestinationBlend = BlendOption.InverseSourceAlpha, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, LogicOp = LogicOperation.Noop, RenderTargetWriteMask = ColorWriteMaskFlags.All }; transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc; _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc); // // PSO for alpha tested objects. // GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy(); alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"]; alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None; _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc); // // PSO for horizontal blur. // var horzBlurPso = new ComputePipelineStateDescription { RootSignature = _postProcessRootSignature, ComputeShader = _shaders["horzBlurCS"], Flags = PipelineStateFlags.None }; _psos["horzBlur"] = Device.CreateComputePipelineState(horzBlurPso); // // PSO for vertical blur. // var vertBlurPso = new ComputePipelineStateDescription { RootSignature = _postProcessRootSignature, ComputeShader = _shaders["vertBlurCS"], Flags = PipelineStateFlags.None }; _psos["vertBlur"] = Device.CreateComputePipelineState(vertBlurPso); }
internal PipelineState(GraphicsDevice device, RootSignature rootSignature, ComputePipelineStateDescription pipelineStateDescription) { IsCompute = true; RootSignature = rootSignature; NativePipelineState = device.NativeDevice.CreateComputePipelineState(pipelineStateDescription); }
public ID3D12PipelineState LoadComputePipeline(string name, ComputePipelineStateDescription description) { return(LoadComputePipeline(name, description, typeof(ID3D12PipelineState).GUID)); }
public PipelineState(GraphicsDevice device, ComputePipelineStateDescription pipelineStateDescription) { IsCompute = true; RootSignature = pipelineStateDescription.RootSignature; NativePipelineState = device.NativeDevice.CreateComputePipelineState(pipelineStateDescription); }