private PipelineState(GraphicsDevice graphicsDevice, PipelineStateDescription pipelineStateDescription) : base(graphicsDevice) { // First time, build caches var pipelineStateCache = GetPipelineStateCache(); var depthClampEmulation = !pipelineStateDescription.RasterizerState.DepthClipEnable && !graphicsDevice.HasDepthClamp; #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES // Depth Clamp can't be emulated on OpenGL ES 2 (TODO: warning?) if (graphicsDevice.IsOpenGLES2) { depthClampEmulation = false; } #endif // Store states BlendState = new BlendState(pipelineStateDescription.BlendState, pipelineStateDescription.Output.RenderTargetCount > 0); RasterizerState = new RasterizerState(pipelineStateDescription.RasterizerState); DepthStencilState = new DepthStencilState(pipelineStateDescription.DepthStencilState, pipelineStateDescription.Output.DepthStencilFormat != PixelFormat.None); PrimitiveType = pipelineStateDescription.PrimitiveType.ToOpenGL(); // Compile effect var effectBytecode = pipelineStateDescription.EffectBytecode; EffectProgram = effectBytecode != null?pipelineStateCache.EffectProgramCache.Instantiate(Tuple.Create(effectBytecode, depthClampEmulation)) : null; var rootSignature = pipelineStateDescription.RootSignature; if (rootSignature != null && effectBytecode != null) { ResourceBinder.Compile(graphicsDevice, rootSignature.EffectDescriptorSetReflection, effectBytecode); } // Vertex attributes if (pipelineStateDescription.InputElements != null) { var vertexAttribs = new List <VertexAttrib>(); foreach (var inputElement in pipelineStateDescription.InputElements) { // Query attribute name from effect var attributeName = "a_" + inputElement.SemanticName + inputElement.SemanticIndex; int attributeIndex; if (!EffectProgram.Attributes.TryGetValue(attributeName, out attributeIndex)) { continue; } var vertexElementFormat = VertexAttrib.ConvertVertexElementFormat(inputElement.Format); vertexAttribs.Add(new VertexAttrib( inputElement.InputSlot, attributeIndex, vertexElementFormat.Size, vertexElementFormat.Type, vertexElementFormat.Normalized, inputElement.AlignedByteOffset)); } VertexAttribs = pipelineStateCache.VertexAttribsCache.Instantiate(vertexAttribs.ToArray()); } }
private void AddAttribute(ref int index, ref VertexAttrib attrib, ref uint enabledVertexAttribArrays) { int attribIndex; if (programAttributes.TryGetValue(attrib.AttributeName, out attribIndex)) { vertexAttribs[index] = attrib; vertexAttribs[index].Index = attribIndex; #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES hasDynamicStagingVB |= attrib.VertexBufferId == 0; #endif if (attribIndex != -1) { enabledVertexAttribArrays |= 1U << attribIndex; } index++; } }
private void CreateAttributes() { int vertexAttribCount = 0; for (int i = 0; i < vertexBufferBindings.Length; ++i) { vertexAttribCount += vertexBufferBindings[i].Declaration.VertexElements.Length; } vertexAttribs = new VertexAttrib[vertexAttribCount]; int j = 0; for (int i = 0; i < vertexBufferBindings.Length; ++i) { var inputSlot = vertexBufferBindings[i]; var vertexBuffer = vertexBufferBindings[i].Buffer; foreach (var vertexElementAndOffset in inputSlot.Declaration.EnumerateWithOffsets()) { var vertexElement = vertexElementAndOffset.VertexElement; var attributeName = "a_" + vertexElement.SemanticName + vertexElement.SemanticIndex; var vertexElementFormat = ConvertVertexElementFormat(vertexElement.Format); #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES IntPtr bufferStart = vertexBuffer.ResourceId == 0 ? vertexBuffer.StagingData : (IntPtr)vertexBufferBindings[i].Offset; #else var bufferStart = (IntPtr)vertexBufferBindings[i].Offset; #endif vertexAttribs[j] = new VertexAttrib { VertexBufferId = vertexBuffer.ResourceId, Index = -1, IsInteger = IsInteger(vertexElementFormat.Type), Size = vertexElementFormat.Size, Type = vertexElementFormat.Type, Normalized = vertexElementFormat.Normalized, Stride = inputSlot.Declaration.VertexStride, Offset = bufferStart + vertexElementAndOffset.Offset, AttributeName = attributeName }; j++; } } if (indexBufferBinding != null) { indexBufferId = indexBufferBinding.Buffer.resourceId; #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (GraphicsDevice.IsOpenGLES2 && indexBufferBinding.Is32Bit) { throw new PlatformNotSupportedException("32 bits index buffer are not supported on OpenGL ES 2.0"); } indexBufferOffset = (indexBufferId == 0 ? indexBufferBinding.Buffer.StagingData : IntPtr.Zero) + indexBufferBinding.Offset; #else indexBufferOffset = (IntPtr)indexBufferBinding.Offset; #endif drawElementsType = indexBufferBinding.Is32Bit ? DrawElementsType.UnsignedInt : DrawElementsType.UnsignedShort; indexElementSize = indexBufferBinding.Is32Bit ? 4 : 2; } // If we have a signature, we can already pre-create the instance if (preferredInputSignature != null) { preferredInstance = GetInstance(preferredInputSignature); } currentShaderSignature = preferredInputSignature; currentInstance = preferredInstance; }