コード例 #1
0
ファイル: BlendState.OpenGL.cs プロジェクト: rohitshe/Code
        public void Apply(CommandList commandList, BlendState oldBlendState)
        {
            // note: need to update blend equation, blend function and color mask even when the blend state is disable in order to keep the hash based caching system valid

            if (blendEnable && !oldBlendState.blendEnable)
            {
                GL.Enable(EnableCap.Blend);
            }

            if (blendEquationHash != oldBlendState.blendEquationHash)
            {
                GL.BlendEquationSeparate(blendEquationModeColor, blendEquationModeAlpha);
            }

            if (blendFuncHash != oldBlendState.blendFuncHash)
            {
                GL.BlendFuncSeparate(blendFactorSrcColor, blendFactorDestColor, blendFactorSrcAlpha, blendFactorDestAlpha);
            }

            if (commandList.NewBlendFactor != commandList.BoundBlendFactor)
            {
                commandList.BoundBlendFactor = commandList.NewBlendFactor;
                GL.BlendColor(OpenGLConvertExtensions.ToOpenGL(commandList.NewBlendFactor));
            }

            if (ColorWriteChannels != oldBlendState.ColorWriteChannels)
            {
                RestoreColorMask();
            }

            if (!blendEnable && oldBlendState.blendEnable)
            {
                GL.Disable(EnableCap.Blend);
            }
        }
コード例 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Buffer" /> class.
        /// </summary>
        /// <param name="description">The description.</param>
        /// <param name="viewFlags">Type of the buffer.</param>
        /// <param name="viewFormat">The view format.</param>
        /// <param name="dataPointer">The data pointer.</param>
        protected Buffer InitializeFromImpl(BufferDescription description, BufferFlags viewFlags, PixelFormat viewFormat, IntPtr dataPointer)
        {
            bufferDescription = description;
            ViewFlags         = viewFlags;

            bool isCompressed;

            OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref viewFormat, out TextureInternalFormat, out TextureFormat, out TextureType, out bufferTextureElementSize, out isCompressed);

            ViewFormat = viewFormat;

            Recreate(dataPointer);

            if (GraphicsDevice != null)
            {
                GraphicsDevice.BuffersMemory += SizeInBytes / (float)0x100000;
            }

            return(this);
        }
コード例 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Buffer" /> class.
        /// </summary>
        /// <param name="description">The description.</param>
        /// <param name="viewFlags">Type of the buffer.</param>
        /// <param name="viewFormat">The view format.</param>
        /// <param name="dataPointer">The data pointer.</param>
        protected Buffer InitializeFromImpl(BufferDescription description, BufferFlags viewFlags, PixelFormat viewFormat, IntPtr dataPointer)
        {
            bufferDescription = description;
            ViewFlags         = viewFlags;

#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            int  pixelSize;
            bool isCompressed;
            OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref viewFormat, out internalFormat, out glPixelFormat, out type, out pixelSize, out isCompressed);
#endif
            ViewFormat = viewFormat;

            Recreate(dataPointer);

            if (GraphicsDevice != null)
            {
                GraphicsDevice.BuffersMemory += SizeInBytes / (float)0x100000;
            }

            return(this);
        }
