void CreateImage(int width, int height,
                         VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties,
                         out VkImage image, out VkDeviceMemory memory)
        {
            var info = new VkImageCreateInfo();

            info.imageType     = VkImageType._2D;
            info.extent.width  = width;
            info.extent.height = height;
            info.extent.depth  = 1;
            info.mipLevels     = 1;
            info.arrayLayers   = 1;
            info.format        = format;
            info.tiling        = tiling;
            info.initialLayout = VkImageLayout.Undefined;
            info.usage         = usage;
            info.sharingMode   = VkSharingMode.Exclusive;
            info.samples       = VkSampleCountFlags._1_Bit;

            image = new VkImage(device, info);

            var req = image.Requirements;

            var allocInfo = new VkMemoryAllocateInfo();

            allocInfo.allocationSize  = req.size;
            allocInfo.memoryTypeIndex = FindMemoryType(req.memoryTypeBits, properties);

            memory = new VkDeviceMemory(device, allocInfo);

            image.Bind(memory, 0);
        }
Exemple #2
0
        /// <summary>
        /// Create a new Image.
        /// </summary>
        /// <remarks>Initial layout will be automatically set to Undefined if tiling is optimal and Preinitialized if tiling is linear.</remarks>
        /// <param name="device">The logical device that create the image.</param>
        /// <param name="format">format and type of the texel blocks that will be contained in the image</param>
        /// <param name="usage">bitmask describing the intended usage of the image.</param>
        /// <param name="_memoryPropertyFlags">Memory property flags.</param>
        /// <param name="width">number of data in the X dimension of the image.</param>
        /// <param name="height">number of data in the Y dimension of the image.</param>
        /// <param name="type">value specifying the basic dimensionality of the image. Layers in array textures do not count as a dimension for the purposes of the image type.</param>
        /// <param name="samples">number of sample per texel.</param>
        /// <param name="tiling">tiling arrangement of the texel blocks in memory.</param>
        /// <param name="mipsLevels">describes the number of levels of detail available for minified sampling of the image.</param>
        /// <param name="layers">number of layers in the image.</param>
        /// <param name="depth">number of data in the Z dimension of the image</param>
        /// <param name="createFlags">bitmask describing additional parameters of the image.</param>
        /// <param name="sharingMode">value specifying the sharing mode of the image when it will be accessed by multiple queue families.</param>
        /// <param name="queuesFamillies">list of queue families that will access this image (ignored if sharingMode is not CONCURRENT).</param>
        public Image(Device device, VkFormat format, VkImageUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags,
                     uint width, uint height,
                     VkImageType type               = VkImageType.Image2D, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1,
                     VkImageTiling tiling           = VkImageTiling.Optimal, uint mipsLevels          = 1, uint layers = 1, uint depth = 1,
                     VkImageCreateFlags createFlags = 0, VkSharingMode sharingMode                    = VkSharingMode.Exclusive, params uint[] queuesFamillies)
            : base(device, _memoryPropertyFlags)
        {
            info.imageType     = type;
            info.format        = format;
            info.extent.width  = width;
            info.extent.height = height;
            info.extent.depth  = depth;
            info.mipLevels     = mipsLevels;
            info.arrayLayers   = layers;
            info.samples       = samples;
            info.tiling        = tiling;
            info.usage         = usage;
            info.initialLayout = (tiling == VkImageTiling.Optimal) ? VkImageLayout.Undefined : VkImageLayout.Preinitialized;
            info.sharingMode   = sharingMode;
            info.flags         = createFlags;

            this.queueFalillies = queuesFamillies;
            lastKnownLayout     = info.initialLayout;

            Activate();
        }
Exemple #3
0
        /// <summary>
        /// create host visible linear image without command from data pointed by IntPtr pointer containing full image file (jpg, png,...)
        /// </summary>
        public static Image Load(Device dev,
                                 IntPtr bitmap, ulong bitmapByteCount, VkImageUsageFlags usage = VkImageUsageFlags.TransferSrc,
                                 VkFormat format = VkFormat.Undefined,
                                 VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                 VkImageTiling tiling  = VkImageTiling.Linear, bool generateMipmaps = false,
                                 VkImageType imageType = VkImageType.Image2D)
        {
            if (format == VkFormat.Undefined)
            {
                format = DefaultTextureFormat;
            }
            if (generateMipmaps)
            {
                usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst);
            }

            using (StbImage stbi = new StbImage(bitmap, bitmapByteCount)) {
                uint mipLevels = generateMipmaps ? ComputeMipLevels(stbi.Width, stbi.Height) : 1;

                Image img = new Image(dev, format, usage, memoryProps, (uint)stbi.Width, (uint)stbi.Height, imageType,
                                      VkSampleCountFlags.SampleCount1, tiling, mipLevels);

                img.Map();
                stbi.CoptyTo(img.MappedData);
                img.Unmap();

                return(img);
            }
        }
