// Size in bytes, and the usages private protected Buffer(uint size, BufferType type, Vk.BufferUsages usages) { Device = SpectrumApp.Instance.GraphicsDevice; Size = size; Type = type; // Create the buffer var bci = new Vk.BufferCreateInfo( size, Vk.BufferUsages.TransferDst | Vk.BufferUsages.TransferSrc | usages, flags: Vk.BufferCreateFlags.None, sharingMode: Vk.SharingMode.Exclusive ); VkBuffer = Device.VkDevice.CreateBuffer(bci); // Create the backing memory var memReq = VkBuffer.GetMemoryRequirements(); var memIdx = Device.FindMemoryTypeIndex(memReq.MemoryTypeBits, Vk.MemoryProperties.DeviceLocal); if (memIdx == -1) { throw new InvalidOperationException("Cannot find a memory type that supports buffers (this means bad or out-of-date hardware)"); } var mai = new Vk.MemoryAllocateInfo(memReq.Size, memIdx); VkMemory = Device.VkDevice.AllocateMemory(mai); VkBuffer.BindMemory(VkMemory); }
/// <summary> /// Initializes a new instance of the <see cref="MappedMemoryRange"/> structure. /// </summary> /// <param name="memory">The memory object to which this range belongs.</param> /// <param name="offset">The zero-based byte offset from the beginning of the memory object.</param> /// <param name="size"> /// Is either the size of range, or <see cref="WholeSize"/> to affect the range from offset /// to the end of the current mapping of the allocation. /// </param> public MappedMemoryRange(DeviceMemory memory, long offset = 0, long size = WholeSize) { Type = StructureType.MappedMemoryRange; Next = IntPtr.Zero; Memory = memory; Offset = offset; Size = size; }
/// <summary> /// Initializes a new instance of the <see cref="SparseMemoryBind"/> structure. /// </summary> /// <param name="resourceOffset">The offset into the resource.</param> /// <param name="size">The size of the memory region to be bound.</param> /// <param name="memory"> /// The <see cref="DeviceMemory"/> object that the range of the resource is bound to. If /// memory 0, the range is unbound. /// </param> /// <param name="memoryOffset"> /// The offset into the <see cref="DeviceMemory"/> object to bind the resource range to. If /// memory is 0, this value is ignored. /// </param> /// <param name="flags">A bitmask specifying usage of the binding operation.</param> public SparseMemoryBind(long resourceOffset, long size, DeviceMemory memory = null, long memoryOffset = 0, SparseMemoryBindFlags flags = 0) { ResourceOffset = resourceOffset; Size = size; Memory = memory; MemoryOffset = memoryOffset; Flags = flags; }
/// <summary> /// Bind device memory to a buffer object. /// <para>Must not already be backed by a memory object.</para> /// <para>Must not have been created with any sparse memory binding flags.</para> /// </summary> /// <param name="memory">The object describing the device memory to attach.</param> /// <param name="memoryOffset"> /// The start offset of the region of memory which is to be bound to the buffer. The number /// of bytes returned in the <see cref="MemoryRequirements.Size"/> member in memory, starting /// from <paramref name="memoryOffset"/> bytes, will be bound to the specified buffer. /// </param> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public void BindMemory(DeviceMemory memory, long memoryOffset = 0) { Result result = vkBindBufferMemory(Parent, this, memory, memoryOffset); VulkanException.ThrowForInvalidResult(result); }
private protected Texture(TextureType type, uint w, uint h, uint d, uint layers) { Device = SpectrumApp.Instance.GraphicsDevice; Type = type; Width = w; Height = h; Depth = d; Layers = layers; // Limits checking if (w == 0) { throw new ArgumentOutOfRangeException(nameof(w), "A texture cannot have a width of zero"); } if (h == 0) { throw new ArgumentOutOfRangeException(nameof(h), "A texture cannot have a height of zero"); } if (d == 0) { throw new ArgumentOutOfRangeException(nameof(d), "A texture cannot have a depth of zero"); } if (layers == 0) { throw new ArgumentOutOfRangeException(nameof(layers), "A texture cannot have 0 layers"); } if (type == TextureType.Texture3D && layers != 1) { throw new ArgumentOutOfRangeException(nameof(layers), "3D textures cannot be arrays"); } if (layers > Limits.MaxTextureLayers) { throw new ArgumentOutOfRangeException(nameof(layers), $"The texture array count ({layers}) is too big for the device ({Limits.MaxTextureLayers})"); } switch (type) { case TextureType.Texture1D: if (w > Limits.MaxTextureSize1D) { throw new ArgumentOutOfRangeException( nameof(w), $"The 1D texture size ({w}) is too big for the device ({Limits.MaxTextureSize1D})" ); } break; case TextureType.Texture2D: if (w > Limits.MaxTextureSize2D || h > Limits.MaxTextureSize2D) { throw new ArgumentOutOfRangeException( nameof(w), $"The 2D texture size ({w}x{h}) is too big for the device ({Limits.MaxTextureSize2D})" ); } break; case TextureType.Texture3D: if (w > Limits.MaxTextureSize3D || h > Limits.MaxTextureSize3D || d > Limits.MaxTextureSize3D) { throw new ArgumentOutOfRangeException( nameof(w), $"The 3D texture size ({w}x{h}x{d}) is too big for the device ({Limits.MaxTextureSize3D})" ); } break; } // Create the image var ici = new Vk.ImageCreateInfo { ImageType = (Vk.ImageType)type, Extent = new Vk.Extent3D((int)w, (int)h, (int)d), MipLevels = 1, ArrayLayers = (int)layers, Format = Vk.Format.R8G8B8A8UNorm, Tiling = Vk.ImageTiling.Optimal, InitialLayout = Vk.ImageLayout.Undefined, Usage = Vk.ImageUsages.TransferDst | Vk.ImageUsages.Sampled | Vk.ImageUsages.TransferSrc, SharingMode = Vk.SharingMode.Exclusive, Samples = Vk.SampleCounts.Count1, Flags = Vk.ImageCreateFlags.None }; VkImage = Device.VkDevice.CreateImage(ici); // Create the backing memory for the image var memReq = VkImage.GetMemoryRequirements(); var memIdx = Device.FindMemoryTypeIndex(memReq.MemoryTypeBits, Vk.MemoryProperties.DeviceLocal); if (memIdx == -1) { throw new InvalidOperationException("Cannot find a memory type that supports textures (this means bad or out-of-date hardware)"); } var mai = new Vk.MemoryAllocateInfo(memReq.Size, memIdx); VkMemory = Device.VkDevice.AllocateMemory(mai); DataSize = (uint)memReq.Size; VkImage.BindMemory(VkMemory); // Create the view var vci = new Vk.ImageViewCreateInfo( Vk.Format.R8G8B8A8UNorm, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, (int)Layers), viewType: GetViewType(Type, layers) ); VkView = VkImage.CreateView(vci); // Make the initial layout transition Device.SubmitScratchCommand(buf => { buf.CmdPipelineBarrier(Vk.PipelineStages.AllGraphics, Vk.PipelineStages.AllGraphics, imageMemoryBarriers: new[] { new Vk.ImageMemoryBarrier( VkImage, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.None, Vk.Accesses.ShaderRead, Vk.ImageLayout.Undefined, Vk.ImageLayout.ShaderReadOnlyOptimal ) }); }); }