/// <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.RegisterBufferMemoryUsage(SizeInBytes); } return(this); }
private void InitializeFromImpl(DataBox[] dataBoxes = null) { if (ParentTexture != null) { CopyParentAttributes(); } if (TextureId == 0) { TextureTarget = GetTextureTarget(Dimension); 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; IsDepthBuffer = ((Description.Flags & TextureFlags.DepthStencil) != 0); if (IsDepthBuffer) { HasStencil = InternalHasStencil(Format); } else { HasStencil = false; } if ((Description.Flags & TextureFlagsCustomResourceId) != 0) { return; } using (var openglContext = GraphicsDevice.UseOpenGLCreationContext()) { TextureTotalSize = ComputeBufferTotalSize(); if (Description.Usage == GraphicsResourceUsage.Staging) { InitializeStagingPixelBufferObject(dataBoxes); return; // TODO: This return causes "GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes);" not to get entered. Is that okay? } // Depth textures are renderbuffers for now // TODO: PERFORMANCE: Why? I think we should change that so we can sample them directly. // TODO: enable switch // TODO: What does this comment even mean? IsRenderbuffer = !Description.IsShaderResource; // Force to renderbuffer if MSAA is on because we don't support MSAA textures ATM (and they don't exist on OpenGL ES). if (Description.IsMultisample) { // TODO: Ideally the caller of this method should be aware of this "force to renderbuffer", // because the caller won't be able to bind it as a texture. IsRenderbuffer = true; } if (IsRenderbuffer) { CreateRenderbuffer(); return; // TODO: This return causes "GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes);" not to get entered. Is that okay? } GL.GenTextures(1, out TextureId); GL.BindTexture(TextureTarget, TextureId); SetFilterMode(); if (Description.MipLevels == 0) { throw new NotImplementedException(); } var setSize = TextureSetSize(TextureTarget); for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex) { int offsetArray = arrayIndex * Description.MipLevels; for (int mipLevel = 0; mipLevel < Description.MipLevels; ++mipLevel) { DataBox dataBox; Int3 dimensions = new Int3(CalculateMipSize(Description.Width, mipLevel), CalculateMipSize(Description.Height, mipLevel), CalculateMipSize(Description.Depth, mipLevel)); if (dataBoxes != null && mipLevel < dataBoxes.Length) { if (setSize > 1 && !compressed && dataBoxes[mipLevel].RowPitch != dimensions.X * TexturePixelSize) { throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D/3D."); } // Might be possible, need to check API better. dataBox = dataBoxes[offsetArray + mipLevel]; } else { dataBox = new DataBox(); } switch (TextureTarget) { case TextureTarget.Texture1D: CreateTexture1D(compressed, dimensions.X, mipLevel, dataBox); break; case TextureTarget.Texture2D: case TextureTarget.TextureCubeMap: CreateTexture2D(compressed, dimensions.X, dimensions.Y, mipLevel, arrayIndex, dataBox); break; case TextureTarget.Texture3D: CreateTexture3D(compressed, dimensions.X, dimensions.Y, dimensions.Z, mipLevel, dataBox); break; case TextureTarget.Texture2DArray: CreateTexture2DArray(compressed, dimensions.X, dimensions.Y, mipLevel, arrayIndex, dataBox); break; } } } GL.BindTexture(TextureTarget, 0); // This unbinds the texture. 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.RegisterTextureMemoryUsage(SizeInBytes); } }