Exemplo n.º 1
0
 public void SetBlendFactor(Color4 blendFactor)
 {
     NativeCommandList.BlendFactor = ColorHelper.ConvertToVector4(blendFactor);
 }
        internal unsafe PipelineState(GraphicsDevice graphicsDevice, PipelineStateDescription pipelineStateDescription) : base(graphicsDevice)
        {
            if (pipelineStateDescription.RootSignature != null)
            {
                var effectReflection = pipelineStateDescription.EffectBytecode.Reflection;

                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 srvDescriptorRangesVS     = new List <DescriptorRange>();
                    var srvDescriptorRangesPS     = new List <DescriptorRange>();
                    var samplerDescriptorRangesVS = new List <DescriptorRange>();
                    var samplerDescriptorRangesPS = new 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;
                            switch (binding.Stage)
                            {
                            case ShaderStage.Vertex:
                                descriptorRanges = isSampler ? samplerDescriptorRangesVS : srvDescriptorRangesVS;
                                break;

                            case ShaderStage.Pixel:
                                descriptorRanges = isSampler ? samplerDescriptorRangesPS : srvDescriptorRangesPS;
                                break;

                            default:
                                throw new NotImplementedException();
                            }

                            if (isSampler)
                            {
                                if (item.ImmutableSampler != null)
                                {
                                    immutableSamplers.Add(new StaticSamplerDescription((ShaderVisibility)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;
                        }
                    }
                    if (srvDescriptorRangesVS.Count > 0)
                    {
                        rootSignatureParameters.Add(new RootParameter(ShaderVisibility.Vertex, srvDescriptorRangesVS.ToArray()));
                        SrvBindCounts[layoutIndex]++;
                    }
                    if (srvDescriptorRangesPS.Count > 0)
                    {
                        rootSignatureParameters.Add(new RootParameter(ShaderVisibility.Pixel, srvDescriptorRangesPS.ToArray()));
                        SrvBindCounts[layoutIndex]++;
                    }
                    if (samplerDescriptorRangesVS.Count > 0)
                    {
                        rootSignatureParameters.Add(new RootParameter(ShaderVisibility.Vertex, samplerDescriptorRangesVS.ToArray()));
                        SamplerBindCounts[layoutIndex]++;
                    }
                    if (samplerDescriptorRangesPS.Count > 0)
                    {
                        rootSignatureParameters.Add(new RootParameter(ShaderVisibility.Pixel, samplerDescriptorRangesPS.ToArray()));
                        SamplerBindCounts[layoutIndex]++;
                    }
                }
                var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootSignatureParameters.ToArray(), immutableSamplers.ToArray());

                var rootSignature = NativeDevice.CreateRootSignature(0, rootSignatureDesc.Serialize());

                var 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:
                    throw new ArgumentOutOfRangeException();

                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;
                }

                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),
                };

                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;
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Set the blend state of the output-merger stage. See <see cref="Render+states"/> to learn how to use it.
 /// </summary>
 /// <param name="blendState">a blend-state</param>
 /// <param name="blendFactor">Blend factors, one for each RGBA component. This requires a blend state object that specifies the <see cref="Blend.BlendFactor" /></param>
 /// <param name="multiSampleMask">32-bit sample coverage. The default value is 0xffffffff.</param>
 private void SetBlendStateImpl(BlendState blendState, Color4 blendFactor, int multiSampleMask = -1)
 {
     if (blendState == null)
     {
         NativeDeviceContext.OutputMerger.SetBlendState(null, ColorHelper.Convert(blendFactor), multiSampleMask);
     }
     else
     {
         NativeDeviceContext.OutputMerger.SetBlendState((SharpDX.Direct3D11.BlendState)blendState.NativeDeviceChild, ColorHelper.Convert(blendFactor), multiSampleMask);
     }
 }
Exemplo n.º 4
0
 public void SetBlendFactor(Color4 blendFactor)
 {
     nativeDeviceContext.OutputMerger.BlendFactor = ColorHelper.Convert(blendFactor);
 }