Exemple #4
0
        /// <summary>
        /// create host visible linear image without command from path
        /// </summary>
        public static Image Load(Device dev,
                                 string path, VkFormat format      = VkFormat.Undefined, bool reserveSpaceForMipmaps = true,
                                 VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                 VkImageTiling tiling    = VkImageTiling.Linear,
                                 VkImageType imageType   = VkImageType.Image2D,
                                 VkImageUsageFlags usage = VkImageUsageFlags.Sampled)
        {
            if (format == VkFormat.Undefined)
            {
                format = DefaultTextureFormat;
            }

            int    width, height, channels;
            IntPtr imgPtr = Stb.Load(path, out width, out height, out channels, 4);

            if (imgPtr == IntPtr.Zero)
            {
                throw new Exception($"File not found: {path}.");
            }

            long size      = width * height * 4;
            uint mipLevels = reserveSpaceForMipmaps ? (uint)Math.Floor(Math.Log(Math.Max(width, height))) + 1 : 1;

            Image img = new Image(dev, format, usage, memoryProps, (uint)width, (uint)height, imageType, VkSampleCountFlags.SampleCount1, tiling, mipLevels);

            img.Map();
            unsafe {
                System.Buffer.MemoryCopy(imgPtr.ToPointer(), img.MappedData.ToPointer(), size, size);
            }
            img.Unmap();

            Stb.FreeImage(imgPtr);

            return(img);
        }
Exemple #5
0
        /// <summary>
        /// Load bitmap into Image with stagging and mipmap generation if necessary
        /// and usage.
        /// </summary>
        public static Image Load(Device dev, Queue staggingQ, CommandPool staggingCmdPool,
                                 string path, VkFormat format      = VkFormat.Undefined,
                                 VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.DeviceLocal,
                                 VkImageTiling tiling    = VkImageTiling.Optimal, bool generateMipmaps = true,
                                 VkImageType imageType   = VkImageType.Image2D,
                                 VkImageUsageFlags usage = VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst)
        {
            if (format == VkFormat.Undefined)
            {
                format = DefaultTextureFormat;
            }
            if (tiling == VkImageTiling.Optimal)
            {
                usage |= VkImageUsageFlags.TransferDst;
            }
            if (generateMipmaps)
            {
                usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst);
            }

            using (StbImage stbi = new StbImage(path)) {
                uint mipLevels = generateMipmaps ? ComputeMipLevels(stbi.Width, stbi.Height) : 1;

                Image img = new Image(dev, format, usage, memoryProps, (uint)stbi.Width, (uint)stbi.Height, imageType,
                                      VkSampleCountFlags.SampleCount1, tiling, mipLevels);

                img.load(staggingQ, staggingCmdPool, stbi.Handle, generateMipmaps);

                return(img);
            }
        }
Exemple #6
0
 public static extern VkResult GetPhysicalDeviceImageFormatProperties(
     VkPhysicalDevice physicalDevice,
     VkFormat format,
     VkImageType type,
     VkImageTiling tiling,
     VkImageUsageFlags usage,
     VkImageCreateFlags flags,
     IntPtr pImageFormatProperties
     );
Exemple #7
0
 public static extern void GetPhysicalDeviceSparseImageFormatProperties(
     VkPhysicalDevice physicalDevice,
     VkFormat format,
     VkImageType type,
     VkSampleCountFlags samples,
     VkImageUsageFlags usage,
     VkImageTiling tiling,
     ref uint pPropertyCount,
     IntPtr pProperties
     );
Exemple #8
0
        public ImagePooled(Device dev, VkFormat format, VkImageType type, VkExtent3D size, uint mipLevels,
                           uint arrayLayers, VkImageTiling tiling, VkSampleCountFlag samples, VkImageUsageFlag usage,
                           VkImageCreateFlag flags, VkSharingMode sharing = VkSharingMode.Exclusive, uint[] sharedQueueFamily = null) :
            base(dev, format, type, size, mipLevels, arrayLayers, tiling, samples, usage, flags, sharing,
                 sharedQueueFamily)
        {
            var memReq  = MemoryRequirements;
            var memType = memReq.FindMemoryType(dev.PhysicalDevice);

            Memory = dev.MemoryPool.Allocate(memType, DeviceMemoryPools.Pool.TexturePool, memReq.TypeRequirements.Size);
            BindMemory(Memory.BackingMemory, Memory.Offset);
        }
Exemple #9
0
        /// <summary>
        /// Load image from byte array containing full image file (jpg, png,...)
        /// </summary>
        public static Image Load(Device dev, Queue staggingQ, CommandPool staggingCmdPool,
                                 byte[] bitmap, VkFormat format    = VkFormat.Undefined,
                                 VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.DeviceLocal,
                                 VkImageTiling tiling    = VkImageTiling.Optimal, bool generateMipmaps = true,
                                 VkImageType imageType   = VkImageType.Image2D,
                                 VkImageUsageFlags usage = VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst)
        {
            Image img = Load(dev, staggingQ, staggingCmdPool, bitmap.Pin(), (ulong)bitmap.Length, format, memoryProps, tiling, generateMipmaps,
                             imageType, usage);

            bitmap.Unpin();
            return(img);
        }
