/// <summary> /// Calculates the expected width of a texture using a specified type. /// </summary> /// <typeparam name="TData">The type of the T pixel data.</typeparam> /// <returns>The expected width</returns> /// <exception cref="System.ArgumentException">If the size is invalid</exception> public int CalculateWidth <TData>(int mipLevel = 0) where TData : struct { var widthOnMip = CalculateMipSize((int)Description.Width, mipLevel); var rowStride = widthOnMip * Description.Format.SizeInBytes(); var dataStrideInBytes = Utilities.SizeOf <TData>() * widthOnMip; var width = ((double)rowStride / dataStrideInBytes) * widthOnMip; if (Math.Abs(width - (int)width) > Double.Epsilon) { throw new ArgumentException("sizeof(TData) / sizeof(Format) * Width is not an integer"); } return((int)width); }
protected static DataBox GetDataBox <T>(PixelFormat format, int width, int height, int depth, T[] textureData, IntPtr fixedPointer) where T : struct { // Check that the textureData size is correct if (textureData == null) { throw new ArgumentNullException("textureData"); } int rowPitch; int slicePitch; int widthCount; int heightCount; Image.ComputePitch(format, width, height, out rowPitch, out slicePitch, out widthCount, out heightCount); if (Utilities.SizeOf(textureData) != (slicePitch * depth)) { throw new ArgumentException("Invalid size for Image"); } return(new DataBox(fixedPointer, rowPitch, slicePitch)); }
/// <summary> /// Copies the content an array of data on CPU memory to this texture into GPU memory using the specified <see cref="GraphicsDevice"/> (The graphics device could be deffered). /// </summary> /// <typeparam name="TData">The type of the T data.</typeparam> /// <param name="device">The <see cref="GraphicsDevice"/>.</param> /// <param name="fromData">The data to copy from.</param> /// <param name="arraySlice">The array slice index. This value must be set to 0 for Texture 3D.</param> /// <param name="mipSlice">The mip slice index.</param> /// <param name="region">Destination region</param> /// <exception cref="System.ArgumentException">When strides is different from optimal strides, and TData is not the same size as the pixel format, or Width * Height != toData.Length</exception> /// <remarks> /// See unmanaged documentation for usage and restrictions. /// </remarks> public unsafe void SetData <TData>(GraphicsDevice device, TData[] fromData, int arraySlice = 0, int mipSlice = 0, ResourceRegion?region = null) where TData : struct { SetData(device, new DataPointer((IntPtr)Interop.Fixed(fromData), fromData.Length * Utilities.SizeOf <TData>()), arraySlice, mipSlice, region); }
/// <summary> /// Copies the content of this texture from GPU memory to an array of data on CPU memory using a specific staging resource. /// </summary> /// <typeparam name="TData">The type of the T data.</typeparam> /// <param name="stagingTexture">The staging texture used to transfer the texture to.</param> /// <param name="toData">To data.</param> /// <param name="arraySlice">The array slice index. This value must be set to 0 for Texture 3D.</param> /// <param name="mipSlice">The mip slice index.</param> /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param> /// <returns><c>true</c> if data was correctly retrieved, <c>false</c> if <see cref="doNotWait"/> flag was true and the resource is still being used by the GPU for writing.</returns> /// <exception cref="System.ArgumentException">When strides is different from optimal strides, and TData is not the same size as the pixel format, or Width * Height != toData.Length</exception> /// <remarks> /// This method is only working when called from the main thread that is accessing the main <see cref="GraphicsDevice"/>. /// </remarks> public unsafe bool GetData <TData>(Texture stagingTexture, TData[] toData, int arraySlice = 0, int mipSlice = 0, bool doNotWait = false) where TData : struct { return(GetData(stagingTexture, new DataPointer((IntPtr)Interop.Fixed(toData), toData.Length * Utilities.SizeOf <TData>()), arraySlice, mipSlice, doNotWait)); }