예제 #1
0
        internal Block AllocateAndBind(VulkanCore.Image image, Chunk.Location location)
        {
            ThrowIfDisposed();

            var   memRequirements = image.GetMemoryRequirements();
            Block block           = Allocate(location, memRequirements);

            image.BindMemory(block.Container.Memory, block.Offset);
            return(block);
        }
예제 #2
0
 // Starts a transfer of raw data from the host to a device image
 // Unlike the buffers, which are easy to divide into blocks, it is very difficult to divide 3D spaces into blocks
 //   with alignment and size constraints. For now, we see if we can easily upload the entire image region with the
 //   existing staging buffer, otherwise we allocate a massive temp buffer to upload the data all at once with.
 //   Yes, this is inefficient. Yes, this is slow. Yes, I hate this as much as you do.
 //   We will improve this once the library is in a usable state.
 //   As it stands, we do have 16MB available, which is a 2048x2048 image before the temp buffers are created.
 public unsafe static void PushImage(byte *src, uint length, TextureType type, Vk.Image dst, in Vk.Offset3D dstOff, in Vk.Extent3D dstSize, uint layer, uint layerCount)
예제 #3
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
                                                                                                                                      ) });
            });
        }