internal unsafe void Initialize(ImageDescription description, IntPtr dataPointer, int offset, GCHandle?handle, bool bufferIsDisposable, PitchFlags pitchFlags = PitchFlags.None) { if (!FormatHelper.IsValid(description.Format) || FormatHelper.IsVideo(description.Format)) { throw new InvalidOperationException("Unsupported DXGI Format"); } this.handle = handle; switch (description.Dimension) { case TextureDimension.Texture1D: if (description.Width <= 0 || description.Height != 1 || description.Depth != 1 || description.ArraySize == 0) { throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 1D"); } // Check that miplevels are fine description.MipLevels = Texture.CalculateMipLevels(description.Width, 1, description.MipLevels); break; case TextureDimension.Texture2D: case TextureDimension.TextureCube: if (description.Width <= 0 || description.Height <= 0 || description.Depth != 1 || description.ArraySize == 0) { throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 2D"); } if (description.Dimension == TextureDimension.TextureCube) { if ((description.ArraySize % 6) != 0) { throw new InvalidOperationException("TextureCube must have an arraysize = 6"); } } // Check that miplevels are fine description.MipLevels = Texture.CalculateMipLevels(description.Width, description.Height, description.MipLevels); break; case TextureDimension.Texture3D: if (description.Width <= 0 || description.Height <= 0 || description.Depth <= 0 || description.ArraySize != 1) { throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 3D"); } // Check that miplevels are fine description.MipLevels = Texture.CalculateMipLevels(description.Width, description.Height, description.Depth, description.MipLevels); break; } // Calculate mipmaps int pixelBufferCount; this.mipMapToZIndex = CalculateImageArray(description, pitchFlags, out pixelBufferCount, out totalSizeInBytes); this.mipmapDescriptions = CalculateMipMapDescription(description, pitchFlags); zBufferCountPerArraySlice = this.mipMapToZIndex[this.mipMapToZIndex.Count - 1]; // Allocate all pixel buffers pixelBuffers = new PixelBuffer[pixelBufferCount]; pixelBufferArray = new PixelBufferArray(this); // Setup all pointers // only release buffer that is not pinned and is asked to be disposed. this.bufferIsDisposable = !handle.HasValue && bufferIsDisposable; this.buffer = dataPointer; if (dataPointer == IntPtr.Zero) { buffer = Utilities.AllocateMemory(totalSizeInBytes); offset = 0; this.bufferIsDisposable = true; } SetupImageArray((IntPtr)((byte *)buffer + offset), totalSizeInBytes, description, pitchFlags, pixelBuffers); Description = description; // PreCompute databoxes dataBoxArray = ComputeDataBox(); }
internal unsafe void Initialize(ImageDescription description, IntPtr dataPointer, int offset, GCHandle? handle, bool bufferIsDisposable, PitchFlags pitchFlags = PitchFlags.None) { if (!FormatHelper.IsValid(description.Format) || FormatHelper.IsVideo(description.Format)) throw new InvalidOperationException("Unsupported DXGI Format"); this.handle = handle; switch (description.Dimension) { case TextureDimension.Texture1D: if (description.Width <= 0 || description.Height != 1 || description.Depth != 1 || description.ArraySize == 0) throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 1D"); // Check that miplevels are fine description.MipLevels = Texture.CalculateMipLevels(description.Width, 1, description.MipLevels); break; case TextureDimension.Texture2D: case TextureDimension.TextureCube: if (description.Width <= 0 || description.Height <= 0 || description.Depth != 1 || description.ArraySize == 0) throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 2D"); if (description.Dimension == TextureDimension.TextureCube) { if ((description.ArraySize % 6) != 0) throw new InvalidOperationException("TextureCube must have an arraysize = 6"); } // Check that miplevels are fine description.MipLevels = Texture.CalculateMipLevels(description.Width, description.Height, description.MipLevels); break; case TextureDimension.Texture3D: if (description.Width <= 0 || description.Height <= 0 || description.Depth <= 0 || description.ArraySize != 1) throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 3D"); // Check that miplevels are fine description.MipLevels = Texture.CalculateMipLevels(description.Width, description.Height, description.Depth, description.MipLevels); break; } // Calculate mipmaps int pixelBufferCount; this.mipMapToZIndex = CalculateImageArray(description, pitchFlags, out pixelBufferCount, out totalSizeInBytes); this.mipmapDescriptions = CalculateMipMapDescription(description, pitchFlags); zBufferCountPerArraySlice = this.mipMapToZIndex[this.mipMapToZIndex.Count - 1]; // Allocate all pixel buffers pixelBuffers = new PixelBuffer[pixelBufferCount]; pixelBufferArray = new PixelBufferArray(this); // Setup all pointers // only release buffer that is not pinned and is asked to be disposed. this.bufferIsDisposable = !handle.HasValue && bufferIsDisposable; this.buffer = dataPointer; if (dataPointer == IntPtr.Zero) { buffer = Utilities.AllocateMemory(totalSizeInBytes); offset = 0; this.bufferIsDisposable = true; } SetupImageArray((IntPtr)((byte*)buffer + offset), totalSizeInBytes, description, pitchFlags, pixelBuffers); Description = description; // PreCompute databoxes dataBoxArray = ComputeDataBox(); }