コード例 #4
0
ファイル: Texture.OpenGL.cs プロジェクト: kiphe19/xenko
        private void InitializeFromImpl(DataBox[] dataBoxes = null)
        {
            if (ParentTexture != null)
            {
                resourceId = ParentTexture.ResourceId;

                // copy parameters
                InternalFormat = ParentTexture.InternalFormat;
                FormatGl       = ParentTexture.FormatGl;
                Type           = ParentTexture.Type;
                Target         = ParentTexture.Target;
                DepthPitch     = ParentTexture.DepthPitch;
                RowPitch       = ParentTexture.RowPitch;
                IsDepthBuffer  = ParentTexture.IsDepthBuffer;
                HasStencil     = ParentTexture.HasStencil;
                IsRenderbuffer = ParentTexture.IsRenderbuffer;

                resourceIdStencil   = ParentTexture.ResourceIdStencil;
                pixelBufferObjectId = ParentTexture.PixelBufferObjectId;
            }

            if (resourceId == 0)
            {
                switch (Dimension)
                {
                case TextureDimension.Texture1D:
#if !SILICONSTUDIO_PLATFORM_MONO_MOBILE
                    Target = TextureTarget.Texture1D;
                    break;
#endif
                case TextureDimension.Texture2D:
                    Target = TextureTarget.Texture2D;
                    break;

                case TextureDimension.Texture3D:
                    Target = TextureTarget.Texture3D;
                    break;

                case TextureDimension.TextureCube:
                    Target = TextureTarget.TextureCubeMap;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                PixelInternalFormat internalFormat;
                PixelFormatGl       format;
                PixelType           type;
                int  pixelSize;
                bool compressed;
                OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref textureDescription.Format, out internalFormat, out format, out type, out pixelSize, out compressed);

                InternalFormat = internalFormat;
                FormatGl       = format;
                Type           = type;
                DepthPitch     = Description.Width * Description.Height * pixelSize;
                RowPitch       = Description.Width * pixelSize;

                if ((Description.Flags & TextureFlags.DepthStencil) != 0)
                {
                    IsDepthBuffer = true;
                    HasStencil    = InternalHasStencil(Format);
                }
                else
                {
                    IsDepthBuffer = false;
                    HasStencil    = false;
                }

                if ((Description.Flags & TextureFlagsCustomResourceId) != 0)
                {
                    return;
                }

                using (GraphicsDevice.UseOpenGLCreationContext())
                {
                    // Depth texture are render buffer for now
                    // TODO: enable switch
                    if ((Description.Flags & TextureFlags.DepthStencil) != 0 && (Description.Flags & TextureFlags.ShaderResource) == 0)
                    {
                        RenderbufferStorage depth, stencil;
                        ConvertDepthFormat(GraphicsDevice, Description.Format, out depth, out stencil);

                        GL.GenRenderbuffers(1, out resourceId);
                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, resourceId);
                        GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, depth, Width, Height);

                        if (stencil != 0)
                        {
                            // separate stencil
                            GL.GenRenderbuffers(1, out resourceIdStencil);
                            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, resourceIdStencil);
                            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, stencil, Width, Height);
                        }
                        else if (HasStencil)
                        {
                            // depth+stencil in a single texture
                            resourceIdStencil = resourceId;
                        }

                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);

                        IsRenderbuffer = true;
                        return;
                    }
                    else
                    {
                        GL.GenTextures(1, out resourceId);
                        GL.BindTexture(Target, resourceId);

                        IsRenderbuffer = false;
                    }

                    // No filtering on depth buffer
                    if ((Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) != TextureFlags.None)
                    {
                        GL.TexParameter(Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                        GL.TexParameter(Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                        GL.TexParameter(Target, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
                        GL.TexParameter(Target, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
                        BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp;
                    }
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    else if (Description.MipLevels <= 1)
                    {
                        GL.TexParameter(Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                        GL.TexParameter(Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                    }
#endif

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    if (!GraphicsDevice.IsOpenGLES2)
#endif
                    {
                        GL.TexParameter(Target, TextureParameterName.TextureBaseLevel, 0);
                        GL.TexParameter(Target, TextureParameterName.TextureMaxLevel, Description.MipLevels - 1);
                    }

                    if (Description.MipLevels == 0)
                    {
                        throw new NotImplementedException();
                    }

                    var setSize = TextureSetSize(Target);

                    for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex)
                    {
                        var offsetArray = arrayIndex * Description.MipLevels;
                        for (int i = 0; i < Description.MipLevels; ++i)
                        {
                            IntPtr data   = IntPtr.Zero;
                            var    width  = CalculateMipSize(Description.Width, i);
                            var    height = CalculateMipSize(Description.Height, i);
                            if (dataBoxes != null && i < dataBoxes.Length)
                            {
                                if (setSize > 1 && !compressed && dataBoxes[i].RowPitch != width * pixelSize)
                                {
                                    throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D.");
                                }
                                // Might be possible, need to check API better.
                                data = dataBoxes[offsetArray + i].DataPointer;
                            }

                            if (setSize == 2)
                            {
                                var dataSetTarget = GetTextureTargetForDataSet2D(Target, arrayIndex);
                                if (compressed)
                                {
                                    GL.CompressedTexImage2D(dataSetTarget, i, (CompressedInternalFormat2D)internalFormat,
                                                            width, height, 0, dataBoxes[offsetArray + i].SlicePitch, data);
                                }
                                else
                                {
                                    GL.TexImage2D(dataSetTarget, i, internalFormat, width, height, 0, format, type, data);
                                }
                            }
                            else if (setSize == 3)
                            {
                                var dataSetTarget = GetTextureTargetForDataSet3D(Target);
                                var depth         = Target == TextureTarget.Texture2DArray ? Description.Depth : CalculateMipSize(Description.Depth, i); // no depth mipmaps in Texture2DArray
                                if (compressed)
                                {
                                    GL.CompressedTexImage3D(dataSetTarget, i, (CompressedInternalFormat3D)internalFormat,
                                                            width, height, depth, 0, dataBoxes[offsetArray + i].SlicePitch, data);
                                }
                                else
                                {
                                    GL.TexImage3D(dataSetTarget, i, (TextureComponentCount3D)internalFormat,
                                                  width, height, depth, 0, format, type, data);
                                }
                            }
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                            else if (setSize == 1)
                            {
                                if (compressed)
                                {
                                    GL.CompressedTexImage1D(TextureTarget.Texture1D, i, internalFormat,
                                                            width, 0, dataBoxes[offsetArray + i].SlicePitch, data);
                                }
                                else
                                {
                                    GL.TexImage1D(TextureTarget.Texture1D, i, internalFormat,
                                                  width, 0, format, type, data);
                                }
                            }
#endif
                        }
                    }
                    GL.BindTexture(Target, 0);

                    InitializePixelBufferObject();
                }

                GraphicsDevice.TextureMemory += (Depth * DepthStride) / (float)0x100000;
            }
        }
コード例 #5
0
        private void InitializeFromImpl(DataBox[] dataBoxes = null)
        {
            if (ParentTexture != null)
            {
                TextureId = ParentTexture.TextureId;

                // copy parameters
                TextureInternalFormat = ParentTexture.TextureInternalFormat;
                TextureFormat         = ParentTexture.TextureFormat;
                TextureType           = ParentTexture.TextureType;
                TextureTarget         = ParentTexture.TextureTarget;
                DepthPitch            = ParentTexture.DepthPitch;
                RowPitch       = ParentTexture.RowPitch;
                IsDepthBuffer  = ParentTexture.IsDepthBuffer;
                HasStencil     = ParentTexture.HasStencil;
                IsRenderbuffer = ParentTexture.IsRenderbuffer;

                stencilId           = ParentTexture.StencilId;
                pixelBufferObjectId = ParentTexture.PixelBufferObjectId;
            }

            if (TextureId == 0)
            {
                switch (Dimension)
                {
                case TextureDimension.Texture1D:
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    if (ArraySize > 1)
                    {
                        throw new PlatformNotSupportedException("Texture1DArray is not implemented under OpenGL");
                    }
                    TextureTarget = TextureTarget.Texture1D;
                    break;
#endif
                case TextureDimension.Texture2D:
                    TextureTarget = ArraySize > 1 ? TextureTarget.Texture2DArray : TextureTarget.Texture2D;
                    break;

                case TextureDimension.Texture3D:
                    TextureTarget = TextureTarget.Texture3D;
                    break;

                case TextureDimension.TextureCube:
                    if (ArraySize > 6)
                    {
                        throw new PlatformNotSupportedException("TextureCubeArray is not implemented under OpenGL");
                    }
                    TextureTarget = TextureTarget.TextureCubeMap;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                bool compressed;
                OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref textureDescription.Format, out TextureInternalFormat, out TextureFormat, out TextureType, out TexturePixelSize, out compressed);

                DepthPitch = Description.Width * Description.Height * TexturePixelSize;
                RowPitch   = Description.Width * TexturePixelSize;

                if ((Description.Flags & TextureFlags.DepthStencil) != 0)
                {
                    IsDepthBuffer = true;
                    HasStencil    = InternalHasStencil(Format);
                }
                else
                {
                    IsDepthBuffer = false;
                    HasStencil    = false;
                }

                if ((Description.Flags & TextureFlagsCustomResourceId) != 0)
                {
                    return;
                }

                using (var openglContext = GraphicsDevice.UseOpenGLCreationContext())
                {
                    // Depth texture are render buffer for now
                    // TODO: enable switch
                    if ((Description.Flags & TextureFlags.DepthStencil) != 0 && (Description.Flags & TextureFlags.ShaderResource) == 0)
                    {
                        RenderbufferStorage depth, stencil;
                        ConvertDepthFormat(GraphicsDevice, Description.Format, out depth, out stencil);

                        GL.GenRenderbuffers(1, out TextureId);
                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, TextureId);
                        GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, depth, Width, Height);

                        if (stencil != 0)
                        {
                            // separate stencil
                            GL.GenRenderbuffers(1, out stencilId);
                            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, stencilId);
                            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, stencil, Width, Height);
                        }
                        else if (HasStencil)
                        {
                            // depth+stencil in a single texture
                            stencilId = TextureId;
                        }

                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);

                        IsRenderbuffer = true;
                        return;
                    }

                    IsRenderbuffer = false;

                    TextureTotalSize = ComputeBufferTotalSize();

                    if (Description.Usage == GraphicsResourceUsage.Staging)
                    {
                        InitializeStagingPixelBufferObject(dataBoxes);
                        return;
                    }

                    GL.GenTextures(1, out TextureId);
                    GL.BindTexture(TextureTarget, TextureId);

                    // No filtering on depth buffer
                    if ((Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) != TextureFlags.None)
                    {
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
                        BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp;

                        if (HasStencil)
                        {
                            // depth+stencil in a single texture
                            stencilId = TextureId;
                        }
                    }
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    else if (Description.MipLevels <= 1)
                    {
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                    }
#endif

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    if (!GraphicsDevice.IsOpenGLES2)
#endif
                    {
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureBaseLevel, 0);
                        GL.TexParameter(TextureTarget, TextureParameterName.TextureMaxLevel, Description.MipLevels - 1);
                    }

                    if (Description.MipLevels == 0)
                    {
                        throw new NotImplementedException();
                    }

                    var setSize = TextureSetSize(TextureTarget);

                    for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex)
                    {
                        var offsetArray = arrayIndex * Description.MipLevels;
                        for (int i = 0; i < Description.MipLevels; ++i)
                        {
                            DataBox dataBox;
                            var     width  = CalculateMipSize(Description.Width, i);
                            var     height = CalculateMipSize(Description.Height, i);
                            var     depth  = CalculateMipSize(Description.Depth, i);
                            if (dataBoxes != null && i < dataBoxes.Length)
                            {
                                if (setSize > 1 && !compressed && dataBoxes[i].RowPitch != width * TexturePixelSize)
                                {
                                    throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D/3D.");
                                }
                                // Might be possible, need to check API better.
                                dataBox = dataBoxes[offsetArray + i];
                            }
                            else
                            {
                                dataBox = new DataBox();
                            }

                            switch (TextureTarget)
                            {
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                            case TextureTarget.Texture1D:
                                if (compressed)
                                {
                                    GL.CompressedTexImage1D(TextureTarget, i, TextureInternalFormat, width, 0, dataBox.SlicePitch, dataBox.DataPointer);
                                }
                                else
                                {
                                    GL.TexImage1D(TextureTarget, i, TextureInternalFormat, width, 0, TextureFormat, TextureType, dataBox.DataPointer);
                                }
                                break;
#endif
                            case TextureTarget.Texture2D:
                            case TextureTarget.TextureCubeMap:
                            {
                                var dataSetTarget = GetTextureTargetForDataSet2D(TextureTarget, arrayIndex);
                                if (compressed)
                                {
                                    GL.CompressedTexImage2D(dataSetTarget, i, (CompressedInternalFormat2D)TextureInternalFormat, width, height, 0, dataBox.SlicePitch, dataBox.DataPointer);
                                }
                                else
                                {
                                    GL.TexImage2D(dataSetTarget, i, (TextureComponentCount2D)TextureInternalFormat, width, height, 0, TextureFormat, TextureType, dataBox.DataPointer);
                                }
                                break;
                            }

                            case TextureTarget.Texture3D:
                            {
                                if (compressed)
                                {
                                    GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, i, (CompressedInternalFormat3D)TextureInternalFormat, width, height, depth, 0, dataBox.SlicePitch, dataBox.DataPointer);
                                }
                                else
                                {
                                    GL.TexImage3D((TextureTarget3d)TextureTarget, i, (TextureComponentCount3D)TextureInternalFormat, width, height, depth, 0, TextureFormat, TextureType, dataBox.DataPointer);
                                }
                                break;
                            }

                            case TextureTarget.Texture2DArray:
                            {
                                // We create all array slices at once, but upload them one by one
                                if (arrayIndex == 0)
                                {
                                    if (compressed)
                                    {
                                        GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, i, (CompressedInternalFormat3D)TextureInternalFormat, width, height, ArraySize, 0, 0, IntPtr.Zero);
                                    }
                                    else
                                    {
                                        GL.TexImage3D((TextureTarget3d)TextureTarget, i, (TextureComponentCount3D)TextureInternalFormat, width, height, ArraySize, 0, TextureFormat, TextureType, IntPtr.Zero);
                                    }
                                }

                                if (dataBox.DataPointer != IntPtr.Zero)
                                {
                                    if (compressed)
                                    {
                                        GL.CompressedTexSubImage3D((TextureTarget3d)TextureTarget, i, 0, 0, arrayIndex, width, height, 1, TextureFormat, dataBox.SlicePitch, dataBox.DataPointer);
                                    }
                                    else
                                    {
                                        GL.TexSubImage3D((TextureTarget3d)TextureTarget, i, 0, 0, arrayIndex, width, height, 1, TextureFormat, TextureType, dataBox.DataPointer);
                                    }
                                }
                                break;
                            }
                            }
                        }
                    }
                    GL.BindTexture(TextureTarget, 0);
                    if (openglContext.CommandList != null)
                    {
                        // If we messed up with some states of a command list, mark dirty states
                        openglContext.CommandList.boundShaderResourceViews[openglContext.CommandList.activeTexture] = null;
                    }
                }

                GraphicsDevice.TextureMemory += (Depth * DepthStride) / (float)0x100000;
            }
        }
