Ejemplo n.º 1
0
        // 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);
        }
Ejemplo n.º 2
0
 /// <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;
 }
Ejemplo n.º 3
0
 /// <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;
 }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        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
                                                                                                                                      ) });
            });
        }