public int GetThreadGroupSize(out Extent3D size) { var totalSize = GetThreadGroupSize(out var x, out var y, out var z); size = new Extent3D(x, y, z); return(totalSize); }
private unsafe Image CreateImage(Rendering.Texture type) { Device device = _renderer.Params.Device; AllocationCallbacks *allocator = (AllocationCallbacks *)_renderer.Params.AllocationCallbacks.ToPointer(); Vk vk = _renderer.Vk; ImageCreateInfo imageCreateInfo = new() { SType = StructureType.ImageCreateInfo, ImageType = ImageType.ImageType2D, Extent = new Extent3D() { Width = Size.X, Height = Size.Y, Depth = 1 }, MipLevels = _mipLevelCount, ArrayLayers = 1, Format = _format, Tiling = ImageTiling.Optimal, InitialLayout = ImageLayout.Undefined, Usage = ImageUsageFlags.ImageUsageTransferDstBit | ImageUsageFlags.ImageUsageTransferSrcBit | ImageUsageFlags.ImageUsageSampledBit, SharingMode = SharingMode.Exclusive, Samples = SampleCountFlags.SampleCount1Bit, QueueFamilyIndexCount = 0, PQueueFamilyIndices = null }; _renderer.AssertVulkan(vk.CreateImage(device, imageCreateInfo, allocator, out Image image)); return(image); }
private void CopyFromOrToBuffer( CommandBuffer commandBuffer, VkBuffer buffer, Image image, int size, bool to, int x, int y, int width, int height) { var aspectFlags = Info.Format.ConvertAspectFlags(); if (aspectFlags == (ImageAspectFlags.ImageAspectDepthBit | ImageAspectFlags.ImageAspectStencilBit)) { aspectFlags = ImageAspectFlags.ImageAspectDepthBit; } var sl = new ImageSubresourceLayers(aspectFlags, (uint)FirstLevel, (uint)FirstLayer, 1); var extent = new Extent3D((uint)width, (uint)height, 1); var region = new BufferImageCopy(0, (uint)width, (uint)height, sl, new Offset3D(x, y, 0), extent); if (to) { _gd.Api.CmdCopyImageToBuffer(commandBuffer, image, ImageLayout.General, buffer, 1, region); } else { _gd.Api.CmdCopyBufferToImage(commandBuffer, buffer, image, ImageLayout.General, 1, region); } }
/// <param name="MemoryOffset">Specified in bytes</param> public SparseImageMemoryBind(ImageSubresource Subresource, Offset3D Offset, Extent3D Extent, DeviceSize MemoryOffset) : this() { this.Subresource = Subresource; this.Offset = Offset; this.Extent = Extent; this.MemoryOffset = MemoryOffset; }
protected Image CreateTextureImage(Format imageFormat, uint width, uint height) { var size = new Extent3D(width, height, 1); var usage = ImageUsageFlags.TransferDst | ImageUsageFlags.Sampled; var createImageInfo = new ImageCreateInfo(ImageType.ImageType2d, imageFormat, size, 1, 1, SampleCountFlags.SampleCountFlags1, ImageTiling.Optimal, usage, SharingMode.Exclusive, null, ImageLayout.Preinitialized); return(device.CreateImage(createImageInfo)); }
public PointCloudBinarySource(FileHandlerBase file, long count, Extent3D extent, SQuantization3D quantization, long dataOffset, short pointSizeBytes) : base(file) { m_count = count; m_extent = extent; m_quantization = quantization; m_pointDataOffset = dataOffset; m_pointSizeBytes = pointSizeBytes; m_quantizedExtent = quantization.Convert(m_extent); }
public SharedQueueItem(uint queueFamilyIndex, uint queueCount, VulkanLogicalDevice vulkanLogicalDevice, Extent3D minImageTransferGranularity, uint timestampValidBits) : this() { this.QueueFamilyIndex = queueFamilyIndex; this.QueueCountRemaining = new int[queueCount]; for (int i = 0; i < queueCount; i++) { QueueCountRemaining[i] = i; } this.myDevice = vulkanLogicalDevice; this.minImageTransferGranularity = minImageTransferGranularity; this.timestampValidBits = timestampValidBits; }
Image CreateImage(Format imageFormat, uint width, uint height) { // Images represent multidimensional - up to 3 - arrays of data which can be used for // various purposes (e.g. attachments, textures), by binding them to a graphics or // compute pipeline via descriptor sets, or by directly specifying them as parameters // to certain commands. var size = new Extent3D(width, height, 1); var usage = ImageUsageFlags.ColorAttachment | ImageUsageFlags.TransferSrc | ImageUsageFlags.TransferDst; var createImageInfo = new ImageCreateInfo(ImageType.ImageType2d, imageFormat, size, 1, 1, SampleCountFlags.SampleCountFlags1, ImageTiling.Optimal, usage, SharingMode.Exclusive, null, ImageLayout.Preinitialized); return(device.CreateImage(createImageInfo)); }
public PointCloudBinarySourceComposite(FileHandlerBase file, Extent3D extent, IPointCloudBinarySource[] sources) : base(file) { m_sources = sources; // verify that they are compatible m_count = m_sources.Sum(s => s.Count); m_extent = extent; m_quantization = m_sources[0].Quantization; m_pointSizeBytes = m_sources[0].PointSizeBytes; m_quantizedExtent = m_quantization.Convert(m_extent); }
public void Extent3DEquals() { var val1 = new Extent3D(0, 1, 2); var val2 = new Extent3D(3, 4, 5); Assert.True(val1.Equals(val1)); Assert.False(val1.Equals(val2)); Assert.True(val1 == val1); Assert.False(val1 == val2); Assert.False(val1 != val1); Assert.True(val1 != val2); Assert.NotEqual(val1.GetHashCode(), val2.GetHashCode()); }
/// <param name="Usage">Image usage flags</param> /// <param name="SharingMode">Cross-queue-family sharing mode</param> /// <param name="QueueFamilyIndices">Array of queue family indices to share across</param> /// <param name="InitialLayout">Initial image layout for all subresources</param> public ImageCreateInfo(ImageType ImageType, Format Format, Extent3D Extent, UInt32 MipLevels, UInt32 ArrayLayers, SampleCountFlags Samples, ImageTiling Tiling, ImageUsageFlags Usage, SharingMode SharingMode, UInt32[] QueueFamilyIndices, ImageLayout InitialLayout) : this() { this.ImageType = ImageType; this.Format = Format; this.Extent = Extent; this.MipLevels = MipLevels; this.ArrayLayers = ArrayLayers; this.Samples = Samples; this.Tiling = Tiling; this.Usage = Usage; this.SharingMode = SharingMode; this.QueueFamilyIndices = QueueFamilyIndices; this.InitialLayout = InitialLayout; }
private void CopyFromOrToBuffer( CommandBuffer commandBuffer, VkBuffer buffer, Image image, int size, bool to, int dstLayer, int dstLevel, int x, int y, int width, int height) { var aspectFlags = Info.Format.ConvertAspectFlags(); if (aspectFlags == (ImageAspectFlags.ImageAspectDepthBit | ImageAspectFlags.ImageAspectStencilBit)) { aspectFlags = ImageAspectFlags.ImageAspectDepthBit; } var sl = new ImageSubresourceLayers(aspectFlags, (uint)(FirstLevel + dstLevel), (uint)(FirstLayer + dstLayer), 1); var extent = new Extent3D((uint)width, (uint)height, 1); int rowLengthAlignment = Info.BlockWidth; // We expect all data being written into the texture to have a stride aligned by 4. if (!to && Info.BytesPerPixel < 4) { rowLengthAlignment = 4 / Info.BytesPerPixel; } var region = new BufferImageCopy( 0, (uint)AlignUpNpot(width, rowLengthAlignment), (uint)AlignUpNpot(height, Info.BlockHeight), sl, new Offset3D(x, y, 0), extent); if (to) { _gd.Api.CmdCopyImageToBuffer(commandBuffer, image, ImageLayout.General, buffer, 1, region); } else { _gd.Api.CmdCopyBufferToImage(commandBuffer, buffer, image, ImageLayout.General, 1, region); } }
public unsafe void Update(Rectangle <uint> bounds, ReadOnlySpan <byte> data) { Vk vk = _renderer.Vk; Buffer <byte> stagingBuffer = new(BufferUsageFlags.BufferUsageTransferSrcBit, MemoryPropertyFlags.MemoryPropertyHostVisibleBit | MemoryPropertyFlags.MemoryPropertyHostCoherentBit, _renderer); stagingBuffer.Update(data); TransitionImageLayout(ImageLayout.ShaderReadOnlyOptimal, ImageLayout.TransferDstOptimal); CommandBuffer commandBuffer = BeginImageCommandBuffer(); BufferImageCopy bufferImageCopy = new() { BufferOffset = 0, BufferRowLength = 0, BufferImageHeight = 0, ImageSubresource = new ImageSubresourceLayers() { AspectMask = ImageAspectFlags.ImageAspectColorBit, MipLevel = 0, BaseArrayLayer = 0, LayerCount = 1 }, ImageOffset = new Offset3D() { X = 0, Y = 0, Z = 0 }, ImageExtent = new Extent3D() { Width = Size.X, Height = Size.Y, Depth = 1 } }; vk.CmdCopyBufferToImage(commandBuffer, stagingBuffer.Handle, _image, ImageLayout.TransferDstOptimal, 1, bufferImageCopy); EndImageCommandBuffer(commandBuffer); TransitionImageLayout(ImageLayout.TransferDstOptimal, ImageLayout.ShaderReadOnlyOptimal); stagingBuffer.Dispose(); }
public LASFile(string path, LASHeader header, LASVLR[] vlrs, LASEVLR[] evlrs) : base(path) { m_header = header; m_vlrs = vlrs; m_evlrs = evlrs; using (var stream = File.Create(FilePath)) { using (var writer = new FlexibleBinaryWriter(stream)) { header.Serialize(writer); } //header.WriteVLRs(stream, vlrs); } m_extent = m_header.Extent; }
public PointCloudTileSet(IPointCloudBinarySource source, PointCloudTileDensity density, SQuantizedExtentGrid <int> tileCounts, Grid <int> lowResCounts) { Extent = source.Extent; Quantization = source.Quantization; QuantizedExtent = source.QuantizedExtent; Density = density; Cols = tileCounts.SizeX; Rows = tileCounts.SizeY; TileSizeX = tileCounts.CellSizeX; TileSizeY = tileCounts.CellSizeY; //TileSize = tileCounts.CellSize; PointCount = density.PointCount; TileCount = density.TileCount; ValidTileCount = density.ValidTileCount; LowResCount = 0; m_tileIndex = CreateTileIndex(ValidTileCount); m_tiles = new PointCloudTile[density.ValidTileCount]; // create valid tiles (in order) long offset = 0; int validTileIndex = 0; foreach (var tile in GetTileOrdering(Rows, Cols)) { int pointCount = tileCounts.Data[tile.Row, tile.Col]; if (pointCount > 0) { var lowResCount = lowResCounts.Data[tile.Row, tile.Col]; m_tiles[validTileIndex] = new PointCloudTile(this, tile.Col, tile.Row, validTileIndex, offset, pointCount, LowResCount, lowResCount); m_tileIndex.Add(tile.Index, validTileIndex); ++validTileIndex; offset += (pointCount - lowResCount); LowResCount += lowResCount; } } }
public PointCloudTileSet(BinaryReader reader) { Rows = reader.ReadUInt16(); Cols = reader.ReadUInt16(); TileSizeY = reader.ReadInt32(); TileSizeX = reader.ReadInt32(); TileCount = Rows * Cols; Extent = reader.ReadExtent3D(); Quantization = reader.ReadSQuantization3D(); QuantizedExtent = Quantization.Convert(Extent); Density = reader.ReadTileDensity(); PointCount = Density.PointCount; ValidTileCount = Density.ValidTileCount; LowResCount = 0; m_tileIndex = CreateTileIndex(ValidTileCount); m_tiles = new PointCloudTile[ValidTileCount]; // fill in valid tiles (dense) long pointOffset = 0; var i = 0; foreach (var tile in GetTileOrdering(Rows, Cols)) { var pointCount = reader.ReadInt32(); var lowResCount = reader.ReadInt32(); if (pointCount > 0) { m_tiles[i] = new PointCloudTile(this, tile.Col, tile.Row, i, pointOffset, pointCount, LowResCount, lowResCount); m_tileIndex.Add(tile.Index, i); pointOffset += (pointCount - lowResCount); LowResCount += lowResCount; ++i; } } }
public LASFile(string path) : base(path) { if (Exists) { try { using (var stream = StreamManager.OpenReadStream(FilePath)) { using (var reader = new FlexibleBinaryReader(stream)) { m_header = reader.ReadLASHeader(); } m_vlrs = m_header.ReadVLRs(stream); m_evlrs = m_header.ReadEVLRs(stream); } m_extent = m_header.Extent; } catch { } } }
public void Initialize(Extent3D extent, int numPointsToProcess) { double SQRT3 = Math.Sqrt(3); //create one big Triangle_t aka. supertriangle //Make the bounding box slightly bigger, //actually no need for this if coming from streaming delaunay side m_extent = extent; // compute the supertriangle vertices, clockwise order, check the math m_superA = new DelaunayPoint(extent.MinX - extent.RangeY * SQRT3 / 3.0f, extent.MinY, extent.MinZ, numPointsToProcess); m_superB = new DelaunayPoint(extent.MidpointX, extent.MaxY + extent.RangeX * SQRT3 * 0.5f, extent.MinZ, numPointsToProcess + 1); m_superC = new DelaunayPoint(extent.MaxX + extent.RangeY * SQRT3 / 3.0f, extent.MinY, extent.MinZ, numPointsToProcess + 2); //create the super Triangle_t m_delaunayGraph = new Triangle(m_superA, m_superB, m_superC); //keep track of the current Triangle_t m_currentTriangle = m_delaunayGraph; m_newTriangles = new List <Triangle>(); m_outputTriangles = new List <int>(); }
public unsafe TextureStorage( VulkanRenderer gd, PhysicalDevice physicalDevice, Device device, TextureCreateInfo info, float scaleFactor, Auto <MemoryAllocation> foreignAllocation = null) { _gd = gd; _device = device; _info = info; ScaleFactor = scaleFactor; var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format); var levels = (uint)info.Levels; var layers = (uint)info.GetLayers(); var depth = (uint)(info.Target == Target.Texture3D ? info.Depth : 1); VkFormat = format; var type = info.Target.Convert(); var extent = new Extent3D((uint)info.Width, (uint)info.Height, depth); var sampleCountFlags = ConvertToSampleCountFlags((uint)info.Samples); var usage = DefaultUsageFlags; if (info.Format.IsDepthOrStencil()) { usage |= ImageUsageFlags.ImageUsageDepthStencilAttachmentBit; } else if (info.Format.IsRtColorCompatible()) { usage |= ImageUsageFlags.ImageUsageColorAttachmentBit; } if (info.Format.IsImageCompatible()) { usage |= ImageUsageFlags.ImageUsageStorageBit; } var flags = ImageCreateFlags.ImageCreateMutableFormatBit; // This flag causes mipmapped texture arrays to break on AMD GCN, so for that copy dependencies are forced for aliasing as cube. bool isCube = info.Target == Target.Cubemap || info.Target == Target.CubemapArray; bool cubeCompatible = gd.IsAmdGcn ? isCube : (info.Width == info.Height && layers >= 6); if (type == ImageType.ImageType2D && cubeCompatible) { flags |= ImageCreateFlags.ImageCreateCubeCompatibleBit; } if (type == ImageType.ImageType3D) { flags |= ImageCreateFlags.ImageCreate2DArrayCompatibleBit; } var imageCreateInfo = new ImageCreateInfo() { SType = StructureType.ImageCreateInfo, ImageType = type, Format = format, Extent = extent, MipLevels = levels, ArrayLayers = layers, Samples = sampleCountFlags, Tiling = ImageTiling.Optimal, Usage = usage, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Flags = flags }; gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError(); if (foreignAllocation == null) { gd.Api.GetImageMemoryRequirements(device, _image, out var requirements); var allocation = gd.MemoryAllocator.AllocateDeviceMemory(physicalDevice, requirements, DefaultImageMemoryFlags); if (allocation.Memory.Handle == 0UL) { gd.Api.DestroyImage(device, _image, null); throw new Exception("Image initialization failed."); } _size = requirements.Size; gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError(); _allocationAuto = new Auto <MemoryAllocation>(allocation); _imageAuto = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image), null, _allocationAuto); InitialTransition(ImageLayout.Undefined, ImageLayout.General); } else { _foreignAllocationAuto = foreignAllocation; foreignAllocation.IncrementReferenceCount(); var allocation = foreignAllocation.GetUnsafe(); gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError(); _imageAuto = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image)); InitialTransition(ImageLayout.Preinitialized, ImageLayout.General); } }
public unsafe PointCloudBinarySource ConvertTextToBinary(string binaryPath, ProgressManager progressManager) { short pointSizeBytes = 3 * sizeof(double); double minX = 0, minY = 0, minZ = 0; double maxX = 0, maxY = 0, maxZ = 0; int pointCount = 0; using (var process = progressManager.StartProcess("ConvertTextToBinary")) { BufferInstance inputBuffer = process.AcquireBuffer(true); BufferInstance outputBuffer = process.AcquireBuffer(true); int pointsPerBuffer = outputBuffer.Length / pointSizeBytes; int usableBytesPerBuffer = pointsPerBuffer * pointSizeBytes; byte *inputBufferPtr = inputBuffer.DataPtr; byte *outputBufferPtr = outputBuffer.DataPtr; int bufferIndex = 0; int skipped = 0; using (var inputStream = StreamManager.OpenReadStream(FilePath)) { long inputLength = inputStream.Length; long estimatedOutputLength = inputLength; using (var outputStream = StreamManager.OpenWriteStream(binaryPath, estimatedOutputLength, 0, true)) { int bytesRead; int readStart = 0; while ((bytesRead = inputStream.Read(inputBuffer.Data, readStart, inputBuffer.Length - readStart)) > 0) { bytesRead += readStart; readStart = 0; int i = 0; while (i < bytesRead) { // identify line start while (i < bytesRead && (inputBufferPtr[i] == '\r' || inputBufferPtr[i] == '\n')) { ++i; } int lineStart = i; // identify line end while (i < bytesRead && inputBufferPtr[i] != '\r' && inputBufferPtr[i] != '\n') { ++i; } // handle buffer overlap if (i == bytesRead) { Array.Copy(inputBuffer.Data, lineStart, inputBuffer.Data, 0, i - lineStart); readStart = i - lineStart; break; } // this may get overwritten if this is not a valid parse double *p = (double *)(outputBufferPtr + bufferIndex); if (!ParseXYZFromLine(inputBufferPtr, lineStart, i, p)) { ++skipped; continue; } if (pointCount == 0) { minX = maxX = p[0]; minY = maxY = p[1]; minZ = maxZ = p[2]; } else { if (p[0] < minX) { minX = p[0]; } else if (p[0] > maxX) { maxX = p[0]; } if (p[1] < minY) { minY = p[1]; } else if (p[1] > maxY) { maxY = p[1]; } if (p[2] < minZ) { minZ = p[2]; } else if (p[2] > maxZ) { maxZ = p[2]; } } bufferIndex += pointSizeBytes; ++pointCount; // write usable buffer chunk if (usableBytesPerBuffer == bufferIndex) { outputStream.Write(outputBuffer.Data, 0, bufferIndex); bufferIndex = 0; } } if (!process.Update((float)inputStream.Position / inputLength)) { break; } } // write remaining buffer if (bufferIndex > 0) { outputStream.Write(outputBuffer.Data, 0, bufferIndex); } } } process.Log("Skipped {0} lines", skipped); process.LogTime("Copied {0:0,0} points", pointCount); } var extent = new Extent3D(minX, minY, minZ, maxX, maxY, maxZ); var source = new PointCloudBinarySource(this, pointCount, extent, null, 0, pointSizeBytes); return(source); }
public static System.Windows.Media.Media3D.MeshGeometry3D GenerateMesh(this PointCloudTileSource source, Grid <float> grid, Extent3D distributionExtent, bool showBackFaces) { // subtract midpoint to center around (0,0,0) Extent3D centeringExtent = source.Extent; Point3D centerOfMass = source.CenterOfMass; double centerOfMassMinusMin = centerOfMass.Z - centeringExtent.MinZ; var positions = new System.Windows.Media.Media3D.Point3DCollection(grid.CellCount); var indices = new System.Windows.Media.Int32Collection(2 * (grid.SizeX - 1) * (grid.SizeY - 1)); float fillVal = grid.FillVal; for (int x = 0; x < grid.SizeX; x++) { for (int y = 0; y < grid.SizeY; y++) { double value = grid.Data[x, y] - centerOfMassMinusMin; double xCoord = ((double)x / grid.SizeX) * distributionExtent.RangeX + distributionExtent.MinX - distributionExtent.MidpointX; double yCoord = ((double)y / grid.SizeY) * distributionExtent.RangeY + distributionExtent.MinY - distributionExtent.MidpointY; xCoord += (distributionExtent.MidpointX - centeringExtent.MidpointX); yCoord += (distributionExtent.MidpointY - centeringExtent.MidpointY); var point = new System.Windows.Media.Media3D.Point3D(xCoord, yCoord, value); positions.Add(point); if (x > 0 && y > 0) { // add two triangles int currentPosition = x * grid.SizeY + y; int topPosition = currentPosition - 1; int leftPosition = currentPosition - grid.SizeY; int topleftPosition = leftPosition - 1; if (grid.Data[x - 1, y] != fillVal && grid.Data[x, y - 1] != fillVal) { if (grid.Data[x, y] != fillVal) { indices.Add(leftPosition); indices.Add(topPosition); indices.Add(currentPosition); if (showBackFaces) { indices.Add(leftPosition); indices.Add(currentPosition); indices.Add(topPosition); } } if (grid.Data[x - 1, y - 1] != fillVal) { indices.Add(topleftPosition); indices.Add(topPosition); indices.Add(leftPosition); if (showBackFaces) { indices.Add(topleftPosition); indices.Add(leftPosition); indices.Add(topPosition); } } } } } } var normals = new System.Windows.Media.Media3D.Vector3DCollection(positions.Count); for (int i = 0; i < positions.Count; i++) { normals.Add(new System.Windows.Media.Media3D.Vector3D(0, 0, 0)); } for (int i = 0; i < indices.Count; i += 3) { int index1 = indices[i]; int index2 = indices[i + 1]; int index3 = indices[i + 2]; System.Windows.Media.Media3D.Vector3D side1 = positions[index1] - positions[index3]; System.Windows.Media.Media3D.Vector3D side2 = positions[index1] - positions[index2]; System.Windows.Media.Media3D.Vector3D normal = System.Windows.Media.Media3D.Vector3D.CrossProduct(side1, side2); normals[index1] += normal; normals[index2] += normal; normals[index3] += normal; } for (int i = 0; i < normals.Count; i++) { if (normals[i].Length > 0) { var normal = normals[i]; normal.Normalize(); // the fact that this is necessary means I am doing something wrong if (normal.Z < 0) { normal.Negate(); } normals[i] = normal; } } var geometry = new System.Windows.Media.Media3D.MeshGeometry3D { Positions = positions, TriangleIndices = indices, Normals = normals }; return(geometry); }
public static System.Windows.Media.Media3D.MeshGeometry3D GenerateMesh(this PointCloudTileSource source, Grid <float> grid, Extent3D distributionExtent) { return(GenerateMesh(source, grid, distributionExtent, false)); }
public unsafe TextureStorage( VulkanGraphicsDevice gd, PhysicalDevice physicalDevice, Device device, TextureCreateInfo info, float scaleFactor, Auto <MemoryAllocation> foreignAllocation = null) { _gd = gd; _device = device; _info = info; ScaleFactor = scaleFactor; var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format); var levels = (uint)info.Levels; var layers = (uint)info.GetLayers(); var depth = (uint)(info.Target == Target.Texture3D ? info.Depth : 1); VkFormat = format; var type = info.Target.Convert(); var extent = new Extent3D((uint)info.Width, (uint)info.Height, depth); var sampleCountFlags = ConvertToSampleCountFlags((uint)info.Samples); var usage = DefaultUsageFlags; if (info.Format.IsDepthOrStencil()) { usage |= ImageUsageFlags.ImageUsageDepthStencilAttachmentBit; } else if (info.Format.IsRtColorCompatible()) { usage |= ImageUsageFlags.ImageUsageColorAttachmentBit; } if (info.Format.IsImageCompatible()) { usage |= ImageUsageFlags.ImageUsageStorageBit; } var flags = ImageCreateFlags.ImageCreateMutableFormatBit; if (info.BlockWidth != 1 || info.BlockHeight != 1) { flags |= ImageCreateFlags.ImageCreateBlockTexelViewCompatibleBit; } bool cubeCompatible = info.Width == info.Height && layers >= 6; if (type == ImageType.ImageType2D && cubeCompatible) { flags |= ImageCreateFlags.ImageCreateCubeCompatibleBit; } if (type == ImageType.ImageType3D) { flags |= ImageCreateFlags.ImageCreate2DArrayCompatibleBit; } // System.Console.WriteLine("create image " + type + " " + format + " " + levels + " " + layers + " " + usage + " " + flags); var imageCreateInfo = new ImageCreateInfo() { SType = StructureType.ImageCreateInfo, ImageType = type, Format = format, Extent = extent, MipLevels = levels, ArrayLayers = layers, Samples = sampleCountFlags, Tiling = ImageTiling.Optimal, Usage = usage, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Flags = flags }; gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError(); if (foreignAllocation == null) { gd.Api.GetImageMemoryRequirements(device, _image, out var requirements); var allocation = gd.MemoryAllocator.AllocateDeviceMemory(physicalDevice, requirements); if (allocation.Memory.Handle == 0UL) { gd.Api.DestroyImage(device, _image, null); throw new Exception("Image initialization failed."); } gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError(); _allocationAuto = new Auto <MemoryAllocation>(allocation); _imageAuto = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image), null, _allocationAuto); InitialTransition(ImageLayout.Undefined, ImageLayout.General); } else { var allocation = foreignAllocation.GetUnsafe(); gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError(); _imageAuto = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image)); InitialTransition(ImageLayout.Preinitialized, ImageLayout.General); } }
/// <summary> /// This will only work if point format, point length, offset, and scale are identical. /// </summary> public LASHeader(LASHeader[] headers, LASVLR[] vlrs, LASEVLR[] evlrs) { var header = headers[0]; var extent = headers.Select(h => h.m_extent).Union3D(); var points = (ulong)headers.Sum(h => (long)h.m_numberOfPointRecords); var pointsByReturn = new ulong[15]; for (var i = 0; i < pointsByReturn.Length; i++) { pointsByReturn[i] = (ulong)headers.Sum(h => (long)h.m_numberOfPointsByReturn[i]); } uint legacyPoints = 0; uint[] legacyPointsByReturn; if (points > uint.MaxValue) { legacyPoints = 0; legacyPointsByReturn = new uint[5]; } else { legacyPoints = (uint)points; legacyPointsByReturn = pointsByReturn.Take(5).Select(c => (uint)c).ToArray(); } m_fileSourceID = header.m_fileSourceID; m_globalEncoding = header.m_globalEncoding; m_projectID = header.m_projectID; m_version = LASVersionInfo.Create(LASVersion.LAS_1_4); m_systemIdentifier = header.m_systemIdentifier; m_generatingSoftware = header.m_generatingSoftware; m_fileCreationDayOfYear = header.m_fileCreationDayOfYear; m_fileCreationYear = header.m_fileCreationYear; m_headerSize = c_minHeaderSize[LASVersion.LAS_1_4]; m_offsetToPointData = m_headerSize + (uint)vlrs.Sum(vlr => vlr.Length); m_numberOfVariableLengthRecords = (uint)vlrs.Length; m_pointDataRecordFormat = header.m_pointDataRecordFormat; m_pointDataRecordLength = header.m_pointDataRecordLength; if (points > uint.MaxValue) { m_legacyNumberOfPointRecords = 0; m_legacyNumberOfPointsByReturn = new uint[5]; } else { m_legacyNumberOfPointRecords = legacyPoints; m_legacyNumberOfPointsByReturn = legacyPointsByReturn; } m_quantization = header.m_quantization; m_extent = extent; m_startOfWaveformDataPacketRecord = 0; m_startOfFirstExtendedVariableLengthRecord = m_offsetToPointData + (points * m_pointDataRecordLength); m_numberOfExtendedVariableLengthRecords = (uint)evlrs.Length; m_numberOfPointRecords = points; m_numberOfPointsByReturn = pointsByReturn; }
public LASHeader(BinaryReader reader) { long length = reader.BaseStream.Length; if (length < c_minHeaderSize[LASVersion.LAS_1_0]) { throw new OpenFailedException("Invalid format: header too short"); } if (Encoding.ASCII.GetString(reader.ReadBytes(FILE_SIGNATURE.Length)) != FILE_SIGNATURE) { throw new OpenFailedException("Invalid format: signature does not match"); } m_fileSourceID = reader.ReadUInt16(); m_globalEncoding = reader.ReadLASGlobalEncoding(); m_projectID = reader.ReadLASProjectID(); m_version = reader.ReadLASVersionInfo(); m_systemIdentifier = reader.ReadBytes(32).ToAsciiString(); m_generatingSoftware = reader.ReadBytes(32).ToAsciiString(); m_fileCreationDayOfYear = reader.ReadUInt16(); m_fileCreationYear = reader.ReadUInt16(); m_headerSize = reader.ReadUInt16(); m_offsetToPointData = reader.ReadUInt32(); ushort minHeaderSize = c_minHeaderSize[m_version.Version]; if (length < minHeaderSize) { throw new OpenFailedException("Invalid format: header too short for version"); } if (minHeaderSize > m_headerSize) { throw new OpenFailedException("Invalid format: header size incorrect"); } m_numberOfVariableLengthRecords = reader.ReadUInt32(); m_pointDataRecordFormat = reader.ReadByte(); m_pointDataRecordLength = reader.ReadUInt16(); m_legacyNumberOfPointRecords = reader.ReadUInt32(); m_legacyNumberOfPointsByReturn = reader.ReadUInt32Array(5); m_quantization = reader.ReadSQuantization3D(); m_extent = reader.ReadExtent3D(); if (m_version.Version >= LASVersion.LAS_1_3) { m_startOfWaveformDataPacketRecord = reader.ReadUInt64(); } if (m_version.Version >= LASVersion.LAS_1_4) { m_startOfFirstExtendedVariableLengthRecord = reader.ReadUInt64(); m_numberOfExtendedVariableLengthRecords = reader.ReadUInt32(); m_numberOfPointRecords = reader.ReadUInt64(); m_numberOfPointsByReturn = reader.ReadUInt64Array(15); } else { m_numberOfPointRecords = m_legacyNumberOfPointRecords; m_numberOfPointsByReturn = new ulong[15]; for (int i = 0; i < m_legacyNumberOfPointsByReturn.Length; i++) { m_numberOfPointsByReturn[i] = m_legacyNumberOfPointsByReturn[i]; } } // This doesn't apply to LAZ files //ulong pointDataRegionLength = (ulong)length - m_offsetToPointData; //if (pointDataRegionLength < m_pointDataRecordLength * PointCount) // throw new Exception("Invalid format: point data region is not the expected size"); }
public LAZBinarySource(FileHandlerBase file, long count, Extent3D extent, SQuantization3D quantization, long dataOffset, short pointSizeBytes) : base(file, count, extent, quantization, dataOffset, pointSizeBytes) { m_handler = (LAZFile)file; }
string Format(Extent3D extent3D) => $"({extent3D.Width}, {extent3D.Height}, {extent3D.Depth})";
private unsafe CommandBuffer BeginImageCommandBuffer() { Device device = _renderer.Params.Device; Vk vk = _renderer.Vk; CommandBufferAllocateInfo commandBufferAllocateInfo = new() { SType = StructureType.CommandBufferAllocateInfo, CommandBufferCount = 1, CommandPool = _renderer.ImageTransitionPool }; _renderer.AssertVulkan(vk.AllocateCommandBuffers(device, commandBufferAllocateInfo, out CommandBuffer commandBuffer)); CommandBufferBeginInfo commandBufferBeginInfo = new() { SType = StructureType.CommandBufferBeginInfo, Flags = CommandBufferUsageFlags.CommandBufferUsageOneTimeSubmitBit, PInheritanceInfo = null }; _renderer.AssertVulkan(vk.BeginCommandBuffer(commandBuffer, commandBufferBeginInfo)); return(commandBuffer); } private unsafe void EndImageCommandBuffer(CommandBuffer commandBuffer) { Device device = _renderer.Params.Device; Vk vk = _renderer.Vk; _renderer.AssertVulkan(vk.EndCommandBuffer(commandBuffer)); SubmitInfo submitInfo = new() { SType = StructureType.SubmitInfo, CommandBufferCount = 1, PCommandBuffers = &commandBuffer, SignalSemaphoreCount = 0, PSignalSemaphores = null, WaitSemaphoreCount = 0, PWaitSemaphores = null, PWaitDstStageMask = null }; _renderer.AssertVulkan(vk.QueueSubmit(_renderer.ImageTransitionQueue, 1, submitInfo, default)); _renderer.AssertVulkan(vk.QueueWaitIdle(_renderer.ImageTransitionQueue)); vk.FreeCommandBuffers(device, _renderer.ImageTransitionPool, 1, commandBuffer); } private unsafe void TransitionImageLayout(ImageLayout oldLayout, ImageLayout newLayout) { Vk vk = _renderer.Vk; CommandBuffer commandBuffer = BeginImageCommandBuffer(); ImageMemoryBarrier imageMemoryBarrier = new() { SType = StructureType.ImageMemoryBarrier, OldLayout = oldLayout, NewLayout = newLayout, SrcQueueFamilyIndex = Vk.QueueFamilyIgnored, DstQueueFamilyIndex = Vk.QueueFamilyIgnored, Image = _image, SubresourceRange = new ImageSubresourceRange() { AspectMask = ImageAspectFlags.ImageAspectColorBit, BaseArrayLayer = 0, LayerCount = 1, BaseMipLevel = 0, LevelCount = _mipLevelCount }, SrcAccessMask = 0, DstAccessMask = 0 }; if ((oldLayout == ImageLayout.Undefined) && (newLayout == ImageLayout.TransferDstOptimal)) { imageMemoryBarrier.SrcAccessMask = 0; imageMemoryBarrier.DstAccessMask = AccessFlags.AccessTransferWriteBit; vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTopOfPipeBit, PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1, imageMemoryBarrier); } else if ((oldLayout == ImageLayout.TransferDstOptimal) && (newLayout == ImageLayout.ShaderReadOnlyOptimal)) { imageMemoryBarrier.SrcAccessMask = AccessFlags.AccessTransferWriteBit; imageMemoryBarrier.DstAccessMask = AccessFlags.AccessShaderReadBit; vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTransferBit, PipelineStageFlags.PipelineStageFragmentShaderBit, 0, 0, null, 0, null, 1, imageMemoryBarrier); } else if ((oldLayout == ImageLayout.ShaderReadOnlyOptimal) && (newLayout == ImageLayout.TransferDstOptimal)) { imageMemoryBarrier.SrcAccessMask = AccessFlags.AccessShaderReadBit; imageMemoryBarrier.DstAccessMask = AccessFlags.AccessTransferWriteBit; vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageFragmentShaderBit, PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1, imageMemoryBarrier); } EndImageCommandBuffer(commandBuffer); } private void CopyBufferToImage(Buffer <byte> source) { Vk vk = _renderer.Vk; CommandBuffer commandBuffer = BeginImageCommandBuffer(); BufferImageCopy bufferImageCopy = new() { BufferOffset = 0, BufferRowLength = 0, BufferImageHeight = 0, ImageSubresource = new ImageSubresourceLayers() { AspectMask = ImageAspectFlags.ImageAspectColorBit, MipLevel = 0, BaseArrayLayer = 0, LayerCount = 1 }, ImageOffset = new Offset3D() { X = 0, Y = 0, Z = 0 }, ImageExtent = new Extent3D() { Width = Size.X, Height = Size.Y, Depth = 1 } }; vk.CmdCopyBufferToImage(commandBuffer, source.Handle, _image, ImageLayout.TransferDstOptimal, 1, bufferImageCopy); EndImageCommandBuffer(commandBuffer); }
private void CopyFromOrToBuffer( CommandBuffer commandBuffer, VkBuffer buffer, Image image, int size, bool to, int dstLayer, int dstLevel, int dstLayers, int dstLevels, bool singleSlice) { bool is3D = Info.Target == Target.Texture3D; int width = Info.Width; int height = Info.Height; int depth = is3D && !singleSlice ? Info.Depth : 1; int layer = is3D ? 0 : dstLayer; int layers = dstLayers; int levels = dstLevels; int offset = 0; for (int level = 0; level < levels; level++) { int mipSize = GetBufferDataLength(Info.GetMipSize(level)); int endOffset = offset + mipSize; if ((uint)endOffset > (uint)size) { break; } int rowLength = (Info.GetMipStride(level) / Info.BytesPerPixel) * Info.BlockWidth; var aspectFlags = Info.Format.ConvertAspectFlags(); if (aspectFlags == (ImageAspectFlags.ImageAspectDepthBit | ImageAspectFlags.ImageAspectStencilBit)) { aspectFlags = ImageAspectFlags.ImageAspectDepthBit; } var sl = new ImageSubresourceLayers( aspectFlags, (uint)(FirstLevel + dstLevel + level), (uint)(FirstLayer + layer), (uint)layers); var extent = new Extent3D((uint)width, (uint)height, (uint)depth); int z = is3D ? dstLayer : 0; var region = new BufferImageCopy((ulong)offset, (uint)rowLength, (uint)height, sl, new Offset3D(0, 0, z), extent); if (to) { _gd.Api.CmdCopyImageToBuffer(commandBuffer, image, ImageLayout.General, buffer, 1, region); } else { _gd.Api.CmdCopyBufferToImage(commandBuffer, buffer, image, ImageLayout.General, 1, region); } offset += mipSize; width = Math.Max(1, width >> 1); height = Math.Max(1, height >> 1); if (Info.Target == Target.Texture3D) { depth = Math.Max(1, depth >> 1); } } }
public unsafe void ComputeExtent(ProgressManager progressManager) { using (var process = progressManager.StartProcess("CalculateLASExtent")) { short pointSizeBytes = PointSizeBytes; int minX = 0, minY = 0, minZ = 0; int maxX = 0, maxY = 0, maxZ = 0; foreach (var chunk in GetBlockEnumerator(process)) { if (minX == 0 && maxX == 0) { var p = (SQuantizedPoint3D *)chunk.PointDataPtr; minX = maxX = (*p).X; minY = maxY = (*p).Y; minZ = maxZ = (*p).Z; } byte *pb = chunk.PointDataPtr; while (pb < chunk.PointDataEndPtr) { var p = (SQuantizedPoint3D *)pb; if ((*p).X < minX) { minX = (*p).X; } else if ((*p).X > maxX) { maxX = (*p).X; } if ((*p).Y < minY) { minY = (*p).Y; } else if ((*p).Y > maxY) { maxY = (*p).Y; } if ((*p).Z < minZ) { minZ = (*p).Z; } else if ((*p).Z > maxZ) { maxZ = (*p).Z; } pb += pointSizeBytes; } if (!process.Update(chunk)) { break; } } var quantizedExtent = new SQuantizedExtent3D(minX, minY, minZ, maxX, maxY, maxZ); m_extent = m_header.Quantization.Convert(quantizedExtent); process.LogTime("Traversed {0:0,0} points", Count); } }