コード例 #6
0
        /// <summary>
        /// Inits this instance with the specified texture datas.
        /// </summary>
        /// <param name="textureDatas">The texture datas.</param>
        protected virtual void Init(DataBox[] textureDatas)
        {
            if (Target != TextureTarget.Texture2D && Target != TextureTarget.TextureCubeMap)
            {
                throw new Exception("incorrect type of Texture2D, it should be TextureTarget.Texture2D or TextureTarget.TextureCubeMap");
            }

            using (var creationContext = GraphicsDevice.UseOpenGLCreationContext())
            {
                // Can we just do a renderbuffer?
                if ((Description.Flags & TextureFlags.ShaderResource) == 0)
                {
                    if ((Description.Flags & TextureFlags.DepthStencil) == TextureFlags.DepthStencil)
                    {
                        RenderbufferStorage depth, stencil;
                        ConvertDepthFormat(GraphicsDevice, Description.Format, out depth, out stencil);

                        // Create depth render buffer (might contain stencil data too)
                        GL.GenRenderbuffers(1, out resourceId);
                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, resourceId);
                        GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, depth, Description.Width, Description.Height);
                        if (OpenGLConvertExtensions.GetErrorCode() != ErrorCode.NoError)
                        {
                            throw new InvalidOperationException("Could not create render buffer");
                        }

                        // If stencil buffer is separate, create it as well
                        if (stencil != 0)
                        {
                            GL.GenRenderbuffers(1, out ResouceIdStencil);
                            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, ResouceIdStencil);
                            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, stencil, Description.Width, Description.Height);
                            if (OpenGLConvertExtensions.GetErrorCode() != ErrorCode.NoError)
                            {
                                throw new InvalidOperationException("Could not create render buffer");
                            }
                        }

                        GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
                        return;
                    }
                }

                PixelInternalFormat internalFormat;
                PixelFormatGl       format;
                PixelType           type;
                int  pixelSize;
                bool compressed;
                ConvertPixelFormat(GraphicsDevice, Description.Format, out internalFormat, out format, out type, out pixelSize, out compressed);

                InternalFormat = internalFormat;
                FormatGl       = format;
                Type           = type;
                DepthPitch     = Description.Width * Description.Height * pixelSize;
                RowPitch       = Description.Width * pixelSize;

                if (Description.Usage == GraphicsResourceUsage.Staging)
                {
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    GL.GenBuffers(1, out resourceId);
                    GL.BindBuffer(BufferTarget.PixelPackBuffer, resourceId);
                    GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)DepthPitch, IntPtr.Zero,
                                  BufferUsageHint.StreamRead);
                    GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
