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++;
            }
        }
Beispiel #3
0
        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;
        }