Exemple #10
0
        /// <summary>
        /// create host visible linear image without command from byte array
        /// </summary>
        public static Image Load(Device dev,
                                 byte[] bitmap, VkImageUsageFlags usage = VkImageUsageFlags.TransferSrc,
                                 VkFormat format = VkFormat.Undefined,
                                 VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                 VkImageTiling tiling  = VkImageTiling.Linear, bool generateMipmaps = false,
                                 VkImageType imageType = VkImageType.Image2D)
        {
            Image img = Load(dev, bitmap.Pin(), (ulong)bitmap.Length, usage, format, memoryProps, tiling, generateMipmaps,
                             imageType);

            bitmap.Unpin();
            return(img);
        }
Exemple #11
0
        public static void CreateImage(
            VkDevice device,
            VkPhysicalDeviceMemoryProperties physicalDeviceMemProperties,
            VkDeviceMemoryManager memoryManager,
            uint width,
            uint height,
            uint depth,
            uint arrayLayers,
            VkFormat format,
            VkImageTiling tiling,
            VkImageUsageFlags usage,
            VkMemoryPropertyFlags properties,
            out VkImage image,
            out VkMemoryBlock memory)
        {
            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.imageType     = VkImageType.Image2D;
            imageCI.extent.width  = width;
            imageCI.extent.height = height;
            imageCI.extent.depth  = depth;
            imageCI.mipLevels     = 1;
            imageCI.arrayLayers   = arrayLayers;
            imageCI.format        = format;
            imageCI.tiling        = tiling;
            imageCI.initialLayout = VkImageLayout.Preinitialized;
            imageCI.usage         = usage;
            imageCI.sharingMode   = VkSharingMode.Exclusive;
            imageCI.samples       = VkSampleCountFlags.Count1;

            VkResult result = vkCreateImage(device, ref imageCI, null, out image);

            CheckResult(result);

            vkGetImageMemoryRequirements(device, image, out VkMemoryRequirements memRequirements);
            VkMemoryBlock memoryToken = memoryManager.Allocate(
                physicalDeviceMemProperties,
                memRequirements.memoryTypeBits,
                properties,
                false,
                memRequirements.size,
                memRequirements.alignment);

            memory = memoryToken;
            result = vkBindImageMemory(device, image, memory.DeviceMemory, memory.Offset);
            CheckResult(result);
        }