#else
                    StagingData = Marshal.AllocHGlobal(DepthPitch);
#endif
                }
                else
                {
                    int textureId;

                    // If we're on main context, change internal states so that texture is bound again
                    if (!creationContext.UseDeviceCreationContext)
                    {
                        GraphicsDevice.UseTemporaryFirstTexture();
                    }

                    GL.GenTextures(1, out textureId);
                    GL.BindTexture(TextureTarget.Texture2D, textureId);

                    // No filtering on depth buffer
                    if ((Description.Flags & (TextureFlags.RenderTarget | TextureFlags.DepthStencil)) !=
                        TextureFlags.None)
                    {
                        GL.TexParameter(Target, TextureParameterName.TextureMinFilter,
                                        (int)TextureMinFilter.Nearest);
                        GL.TexParameter(Target, TextureParameterName.TextureMagFilter,
                                        (int)TextureMagFilter.Nearest);
                        GL.TexParameter(Target, TextureParameterName.TextureWrapS,
                                        (int)TextureWrapMode.ClampToEdge);
                        GL.TexParameter(Target, TextureParameterName.TextureWrapT,
                                        (int)TextureWrapMode.ClampToEdge);
                    }
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    else if (Description.MipLevels <= 1)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                    }
#endif

#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    GL.TexParameter(Target, TextureParameterName.TextureBaseLevel, 0);
                    GL.TexParameter(Target, TextureParameterName.TextureMaxLevel, Description.MipLevels - 1);
