Exemple #1
0
        public static PipelineState New(GraphicsDevice graphicsDevice, ref PipelineStateDescription pipelineStateDescription)
        {
            PipelineState pipelineState = null;

            // Hash the current state
            var hashedState = new PipelineStateDescriptionWithHash(pipelineStateDescription);

            // check if it is in the cache, or being worked on...
            bool foundInCache = false;

            lock (graphicsDevice.CachedPipelineStates) {
                foundInCache = graphicsDevice.CachedPipelineStates.TryGetValue(hashedState, out pipelineState);
                if (!foundInCache)
                {
                    pipelineState = new PipelineState(graphicsDevice); // mark we will work on this pipeline (which is just blank right now)
                    graphicsDevice.CachedPipelineStates[hashedState] = pipelineState;
                }
            }

            // if we have this cached, wait until it is ready to return
            if (foundInCache)
            {
                pipelineState.AddReferenceInternal();
                return(pipelineState);
            }

            if (GraphicsDevice.Platform == GraphicsPlatform.Vulkan)
            {
                // if we are using Vulkan, just make a new pipeline without locking
                pipelineState.Prepare(pipelineStateDescription);
            }
            else
            {
                // D3D seems to have quite bad concurrency when using CreateSampler while rendering
                lock (graphicsDevice.CachedPipelineStates) {
                    pipelineState.Prepare(pipelineStateDescription);
                }
            }

            return(pipelineState);
        }
        /// <summary>
        /// Determine and updates <see cref="CurrentState"/> from <see cref="State"/>.
        /// </summary>
        public void Update()
        {
            // Hash current state
            var hashedState = new PipelineStateDescriptionWithHash(State);

            // Find existing PipelineState object
            PipelineState pipelineState;

            // TODO GRAPHICS REFACTOR We could avoid lock by adding them to a ThreadLocal (or RenderContext) and merge at end of frame
            lock (cache)
            {
                if (!cache.TryGetValue(hashedState, out pipelineState))
                {
                    // Otherwise, instantiate it
                    // First, make an copy
                    hashedState = new PipelineStateDescriptionWithHash(State.Clone());
                    cache.Add(hashedState, pipelineState = PipelineState.New(graphicsDevice, ref State));
                }
            }

            CurrentState = pipelineState;
        }
Exemple #3
0
        public static PipelineState New(GraphicsDevice graphicsDevice, ref PipelineStateDescription pipelineStateDescription)
        {
            // Hash the current state
            var hashedState = new PipelineStateDescriptionWithHash(pipelineStateDescription);

            // Store SamplerState in a cache (D3D seems to have quite bad concurrency when using CreateSampler while rendering)
            PipelineState pipelineState;

            lock (graphicsDevice.CachedPipelineStates)
            {
                if (graphicsDevice.CachedPipelineStates.TryGetValue(hashedState, out pipelineState))
                {
                    // TODO: Appropriate destroy
                    pipelineState.AddReferenceInternal();
                }
                else
                {
                    pipelineState = new PipelineState(graphicsDevice, pipelineStateDescription);
                    graphicsDevice.CachedPipelineStates.Add(hashedState, pipelineState);
                }
            }
            return(pipelineState);
        }
Exemple #4
0
        private void ClearStateImpl()
        {
            NativeDeviceContext.ClearState();

            for (int i = 0; i < samplerStates.Length; ++i)
            {
                samplerStates[i] = null;
            }
            for (int i = 0; i < constantBuffers.Length; ++i)
            {
                constantBuffers[i] = null;
            }
            for (int i = 0; i < unorderedAccessViews.Length; ++i)
            {
                unorderedAccessViews[i] = null;
            }
            for (int i = 0; i < currentRenderTargetViews.Length; i++)
            {
                currentRenderTargetViews[i] = null;
            }

            // Since nothing can be drawn in default state, no need to set anything (another SetPipelineState should happen before)
            currentPipelineState = GraphicsDevice.DefaultPipelineState;
        }
        internal void Apply(CommandList commandList, PipelineState previousPipeline)
        {
            var nativeDeviceContext = commandList.NativeDeviceContext;

            if (rootSignature != previousPipeline.rootSignature)
            {
                //rootSignature.Apply
            }

            if (effectBytecode != previousPipeline.effectBytecode)
            {
                if (computeShader != null)
                {
                    if (computeShader != previousPipeline.computeShader)
                    {
                        nativeDeviceContext.ComputeShader.Set(computeShader);
                    }
                }
                else
                {
                    if (vertexShader != previousPipeline.vertexShader)
                    {
                        nativeDeviceContext.VertexShader.Set(vertexShader);
                    }
                    if (pixelShader != previousPipeline.pixelShader)
                    {
                        nativeDeviceContext.PixelShader.Set(pixelShader);
                    }
                    if (hullShader != previousPipeline.hullShader)
                    {
                        nativeDeviceContext.HullShader.Set(hullShader);
                    }
                    if (domainShader != previousPipeline.domainShader)
                    {
                        nativeDeviceContext.DomainShader.Set(domainShader);
                    }
                    if (geometryShader != previousPipeline.geometryShader)
                    {
                        nativeDeviceContext.GeometryShader.Set(geometryShader);
                    }
                }
            }

            if (blendState != previousPipeline.blendState || sampleMask != previousPipeline.sampleMask)
            {
                nativeDeviceContext.OutputMerger.SetBlendState(blendState, nativeDeviceContext.OutputMerger.BlendFactor, sampleMask);
            }

            if (rasterizerState != previousPipeline.rasterizerState)
            {
                nativeDeviceContext.Rasterizer.State = rasterizerState;
            }

            if (depthStencilState != previousPipeline.depthStencilState)
            {
                nativeDeviceContext.OutputMerger.DepthStencilState = depthStencilState;
            }

            if (inputLayout != previousPipeline.inputLayout)
            {
                nativeDeviceContext.InputAssembler.InputLayout = inputLayout;
            }

            if (primitiveTopology != previousPipeline.primitiveTopology)
            {
                nativeDeviceContext.InputAssembler.PrimitiveTopology = primitiveTopology;
            }
        }
Exemple #6
0
 /// <summary>
 /// Determine and updates <see cref="CurrentState"/> from <see cref="State"/>.
 /// </summary>
 public void Update()
 {
     // we already do caching within pipeline state below
     CurrentState = PipelineState.New(graphicsDevice, ref State);
 }
Exemple #7
0
 public void SetPipelineState(PipelineState pipelineState)
 {
     NullHelper.ToImplement();
 }