Exemple #12
0
        public Image(Device dev, VkFormat format, VkImageType type, VkExtent3D size, uint mipLevels, uint arrayLayers,
                     VkImageTiling tiling, VkSampleCountFlag samples, VkImageUsageFlag usage, VkImageCreateFlag flags,
                     VkSharingMode sharing    = VkSharingMode.Exclusive,
                     uint[] sharedQueueFamily = null)
        {
            Device      = dev;
            Format      = format;
            Dimensions  = size;
            MipmapCount = mipLevels;
            LayerCount  = arrayLayers;
            unsafe
            {
#if DEBUG
                var properties = Device.PhysicalDevice.Handle.GetPhysicalDeviceImageFormatProperties(format, type,
                                                                                                     tiling, usage, flags);
#endif
                if (sharing == VkSharingMode.Concurrent)
                    Debug.Assert(sharedQueueFamily != null);
                fixed(uint *sharedPtr = sharedQueueFamily)
                {
                    var info = new VkImageCreateInfo()
                    {
                        SType               = VkStructureType.ImageCreateInfo,
                        Format              = format,
                        ImageType           = type,
                        Tiling              = tiling,
                        Extent              = size,
                        ArrayLayers         = arrayLayers,
                        MipLevels           = mipLevels,
                        Flags               = flags,
                        InitialLayout       = VkImageLayout.Undefined,
                        PNext               = IntPtr.Zero,
                        PQueueFamilyIndices = sharedPtr,
                        SharingMode         = sharing,
                        Samples             = samples,
                        Usage               = usage
                    };

                    Handle = Device.Handle.CreateImage(&info, Instance.AllocationCallbacks);
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// create host visible linear image without command from data pointed by IntPtr pointer containing full image file (jpg, png,...)
        /// </summary>
        public static Image Load(Device dev,
                                 IntPtr bitmap, ulong bitmapByteCount, VkImageUsageFlags usage = VkImageUsageFlags.TransferSrc,
                                 VkFormat format = VkFormat.Undefined,
                                 VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                 VkImageTiling tiling  = VkImageTiling.Linear, bool generateMipmaps = false,
                                 VkImageType imageType = VkImageType.Image2D)
        {
            if (format == VkFormat.Undefined)
            {
                format = DefaultTextureFormat;
            }

            int    width, height, channels;
            IntPtr imgPtr = Stb.Load(bitmap, (int)bitmapByteCount, out width, out height, out channels, 4);

            if (imgPtr == IntPtr.Zero)
            {
                throw new Exception($"STBI image loading error.");
            }

            uint mipLevels = generateMipmaps ? (uint)Math.Floor(Math.Log(Math.Max(width, height))) + 1 : 1;

            if (generateMipmaps)
            {
                usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst);
            }

            long  size = width * height * 4;
            Image img  = new Image(dev, format, usage, memoryProps, (uint)width, (uint)height, imageType, VkSampleCountFlags.SampleCount1, tiling, mipLevels);

            img.Map();
            unsafe {
                System.Buffer.MemoryCopy(imgPtr.ToPointer(), img.MappedData.ToPointer(), size, size);
            }
            img.Unmap();

            Stb.FreeImage(imgPtr);

            return(img);
        }
Exemple #14
0
        /// <summary>
        /// Load bitmap into Image with stagging and mipmap generation if necessary
        /// and usage.
        /// </summary>
        public static Image Load(Device dev, Queue staggingQ, CommandPool staggingCmdPool,
                                 string path, VkFormat format      = VkFormat.Undefined,
                                 VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.DeviceLocal,
                                 VkImageTiling tiling    = VkImageTiling.Optimal, bool generateMipmaps = true,
                                 VkImageType imageType   = VkImageType.Image2D,
                                 VkImageUsageFlags usage = VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst)
        {
            if (format == VkFormat.Undefined)
            {
                format = DefaultTextureFormat;
            }

            int    width, height, channels;
            IntPtr imgPtr = Stb.Load(path, out width, out height, out channels, 4);

            if (imgPtr == IntPtr.Zero)
            {
                throw new Exception($"File not found: {path}.");
            }

            uint mipLevels = generateMipmaps ? (uint)Math.Floor(Math.Log(Math.Max(width, height))) + 1 : 1;

            if (tiling == VkImageTiling.Optimal)
            {
                usage |= VkImageUsageFlags.TransferDst;
            }
            if (generateMipmaps)
            {
                usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst);
            }

            Image img = new Image(dev, format, usage, memoryProps, (uint)width, (uint)height, imageType, VkSampleCountFlags.SampleCount1, tiling, mipLevels);

            img.load(staggingQ, staggingCmdPool, imgPtr, generateMipmaps);

            Stb.FreeImage(imgPtr);

            return(img);
        }
Exemple #15
0
        public Image(Device device, VkFormat format, VkImageUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags,
                     uint width, uint height,
                     VkImageType type               = VkImageType.Image2D, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1,
                     VkImageTiling tiling           = VkImageTiling.Optimal, uint mipsLevels          = 1, uint layers = 1, uint depth = 1,
                     VkImageCreateFlags createFlags = 0)
            : base(device, _memoryPropertyFlags)
        {
            info.imageType     = type;
            info.format        = format;
            info.extent.width  = width;
            info.extent.height = height;
            info.extent.depth  = depth;
            info.mipLevels     = mipsLevels;
            info.arrayLayers   = layers;
            info.samples       = samples;
            info.tiling        = tiling;
            info.usage         = usage;
            info.initialLayout = (tiling == VkImageTiling.Optimal) ? VkImageLayout.Undefined : VkImageLayout.Preinitialized;
            info.sharingMode   = VkSharingMode.Exclusive;
            info.flags         = createFlags;

            Activate(); //DONT OVERRIDE Activate in derived classes!!!!
        }
Exemple #16
0
        /// <summary>
        /// create host visible linear image without command from path
        /// </summary>
        public static Image Load(Device dev,
                                 string path, VkImageUsageFlags usage = VkImageUsageFlags.Sampled, bool reserveSpaceForMipmaps = true, VkFormat format = VkFormat.Undefined,
                                 VkMemoryPropertyFlags memoryProps    = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                 VkImageTiling tiling = VkImageTiling.Linear, VkImageType imageType = VkImageType.Image2D)
        {
            if (format == VkFormat.Undefined)
            {
                format = DefaultTextureFormat;
            }

            using (StbImage stbi = new StbImage(path)) {
                uint mipLevels = reserveSpaceForMipmaps ? ComputeMipLevels(stbi.Width, stbi.Height) : 1;

                Image img = new Image(dev, format, usage, memoryProps, (uint)stbi.Width, (uint)stbi.Height, imageType,
                                      VkSampleCountFlags.SampleCount1, tiling, mipLevels);

                img.Map();
                stbi.CoptyTo(img.MappedData);
                img.Unmap();

                return(img);
            }
        }
Exemple #17
0
 internal extern static Result vkGetPhysicalDeviceImageFormatProperties(IntPtr physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, ref VkImageFormatProperties pImageFormatProperties);
Exemple #18
0
 internal extern static void vkGetPhysicalDeviceSparseImageFormatProperties(IntPtr physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlags samples, VkImageUsageFlags usage, VkImageTiling tiling, ref UInt32 pPropertyCount, [In, Out] VkSparseImageFormatProperties[] pProperties);
Exemple #19
0
        public static ReadOnlySpan <VkSparseImageFormatProperties> vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlags samples, VkImageUsageFlags usage, VkImageTiling tiling)
        {
            uint propertyCount = 0;

            vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &propertyCount, null);

            ReadOnlySpan <VkSparseImageFormatProperties> properties = new VkSparseImageFormatProperties[propertyCount];

            fixed(VkSparseImageFormatProperties *propertiesPtr = properties)
            {
                vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, &propertyCount, propertiesPtr);
            }

            return(properties);
        }