#endif

                    if (Description.MipLevels == 0)
                    {
                        throw new NotImplementedException();
                    }

                    for (int i = 0; i < Description.MipLevels; ++i)
                    {
                        IntPtr data   = IntPtr.Zero;
                        var    width  = CalculateMipSize(Description.Width, i);
                        var    height = CalculateMipSize(Description.Height, i);
                        if (textureDatas != null && i < textureDatas.Length)
                        {
                            if (!compressed && textureDatas[i].RowPitch != width * pixelSize)
                            {
                                throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D.");
                            }
                            // Might be possible, need to check API better.
                            data = textureDatas[i].DataPointer;
                        }
                        if (compressed)
                        {
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES && !SILICONSTUDIO_PLATFORM_MONO_MOBILE
                            throw new NotSupportedException("Can't use compressed textures on desktop OpenGL ES.");
#else
                            GL.CompressedTexImage2D(Target, i, internalFormat,
                                                    width, height, 0, textureDatas[i].SlicePitch, data);
#endif
                        }
                        else
                        {
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES && !SILICONSTUDIO_PLATFORM_MONO_MOBILE
                            GL.TexImage2D(TextureTarget2d.Texture2D, i, internalFormat.ToOpenGL(),
                                          width, height, 0, format, type, data);
#else
                            GL.TexImage2D(Target, i, internalFormat,
                                          width, height, 0, format, type, data);
#endif
                        }
                    }
                    GL.BindTexture(Target, 0);

                    resourceId = textureId;

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    if (!GraphicsDevice.IsOpenGLES2)
#endif
                    {
                        if (Description.Usage == GraphicsResourceUsage.Dynamic)
                        {
                            InitializePixelBufferObject();
                        }
                    }
                }
            }
        }