private void CreateShaders(DevicePipelineStateCache pipelineStateCache)
        {
            if (effectBytecode == null)
            {
                return;
            }

            foreach (var shaderBytecode in effectBytecode.Stages)
            {
                var reflection = effectBytecode.Reflection;

                // TODO CACHE Shaders with a bytecode hash
                switch (shaderBytecode.Stage)
                {
                case ShaderStage.Vertex:
                    vertexShader = pipelineStateCache.VertexShaderCache.Instantiate(shaderBytecode);
                    // Note: input signature can be reused when reseting device since it only stores non-GPU data,
                    // so just keep it if it has already been created before.
                    if (inputSignature == null)
                    {
                        inputSignature = shaderBytecode;
                    }
                    break;

                case ShaderStage.Domain:
                    domainShader = pipelineStateCache.DomainShaderCache.Instantiate(shaderBytecode);
                    break;

                case ShaderStage.Hull:
                    hullShader = pipelineStateCache.HullShaderCache.Instantiate(shaderBytecode);
                    break;

                case ShaderStage.Geometry:
                    if (reflection.ShaderStreamOutputDeclarations != null && reflection.ShaderStreamOutputDeclarations.Count > 0)
                    {
                        // Calculate the strides
                        var soStrides = new List <int>();
                        foreach (var streamOutputElement in reflection.ShaderStreamOutputDeclarations)
                        {
                            for (int i = soStrides.Count; i < (streamOutputElement.Stream + 1); i++)
                            {
                                soStrides.Add(0);
                            }

                            soStrides[streamOutputElement.Stream] += streamOutputElement.ComponentCount * sizeof(float);
                        }
                        var soElements = new SharpDX.Direct3D11.StreamOutputElement[0];     // TODO CREATE StreamOutputElement from bytecode.Reflection.ShaderStreamOutputDeclarations
                        // TODO GRAPHICS REFACTOR better cache
                        geometryShader = new SharpDX.Direct3D11.GeometryShader(GraphicsDevice.NativeDevice, shaderBytecode, soElements, soStrides.ToArray(), reflection.StreamOutputRasterizedStream);
                    }
                    else
                    {
                        geometryShader = pipelineStateCache.GeometryShaderCache.Instantiate(shaderBytecode);
                    }
                    break;

                case ShaderStage.Pixel:
                    pixelShader = pipelineStateCache.PixelShaderCache.Instantiate(shaderBytecode);
                    break;

                case ShaderStage.Compute:
                    computeShader = pipelineStateCache.ComputeShaderCache.Instantiate(shaderBytecode);
                    break;
                }
            }
        }
Beispiel #2
0
        private void CreateShaders(DevicePipelineStateCache pipelineStateCache)
        {
            if (effectBytecode == null)
            {
                return;
            }

            foreach (var shaderBytecode in effectBytecode.Stages)
            {
                var reflection = effectBytecode.Reflection;

                // TODO CACHE Shaders with a bytecode hash
                switch (shaderBytecode.Stage)
                {
                case ShaderStage.Vertex:
                    vertexShader = pipelineStateCache.VertexShaderCache.Instantiate(shaderBytecode);
                    // Note: input signature can be reused when reseting device since it only stores non-GPU data,
                    // so just keep it if it has already been created before.
                    if (inputSignature == null)
                    {
                        inputSignature = shaderBytecode;
                    }
                    break;

                case ShaderStage.Domain:
                    domainShader = pipelineStateCache.DomainShaderCache.Instantiate(shaderBytecode);
                    break;

                case ShaderStage.Hull:
                    hullShader = pipelineStateCache.HullShaderCache.Instantiate(shaderBytecode);
                    break;

                case ShaderStage.Geometry:
                    if (reflection.ShaderStreamOutputDeclarations != null && reflection.ShaderStreamOutputDeclarations.Count > 0)
                    {
                        // stream out elements
                        var soElements = new List <SharpDX.Direct3D11.StreamOutputElement>();
                        foreach (var streamOutputElement in reflection.ShaderStreamOutputDeclarations)
                        {
                            var soElem = new SharpDX.Direct3D11.StreamOutputElement()
                            {
                                Stream         = streamOutputElement.Stream,
                                SemanticIndex  = streamOutputElement.SemanticIndex,
                                SemanticName   = streamOutputElement.SemanticName,
                                StartComponent = streamOutputElement.StartComponent,
                                ComponentCount = streamOutputElement.ComponentCount,
                                OutputSlot     = streamOutputElement.OutputSlot
                            };
                            soElements.Add(soElem);
                        }
                        // TODO GRAPHICS REFACTOR better cache
                        geometryShader = new SharpDX.Direct3D11.GeometryShader(GraphicsDevice.NativeDevice, shaderBytecode, soElements.ToArray(), reflection.StreamOutputStrides, reflection.StreamOutputRasterizedStream);
                    }
                    else
                    {
                        geometryShader = pipelineStateCache.GeometryShaderCache.Instantiate(shaderBytecode);
                    }
                    break;

                case ShaderStage.Pixel:
                    pixelShader = pipelineStateCache.PixelShaderCache.Instantiate(shaderBytecode);
                    break;

                case ShaderStage.Compute:
                    computeShader = pipelineStateCache.ComputeShaderCache.Instantiate(shaderBytecode);
                    break;
                }
            }
        }