Exemple #20
0
 public IReadOnlyList<VkSparseImageFormatProperties> GetSparseImageFormatProperties(VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage,
     VkImageTiling tiling)
 {
     int count;
     Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, (VkSparseImageFormatProperties*)0);
     var resultArray = new VkSparseImageFormatProperties[count];
     fixed (VkSparseImageFormatProperties* pResultArray = resultArray)
     {
         Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, pResultArray);
         return resultArray;
     }
 }
 public VkImageFormatProperties GetImageFormatProperties(VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags)
 {
     using (var prop = new Marshalled <VkImageFormatProperties>()) {
         Instance.Commands.getPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, prop.Address);
         return(prop.Value);
     }
 }
        public List <VkSparseImageFormatProperties> GetSparseImageFormatProperties(VkFormat format, VkImageType type, VkSampleCountFlags samples, VkImageUsageFlags usage, VkImageTiling tiling)
        {
            var result = new List <VkSparseImageFormatProperties>();

            uint count = 0;

            Instance.Commands.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, ref count, IntPtr.Zero);
            var resultNative = new MarshalledArray <VkSparseImageFormatProperties>((int)count);

            Instance.Commands.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, ref count, resultNative.Address);

            using (resultNative) {
                for (int i = 0; i < count; i++)
                {
                    var prop = resultNative[i];
                    result.Add(prop);
                }
            }

            return(result);
        }
Exemple #23
0
        public IReadOnlyList <VkSparseImageFormatProperties> GetSparseImageFormatProperties(VkFormat format, VkImageType type, VkSampleCount samples, VkImageUsageFlags usage,
                                                                                            VkImageTiling tiling)
        {
            int count;

            Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, (VkSparseImageFormatProperties *)0);
            var resultArray = new VkSparseImageFormatProperties[count];

            fixed(VkSparseImageFormatProperties *pResultArray = resultArray)
            {
                Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, pResultArray);
                return(resultArray);
            }
        }
