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; }
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); }
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; } }
/// <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); }
public void SetPipelineState(PipelineState pipelineState) { NullHelper.ToImplement(); }