/// <summary> /// Initializes a new instance of the <see cref="ImageSubresourceRange"/> structure. /// </summary> /// <param name="aspectMask"> /// A bitmask indicating which aspect(s) of the image are included in the view. /// </param> /// <param name="baseMipLevel">The first mipmap level accessible to the view.</param> /// <param name="levelCount"> /// The number of mipmap levels (starting from <see cref="BaseMipLevel"/>) accessible to the view. /// </param> /// <param name="baseArrayLayer">The first array layer accessible to the view.</param> /// <param name="layerCount"> /// The number of array layers (starting from <see cref="BaseArrayLayer"/>) accessible to the view. /// </param> public ImageSubresourceRange(ImageAspects aspectMask, int baseMipLevel, int levelCount, int baseArrayLayer, int layerCount) { AspectMask = aspectMask; BaseMipLevel = baseMipLevel; LevelCount = levelCount; BaseArrayLayer = baseArrayLayer; LayerCount = layerCount; }
void IInternalTexture.Upload( HostBuffer stagingBuffer, TransientExecutor executor, Image image, ImageAspects aspects) { if (stagingBuffer == null) { throw new ArgumentNullException(nameof(stagingBuffer)); } if (executor == null) { throw new ArgumentNullException(nameof(executor)); } //Write all the faces to the staging buffer and create copy commands long offset = 0; BufferImageCopy[] copyRegions = new BufferImageCopy[faces.Length]; for (int i = 0; i < faces.Length; i++) { copyRegions[i] = new BufferImageCopy { BufferOffset = offset, BufferRowLength = 0, BufferImageHeight = 0, ImageSubresource = new ImageSubresourceLayers( aspectMask: aspects, mipLevel: 0, baseArrayLayer: i, layerCount: 1), ImageOffset = new Offset3D(x: 0, y: 0, z: 0), ImageExtent = new Extent3D( width: size.X, height: size.Y, depth: 1) }; offset += faces[i].Write(stagingBuffer, offset); } //Copy our staging buffer to the image executor.ExecuteBlocking(commandBuffer => { commandBuffer.CmdCopyBufferToImage( srcBuffer: stagingBuffer.VulkanBuffer, dstImage: image, dstImageLayout: ImageLayout.TransferDstOptimal, regions: copyRegions); }); }
private static void BlitImage( ImageAspects aspectMask, Image fromImage, IntRect fromRegion, int fromMipLevel, int fromLayerCount, Image toImage, IntRect toRegion, int toMipLevel, int toLayerCount, TransientExecutor executor) { ImageBlit blit = new ImageBlit { SrcSubresource = new ImageSubresourceLayers( aspectMask, fromMipLevel, baseArrayLayer: 0, fromLayerCount), SrcOffset1 = new Offset3D(fromRegion.Min.X, fromRegion.Min.Y, 0), SrcOffset2 = new Offset3D(fromRegion.Max.X, fromRegion.Max.Y, 1), DstSubresource = new ImageSubresourceLayers( aspectMask, toMipLevel, baseArrayLayer: 0, toLayerCount), DstOffset1 = new Offset3D(toRegion.Min.X, toRegion.Min.Y, 0), DstOffset2 = new Offset3D(toRegion.Max.X, toRegion.Max.Y, 1) }; //Execute the blit executor.ExecuteBlocking(commandBuffer => { commandBuffer.CmdBlitImage( srcImage: fromImage, srcImageLayout: ImageLayout.TransferSrcOptimal, dstImage: toImage, dstImageLayout: ImageLayout.TransferDstOptimal, regions: new [] { blit }, filter: Filter.Linear); }); }
private static ImageView CreateView( Image image, Format format, int mipLevels, ImageAspects aspects, bool cubeMap) => image.CreateView(new ImageViewCreateInfo( format: format, subresourceRange: new ImageSubresourceRange( aspectMask: aspects, baseMipLevel: 0, levelCount: mipLevels, baseArrayLayer: 0, layerCount: cubeMap ? 6 : 1), viewType: cubeMap ? ImageViewType.ImageCube : ImageViewType.Image2D, components: new ComponentMapping( r: ComponentSwizzle.R, g: ComponentSwizzle.G, b: ComponentSwizzle.B, a: ComponentSwizzle.A)));
private DeviceTexture( Int2 size, Format format, ImageLayout desiredLayout, int mipLevels, ImageAspects aspects, Image image, Block?memory, ImageView view, bool disposeImage = true) { this.size = size; this.format = format; this.desiredLayout = desiredLayout; this.mipLevels = mipLevels; this.aspects = aspects; this.image = image; this.memory = memory; this.view = view; this.disposeImage = disposeImage; }
void IInternalTexture.Upload( HostBuffer stagingBuffer, TransientExecutor executor, Image image, ImageAspects aspects) { if (stagingBuffer == null) { throw new ArgumentNullException(nameof(stagingBuffer)); } if (executor == null) { throw new ArgumentNullException(nameof(executor)); } //Write to the staging buffer stagingBuffer.Write(pixels, offset: 0); //Copy the staging buffer to the image executor.ExecuteBlocking(commandBuffer => { commandBuffer.CmdCopyBufferToImage( srcBuffer: stagingBuffer.VulkanBuffer, dstImage: image, dstImageLayout: ImageLayout.TransferDstOptimal, regions: new BufferImageCopy { BufferOffset = 0, BufferRowLength = 0, BufferImageHeight = 0, ImageSubresource = new ImageSubresourceLayers( aspectMask: aspects, 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) }); }); }
private static void TransitionImageLayout( Image image, ImageAspects aspectMask, int baseMipLevel, int mipLevels, int baseLayer, int layers, ImageLayout oldLayout, ImageLayout newLayout, TransientExecutor executor) { //Get where this transition has to wait and what has to wait for this transition Accesses sourceAccess, destinationAccess; PipelineStages sourcePipelineStages, destinationPipelineStages; if (oldLayout == ImageLayout.Undefined && newLayout == ImageLayout.TransferDstOptimal) { sourceAccess = Accesses.None; destinationAccess = Accesses.TransferWrite; sourcePipelineStages = PipelineStages.TopOfPipe; destinationPipelineStages = PipelineStages.Transfer; } else if (oldLayout == ImageLayout.Undefined && newLayout == ImageLayout.DepthStencilAttachmentOptimal) { sourceAccess = Accesses.None; destinationAccess = Accesses.DepthStencilAttachmentRead | Accesses.DepthStencilAttachmentWrite; sourcePipelineStages = PipelineStages.TopOfPipe; destinationPipelineStages = PipelineStages.EarlyFragmentTests; } else if (oldLayout == ImageLayout.Undefined && newLayout == ImageLayout.ColorAttachmentOptimal) { sourceAccess = Accesses.None; destinationAccess = Accesses.ColorAttachmentRead | Accesses.ColorAttachmentWrite; sourcePipelineStages = PipelineStages.TopOfPipe; destinationPipelineStages = PipelineStages.ColorAttachmentOutput; } else if (oldLayout == ImageLayout.TransferDstOptimal && newLayout == ImageLayout.TransferSrcOptimal) { sourceAccess = Accesses.TransferWrite; destinationAccess = Accesses.TransferRead; sourcePipelineStages = PipelineStages.Transfer; destinationPipelineStages = PipelineStages.Transfer; } else if (oldLayout == ImageLayout.TransferDstOptimal && newLayout == ImageLayout.ShaderReadOnlyOptimal) { sourceAccess = Accesses.TransferWrite; destinationAccess = Accesses.ShaderRead; sourcePipelineStages = PipelineStages.Transfer; destinationPipelineStages = PipelineStages.FragmentShader; } else if (oldLayout == ImageLayout.TransferSrcOptimal && newLayout == ImageLayout.ShaderReadOnlyOptimal) { sourceAccess = Accesses.TransferRead; destinationAccess = Accesses.ShaderRead; sourcePipelineStages = PipelineStages.Transfer; destinationPipelineStages = PipelineStages.FragmentShader; } else { throw new Exception( $"[{nameof(DeviceTexture)}] Unsupported image transition: from: {oldLayout} to: {newLayout}"); } //Create the transition barrier var imageMemoryBarrier = new ImageMemoryBarrier( image: image, subresourceRange: new ImageSubresourceRange( aspectMask: aspectMask, baseMipLevel: baseMipLevel, levelCount: mipLevels, baseArrayLayer: baseLayer, layerCount: layers), srcAccessMask: sourceAccess, dstAccessMask: destinationAccess, oldLayout: oldLayout, newLayout: newLayout); //Execute the barrier executor.ExecuteBlocking(commandBuffer => { commandBuffer.CmdPipelineBarrier( srcStageMask: sourcePipelineStages, dstStageMask: destinationPipelineStages, dependencyFlags: Dependencies.None, memoryBarriers: null, bufferMemoryBarriers: null, imageMemoryBarriers: new [] { imageMemoryBarrier }); }); }
/// <summary> /// Initializes a new instance of <see cref="ImageSubresource"/> structure. /// </summary> /// <param name="aspectMask">An <see cref="ImageAspects"/> selecting the image aspect.</param> /// <param name="mipLevel">Selects the mipmap level.</param> /// <param name="arrayLayer">Selects the array layer.</param> public ImageSubresource(ImageAspects aspectMask, int mipLevel, int arrayLayer) { AspectMask = aspectMask; MipLevel = mipLevel; ArrayLayer = arrayLayer; }