Exemple #24
0
        public static Image Load(Queue staggingQ, CommandPool staggingCmdPool, string ktxPath, VkImageUsageFlags usage = VkImageUsageFlags.Sampled,
                                 VkMemoryPropertyFlags memoryProperty = VkMemoryPropertyFlags.DeviceLocal, bool generateMipmaps = true,
                                 VkImageTiling tiling = VkImageTiling.Optimal)
        {
            Image img = null;

            using (Stream ktxStream = File.Open(ktxPath, FileMode.Open, FileAccess.Read)) {
                using (BinaryReader br = new BinaryReader(ktxStream)) {
                    if (!br.ReadBytes(12).AreEquals(ktxSignature))
                    {
                        throw new KtxException("Not a ktx file: " + ktxPath);
                    }

                    UInt32 endianness            = br.ReadUInt32();
                    UInt32 glType                = br.ReadUInt32();
                    UInt32 glTypeSize            = br.ReadUInt32();
                    UInt32 glFormat              = br.ReadUInt32();
                    UInt32 glInternalFormat      = br.ReadUInt32();
                    UInt32 glBaseInternalFormat  = br.ReadUInt32();
                    UInt32 pixelWidth            = br.ReadUInt32();
                    UInt32 pixelHeight           = br.ReadUInt32();
                    UInt32 pixelDepth            = Math.Min(1, br.ReadUInt32());
                    UInt32 numberOfArrayElements = br.ReadUInt32();             //only for array text, else 0
                    UInt32 numberOfFaces         = br.ReadUInt32();             //only for cube map, else
                    UInt32 numberOfMipmapLevels  = Math.Min(1, br.ReadUInt32());
                    UInt32 bytesOfKeyValueData   = br.ReadUInt32();

                    VkFormat vkFormat = GLHelper.vkGetFormatFromOpenGLInternalFormat(glInternalFormat);
                    if (vkFormat == VkFormat.Undefined)
                    {
                        vkFormat = GLHelper.vkGetFormatFromOpenGLFormat(glFormat, glType);
                        if (vkFormat == VkFormat.Undefined)
                        {
                            throw new KtxException("Undefined format: " + ktxPath);
                        }
                    }

                    VkFormatFeatureFlags phyFormatSupport = (tiling == VkImageTiling.Linear) ?
                                                            staggingQ.Dev.phy.GetFormatProperties(vkFormat).linearTilingFeatures :
                                                            staggingQ.Dev.phy.GetFormatProperties(vkFormat).optimalTilingFeatures;

                    uint requestedMipsLevels = numberOfMipmapLevels;
                    if (numberOfMipmapLevels == 1)
                    {
                        requestedMipsLevels = (generateMipmaps && phyFormatSupport.HasFlag(VkFormatFeatureFlags.BlitSrc | VkFormatFeatureFlags.BlitDst)) ?
                                              (uint)Math.Floor(Math.Log(Math.Max(pixelWidth, pixelHeight))) + 1 : 1;
                    }

                    if (tiling == VkImageTiling.Optimal)
                    {
                        usage |= VkImageUsageFlags.TransferDst;
                    }
                    if (generateMipmaps)
                    {
                        usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst);
                    }

                    VkImageCreateFlags createFlags = 0;

                    VkImageType imgType =
                        (pixelWidth == 0) ? throw new KtxException("pixelWidth must be > 0") :
                              (pixelHeight == 0) ? imgType = VkImageType.Image1D :
                                                             (pixelDepth == 0) ? imgType = VkImageType.Image2D : imgType = VkImageType.Image3D;


                    VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1;

                    if (numberOfFaces > 1)
                    {
                        if (imgType != VkImageType.Image2D)
                        {
                            throw new KtxException("cubemap faces must be 2D textures");
                        }
                        createFlags           = VkImageCreateFlags.CubeCompatible;
                        samples               = VkSampleCountFlags.SampleCount1;
                        numberOfArrayElements = numberOfFaces;
                    }
                    else
                    {
                        numberOfFaces = 1;
                        if (numberOfArrayElements == 0)
                        {
                            numberOfArrayElements = 1;
                        }
                    }

                    if (imgType != VkImageType.Image3D)
                    {
                        pixelDepth = 1;
                    }

                    img = new Image(staggingQ.Dev, vkFormat, usage, memoryProperty, pixelWidth, pixelHeight, imgType, samples,
                                    tiling, requestedMipsLevels, numberOfArrayElements, pixelDepth, createFlags);

                    byte[] keyValueDatas = br.ReadBytes((int)bytesOfKeyValueData);


                    if (memoryProperty.HasFlag(VkMemoryPropertyFlags.DeviceLocal))
                    {
                        ulong staggingSize = img.AllocatedDeviceMemorySize;


                        using (HostBuffer stagging = new HostBuffer(staggingQ.Dev, VkBufferUsageFlags.TransferSrc, staggingSize)) {
                            stagging.Map();

                            CommandBuffer cmd = staggingCmdPool.AllocateCommandBuffer();
                            cmd.Start(VkCommandBufferUsageFlags.OneTimeSubmit);
                            img.SetLayout(cmd, VkImageAspectFlags.Color,
                                          VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal,
                                          VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.Transfer);

                            List <VkBufferImageCopy> buffCopies = new List <VkBufferImageCopy> ();

                            VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy {
                                imageExtent      = img.CreateInfo.extent,
                                imageSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, img.CreateInfo.arrayLayers, 0)
                            };

                            ulong bufferOffset = 0;
                            uint  imgWidth     = img.CreateInfo.extent.height;
                            uint  imgHeight    = img.CreateInfo.extent.width;

                            for (int mips = 0; mips < numberOfMipmapLevels; mips++)
                            {
                                UInt32 imgSize = br.ReadUInt32();

                                bufferCopyRegion.bufferImageHeight = imgWidth;
                                bufferCopyRegion.bufferRowLength   = imgHeight;
                                bufferCopyRegion.bufferOffset      = bufferOffset;

                                if (createFlags.HasFlag(VkImageCreateFlags.CubeCompatible))
                                {
                                    IntPtr ptrFace = img.MappedData;
                                    bufferCopyRegion.imageSubresource.layerCount = 1;
                                    for (uint face = 0; face < numberOfFaces; face++)
                                    {
                                        bufferCopyRegion.imageSubresource.baseArrayLayer = face;
                                        Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize);
                                        buffCopies.Add(bufferCopyRegion);
                                        uint faceOffset = imgSize + (imgSize % 4);
                                        ptrFace      += (int)faceOffset;                                   //cube padding
                                        bufferOffset += faceOffset;
                                        bufferCopyRegion.bufferOffset = bufferOffset;
                                    }
                                }
                                else
                                {
                                    Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData, (int)imgSize);
                                    buffCopies.Add(bufferCopyRegion);
                                }
                                bufferOffset += imgSize;
                                imgWidth     /= 2;
                                imgHeight    /= 2;
                            }
                            stagging.Unmap();
                            Vk.vkCmdCopyBufferToImage(cmd.Handle, stagging.handle, img.handle, VkImageLayout.TransferDstOptimal,
                                                      (uint)buffCopies.Count, buffCopies.Pin());
                            buffCopies.Unpin();

                            if (requestedMipsLevels > numberOfMipmapLevels)
                            {
                                img.BuildMipmaps(cmd);
                            }
                            else
                            {
                                img.SetLayout(cmd, VkImageAspectFlags.Color,
                                              VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal,
                                              VkPipelineStageFlags.Transfer, VkPipelineStageFlags.AllGraphics);
                            }

                            cmd.End();

                            staggingQ.Submit(cmd);
                            staggingQ.WaitIdle();

                            cmd.Free();
                        }

                        //for (int mips = 0; mips < numberOfMipmapLevels; mips++) {
                        //UInt32 imgSize = br.ReadUInt32 ();

                        /*VkImageBlit imageBlit = new VkImageBlit {
                         *      srcSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, numberOfArrayElements, (uint)mips - 1),
                         *      srcOffsets_1 = new VkOffset3D((int)pixelWidth >> (mips - 1), (int)pixelHeight >> (mips - 1),1),
                         *      dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, numberOfArrayElements, (uint)mips),
                         *      dstOffsets_1 = new VkOffset3D ((int)pixelWidth >> mips, (int)pixelHeight >> mips, 1),
                         * };*/
                        //for (int layer = 0; layer < numberOfArrayElements; layer++) {
                        //for (int face = 0; face < numberOfFaces; face++) {
                        //for (int slice = 0; slice < pixelDepth; slice++) {

                        /*for (int y = 0; y < pixelHeight; y++) {
                         *      for (int x = 0; x < pixelWidth; x++) {
                         *              //Uncompressed texture data matches a GL_UNPACK_ALIGNMENT of 4.
                         *      }
                         * }*/
                        //}
                        //Byte cubePadding[0-3]
                        //}
                        //}
                        //Byte mipPadding[0-3]
                        //}
                    }
                }
            }

            return(img);
        }
Exemple #25
0
        public static Image Load(Queue staggingQ, CommandPool staggingCmdPool, string ktxPath, VkImageUsageFlags usage = VkImageUsageFlags.Sampled,
                                 VkMemoryPropertyFlags memoryProperty = VkMemoryPropertyFlags.DeviceLocal, bool generateMipmaps = true,
                                 VkImageTiling tiling = VkImageTiling.Optimal)
        {
            Image img = null;

            using (Stream ktxStream = File.Open(ktxPath, FileMode.Open, FileAccess.Read)) {
                using (BinaryReader br = new BinaryReader(ktxStream)) {
                    if (!br.ReadBytes(12).AreEquals(ktxSignature))
                    {
                        throw new KtxException("Not a ktx file: " + ktxPath);
                    }

                    UInt32 endianness            = br.ReadUInt32();
                    UInt32 glType                = br.ReadUInt32();
                    UInt32 glTypeSize            = br.ReadUInt32();
                    UInt32 glFormat              = br.ReadUInt32();
                    UInt32 glInternalFormat      = br.ReadUInt32();
                    UInt32 glBaseInternalFormat  = br.ReadUInt32();
                    UInt32 pixelWidth            = br.ReadUInt32();
                    UInt32 pixelHeight           = br.ReadUInt32();
                    UInt32 pixelDepth            = Math.Max(1, br.ReadUInt32());
                    UInt32 numberOfArrayElements = br.ReadUInt32();             //only for array text, else 0
                    UInt32 numberOfFaces         = br.ReadUInt32();             //only for cube map, else 1
                    UInt32 numberOfMipmapLevels  = Math.Max(1, br.ReadUInt32());
                    UInt32 bytesOfKeyValueData   = br.ReadUInt32();

                    VkFormat vkFormat = GLHelper.vkGetFormatFromOpenGLInternalFormat(glInternalFormat);
                    if (vkFormat == VkFormat.Undefined)
                    {
                        vkFormat = GLHelper.vkGetFormatFromOpenGLFormat(glFormat, glType);
                        if (vkFormat == VkFormat.Undefined)
                        {
                            throw new KtxException("Undefined format: " + ktxPath);
                        }
                    }
                    VkFormatProperties   formatProperties = staggingQ.Dev.phy.GetFormatProperties(vkFormat);
                    VkFormatFeatureFlags phyFormatSupport = (tiling == VkImageTiling.Linear) ?
                                                            formatProperties.linearTilingFeatures :
                                                            formatProperties.optimalTilingFeatures;

                    uint requestedMipsLevels = numberOfMipmapLevels;
                    if (numberOfMipmapLevels == 1)
                    {
                        requestedMipsLevels = (generateMipmaps && phyFormatSupport.HasFlag(VkFormatFeatureFlags.BlitSrc | VkFormatFeatureFlags.BlitDst)) ?
                                              (uint)Math.Floor(Math.Log(Math.Max(pixelWidth, pixelHeight))) + 1 : 1;
                    }

                    if (tiling == VkImageTiling.Optimal)
                    {
                        usage |= VkImageUsageFlags.TransferDst;
                    }
                    if (generateMipmaps)
                    {
                        usage |= (VkImageUsageFlags.TransferSrc | VkImageUsageFlags.TransferDst);
                    }

                    VkImageCreateFlags createFlags = 0;

                    VkImageType imgType =
                        (pixelWidth == 0) ? throw new KtxException("pixelWidth must be > 0") :
                              (pixelHeight == 0) ? imgType = VkImageType.Image1D :
                                                             (pixelDepth == 1) ? imgType = VkImageType.Image2D : imgType = VkImageType.Image3D;


                    VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1;

                    if (numberOfFaces > 1)
                    {
                        if (imgType != VkImageType.Image2D)
                        {
                            throw new KtxException("cubemap faces must be 2D textures");
                        }
                        createFlags           = VkImageCreateFlags.CubeCompatible;
                        samples               = VkSampleCountFlags.SampleCount1;
                        numberOfArrayElements = numberOfFaces;
                    }
                    else
                    {
                        numberOfFaces = 1;
                        if (numberOfArrayElements == 0)
                        {
                            numberOfArrayElements = 1;
                        }
                    }

                    if (!Image.CheckFormatIsSupported(usage, phyFormatSupport))
                    {
                        throw new Exception($"Unsupported image format: {vkFormat}, {tiling}, {usage}");
                    }

                    img = new Image(staggingQ.Dev, vkFormat, usage, memoryProperty, pixelWidth, pixelHeight, imgType, samples,
                                    tiling, requestedMipsLevels, numberOfArrayElements, pixelDepth, createFlags);

                    byte[] keyValueDatas = br.ReadBytes((int)bytesOfKeyValueData);

                    uint blockW, blockH;
                    bool isCompressed = vkFormat.TryGetCompressedFormatBlockSize(out blockW, out blockH);
                    uint blockSize    = blockW * blockH;

                    if (memoryProperty.HasFlag(VkMemoryPropertyFlags.DeviceLocal))
                    {
                        ulong staggingSize = img.AllocatedDeviceMemorySize;
                        Console.WriteLine($"KtxStream size = {ktxStream.Length}, img Allocation = {img.AllocatedDeviceMemorySize}");

                        using (HostBuffer stagging = new HostBuffer(staggingQ.Dev, VkBufferUsageFlags.TransferSrc, staggingSize)) {
                            stagging.Map();

                            PrimaryCommandBuffer cmd = staggingCmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);
                            img.SetLayout(cmd, VkImageAspectFlags.Color,
                                          VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal,
                                          VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.Transfer);

                            List <VkBufferImageCopy> buffCopies = new List <VkBufferImageCopy> ();

                            VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy {
                                imageExtent      = img.CreateInfo.extent,
                                imageSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, img.CreateInfo.arrayLayers, 0)
                            };

                            ulong bufferOffset = 0;
                            uint  imgWidth     = img.CreateInfo.extent.width;
                            uint  imgHeight    = img.CreateInfo.extent.height;

                            for (int mips = 0; mips < numberOfMipmapLevels; mips++)
                            {
                                UInt32 imgSize = br.ReadUInt32();

                                bufferCopyRegion.bufferRowLength   = imgWidth;
                                bufferCopyRegion.bufferImageHeight = imgHeight;

                                if (isCompressed && (imgWidth % blockW > 0 || imgHeight % blockH > 0))
                                {
                                    bufferCopyRegion.bufferRowLength   += blockW - imgWidth % blockW;
                                    bufferCopyRegion.bufferImageHeight += blockH - imgHeight % blockH;
                                }
                                bufferCopyRegion.bufferOffset = bufferOffset;
                                bufferCopyRegion.imageSubresource.mipLevel = (uint)mips;
                                bufferCopyRegion.imageExtent.width         = imgWidth;
                                bufferCopyRegion.imageExtent.height        = imgHeight;

                                if (createFlags.HasFlag(VkImageCreateFlags.CubeCompatible))
                                {
                                    //TODO:handle compressed formats
                                    for (uint face = 0; face < numberOfFaces; face++)
                                    {
                                        Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize);
                                        uint faceOffset = imgSize + (imgSize % 4);                                        //cube padding
                                        bufferOffset += faceOffset;
                                    }
                                    buffCopies.Add(bufferCopyRegion);
                                    bufferCopyRegion.bufferOffset = bufferOffset;
                                }
                                else if (isCompressed && (imgWidth % blockW > 0 || imgHeight % blockH > 0))
                                {
                                    for (int line = 0; line < imgHeight; line++)
                                    {
                                        Marshal.Copy(br.ReadBytes((int)imgWidth), 0, stagging.MappedData + (int)bufferOffset, (int)imgWidth);
                                        bufferOffset += bufferCopyRegion.bufferRowLength;
                                    }
                                    buffCopies.Add(bufferCopyRegion);
                                }
                                else
                                {
                                    Marshal.Copy(br.ReadBytes((int)imgSize), 0, stagging.MappedData + (int)bufferOffset, (int)imgSize);
                                    buffCopies.Add(bufferCopyRegion);
                                    bufferOffset += imgSize;
                                }

                                if (isCompressed && bufferOffset % blockSize > 0)
                                {
                                    bufferOffset += blockSize - bufferOffset % blockSize;
                                }

                                imgWidth  /= 2;
                                imgHeight /= 2;
                            }
                            stagging.Unmap();

                            Vk.vkCmdCopyBufferToImage(cmd.Handle, stagging.handle, img.handle, VkImageLayout.TransferDstOptimal,
                                                      (uint)buffCopies.Count, buffCopies.Pin());
                            buffCopies.Unpin();

                            if (requestedMipsLevels > numberOfMipmapLevels)
                            {
                                img.BuildMipmaps(cmd);
                            }
                            else
                            {
                                img.SetLayout(cmd, VkImageAspectFlags.Color,
                                              VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal,
                                              VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);
                            }

                            cmd.End();

                            staggingQ.Submit(cmd);
                            staggingQ.WaitIdle();

                            cmd.Free();
                        }
                    }
                    else
                    {
                    }
                }
            }

            return(img);
        }
Exemple #26
0
        public Image GetPageTexture(int page, Queue staggingQ, CommandPool cmdPool,
                                    VkMemoryPropertyFlags imgProp = VkMemoryPropertyFlags.DeviceLocal, bool genMipMaps = true, VkImageTiling tiling = VkImageTiling.Optimal)
        {
            string path = Path.Combine(Path.GetDirectoryName(fntFilePath), PageImagePathes[page]);

            if (path.EndsWith("ktx", StringComparison.OrdinalIgnoreCase))
            {
                return(KTX.KTX.Load(staggingQ, cmdPool, path,
                                    VkImageUsageFlags.Sampled, imgProp, genMipMaps, tiling));
            }
            return(Image.Load(staggingQ.Dev, staggingQ, cmdPool, path, VkFormat.R8g8b8a8Unorm, imgProp, tiling, genMipMaps));
        }