Beispiel #1
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();
        }
Beispiel #2
0
        public Buffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropFlags, ulong stride, ulong count,
                      VkSharingMode sharingMode = VkSharingMode.Exclusive, uint[] queueFamilyIndices = null, IntPtr data = default)
        {
            Stride = stride;
            Count  = count;
            Size   = stride * count;

            // Create the buffer handle
            var bufferCreateInfo = new VkBufferCreateInfo(usageFlags, Size, queueFamilyIndices)
            {
                sharingMode = sharingMode
            };

            if (data != null && (memoryPropertyFlags & VkMemoryPropertyFlags.HostCoherent) == 0)
            {
                bufferCreateInfo.usage |= VkBufferUsageFlags.TransferDst;
            }

            handle = Device.CreateBuffer(ref bufferCreateInfo);

            UsageFlags          = usageFlags;
            memoryPropertyFlags = memoryPropFlags;

            Device.GetBufferMemoryRequirements(handle, out VkMemoryRequirements memReqs);
            Allocate(memReqs);
            Device.BindBufferMemory(handle, memory, 0);

            if (data != IntPtr.Zero)
            {
                SetData(data, 0, Size);
            }

            SetupDescriptor();
        }
Beispiel #3
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);
            }
        }
Beispiel #4
0
        private void CreateUniformBuffer(VkDevice device, VkPhysicalDevice physicalDevice)
        {
            var bufferSize = Marshal.SizeOf <Transform>();
            VkMemoryPropertyFlags memoryFlags = VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;

            SampleHelpers.CreateBuffer(device, physicalDevice, bufferSize, VkBufferUsageFlags.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memoryFlags, out m_uniformBuffer, out m_uniformBufferMemory);
        }
Beispiel #5
0
        public VkBuffer(VkGraphicsDevice gd, uint sizeInBytes, BufferUsage usage)
        {
            _gd         = gd;
            SizeInBytes = sizeInBytes;
            Usage       = usage;

            VkBufferUsageFlags vkUsage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst;

            if ((usage & BufferUsage.VertexBuffer) == BufferUsage.VertexBuffer)
            {
                vkUsage |= VkBufferUsageFlags.VertexBuffer;
            }
            if ((usage & BufferUsage.IndexBuffer) == BufferUsage.IndexBuffer)
            {
                vkUsage |= VkBufferUsageFlags.IndexBuffer;
            }
            if ((usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer)
            {
                vkUsage |= VkBufferUsageFlags.UniformBuffer;
            }
            if ((usage & BufferUsage.StructuredBufferReadWrite) == BufferUsage.StructuredBufferReadWrite ||
                (usage & BufferUsage.StructuredBufferReadOnly) == BufferUsage.StructuredBufferReadOnly)
            {
                vkUsage |= VkBufferUsageFlags.StorageBuffer;
            }
            if ((usage & BufferUsage.IndirectBuffer) == BufferUsage.IndirectBuffer)
            {
                vkUsage |= VkBufferUsageFlags.IndirectBuffer;
            }

            VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();

            bufferCI.size  = sizeInBytes;
            bufferCI.usage = vkUsage;
            VkResult result = vkCreateBuffer(gd.Device, ref bufferCI, null, out _deviceBuffer);

            CheckResult(result);

            vkGetBufferMemoryRequirements(gd.Device, _deviceBuffer, out _bufferMemoryRequirements);

            bool hostVisible = (usage & BufferUsage.Dynamic) == BufferUsage.Dynamic ||
                               (usage & BufferUsage.Staging) == BufferUsage.Staging;

            VkMemoryPropertyFlags memoryPropertyFlags =
                hostVisible
                ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent
                : VkMemoryPropertyFlags.DeviceLocal;

            VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                gd.PhysicalDeviceMemProperties,
                _bufferMemoryRequirements.memoryTypeBits,
                memoryPropertyFlags,
                hostVisible,
                _bufferMemoryRequirements.size,
                _bufferMemoryRequirements.alignment);

            _memory = memoryToken;
            result  = vkBindBufferMemory(gd.Device, _deviceBuffer, _memory.DeviceMemory, _memory.Offset);
            CheckResult(result);
        }
Beispiel #6
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);
            }
        }
Beispiel #7
0
        /**
         * Get the index of a memory type that has all the requested property bits set
         *
         * @param typeBits Bitmask with bits set for each memory type supported by the resource to request for (from VkMemoryRequirements)
         * @param properties Bitmask of properties for the memory type to request
         * @param (Optional) memTypeFound Pointer to a bool that is set to true if a matching memory type has been found
         *
         * @return Index of the requested memory type
         *
         * @throw Throws an exception if memTypeFound is null and no memory type could be found that supports the requested properties
         */
        public uint GetMemoryType(uint typeBits, VkMemoryPropertyFlags properties, uint *memTypeFound = null)
        {
            for (uint i = 0; i < MemoryProperties.memoryTypeCount; i++)
            {
                if ((typeBits & 1) == 1)
                {
                    if ((MemoryProperties.GetMemoryType(i).propertyFlags & properties) == properties)
                    {
                        if (memTypeFound != null)
                        {
                            *memTypeFound = True;
                        }
                        return(i);
                    }
                }
                typeBits >>= 1;
            }

            if (memTypeFound != null)
            {
                *memTypeFound = False;
                return(0);
            }
            else
            {
                throw new InvalidOperationException("Could not find a matching memory type");
            }
        }
Beispiel #8
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);
        }
Beispiel #9
0
        public VkDeviceBuffer(
            VkRenderContext rc,
            ulong size,
            VkBufferUsageFlags usage,
            VkMemoryPropertyFlags memoryProperties,
            bool dynamic)
        {
            _rc               = rc;
            usage            |= VkBufferUsageFlags.TransferSrc;
            _usage            = usage;
            _memoryProperties = memoryProperties;
            _isDynamic        = dynamic;

            VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();

            bufferCI.size  = size;
            bufferCI.usage = _usage;
            VkResult result = vkCreateBuffer(rc.Device, ref bufferCI, null, out _buffer);

            CheckResult(result);

            vkGetBufferMemoryRequirements(rc.Device, _buffer, out _bufferMemoryRequirements);
            _bufferCapacity = _bufferMemoryRequirements.size;
            uint          memoryType  = FindMemoryType(rc.PhysicalDevice, _bufferMemoryRequirements.memoryTypeBits, memoryProperties);
            VkMemoryBlock memoryToken = rc.MemoryManager.Allocate(
                memoryType,
                _bufferMemoryRequirements.size,
                _bufferMemoryRequirements.alignment);

            _memory = memoryToken;
            vkBindBufferMemory(rc.Device, _buffer, _memory.DeviceMemory, _memory.Offset);
        }
Beispiel #10
0
        /// <summary>
        /// Searches the available memory types for one matching the set of passed flags. Search order is
        /// <list type="number">
        /// <item><c>notPref</c> and <c>req | pref</c></item>
        /// <item><c>notPref</c> and <c>req</c></item>
        /// <item><c>req | pref</c></item>
        /// <item><c>req</c></item>
        /// </list>
        /// </summary>
        /// <param name="mask">The memory type mask associated with memory requirements.</param>
        /// <param name="req">The required flags.</param>
        /// <param name="pref">The preferred flags.</param>
        /// <param name="prefNot">The flags that are preferred to not be present.</param>
        /// <returns>The memory type index, or <c>null</c> if a matching type was not found.</returns>
        public uint?FindMemoryType(uint mask, VkMemoryPropertyFlags req, VkMemoryPropertyFlags pref,
                                   VkMemoryPropertyFlags prefNot = VkMemoryPropertyFlags.NoFlags)
        {
            var noSet = stackalloc VkMemoryPropertyFlags[2] {
                prefNot, VkMemoryPropertyFlags.NoFlags
            };
            var yesSet = stackalloc VkMemoryPropertyFlags[2] {
                req | pref, req
            };

            foreach (var noMask in (new ReadOnlySpan <VkMemoryPropertyFlags>(noSet, 2)))
            {
                foreach (var yesMask in (new ReadOnlySpan <VkMemoryPropertyFlags>(yesSet, 2)))
                {
                    for (uint mi = 0, mbit = 1; mi < MemoryTypeCount; ++mi, mbit <<= 1)
                    {
                        var maskPass = (mask & mbit) != 0;
                        var yesPass  = (_memoryTypes[mi].PropertyFlags & yesMask) == yesMask;
                        var noPass   = (_memoryTypes[mi].PropertyFlags & noMask) == 0;
                        if (maskPass && yesPass && noPass)
                        {
                            return(mi);
                        }
                    }
                }
            }

            return(null);
        }
Beispiel #11
0
        private void CreateVertexBuffer(VkDevice device, VkPhysicalDevice physicalDevice)
        {
            // 初期頂点データ.
            var vertices = new Vertex[3] {
                new Vertex()
                {
                    Position = new vec3(-.5f, 0.5f, 0.0f), Color = new vec4(0.0f, 0.0f, 1.0f, 1.0f)
                },
                new Vertex()
                {
                    Position = new vec3(+.5f, 0.5f, 0.0f), Color = new vec4(0.0f, 1.0f, 0.0f, 1.0f)
                },
                new Vertex()
                {
                    Position = new vec3(0.0f, -.5f, 0.0f), Color = new vec4(1.0f, 0.0f, 0.0f, 1.0f)
                },
            };
            var bufferSize = Marshal.SizeOf <Vertex>() * vertices.Length;
            VkMemoryPropertyFlags memoryFlags = VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;

            SampleHelpers.CreateBuffer(device, physicalDevice, bufferSize, VkBufferUsageFlags.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, memoryFlags, out m_vertexBuffer, out m_vertexBufferMemory);

            // 初期頂点データの書き込み.
            MappedMemoryStream mappedStream;

            VulkanAPI.vkMapMemory(device, m_vertexBufferMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mappedStream);
            mappedStream.Write(vertices);
            VulkanAPI.vkUnmapMemory(device, m_vertexBufferMemory);
        }
Beispiel #12
0
        public void CreateCubeModel(VkDevice device, VkPhysicalDevice physicalDevice)
        {
            var cubeVertices = CubeModel.GetVertices();
            var cubeIndices  = CubeModel.GetIndices();
            var vbSize       = Marshal.SizeOf <CubeModel.Vertex>() * cubeVertices.Length;
            var ibSize       = Marshal.SizeOf <ushort>() * cubeIndices.Length;

            VkMemoryPropertyFlags flags = VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;

            SampleHelpers.CreateBuffer(device, physicalDevice, vbSize, VkBufferUsageFlags.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, flags, out m_vertexBuffer, out m_vertexBufferMemory);
            SampleHelpers.CreateBuffer(device, physicalDevice, ibSize, VkBufferUsageFlags.VK_BUFFER_USAGE_INDEX_BUFFER_BIT, flags, out m_indexBuffer, out m_indexBufferMemory);

            // 初期データの書き込み.
            MappedMemoryStream mapped;

            VulkanAPI.vkMapMemory(device, m_vertexBufferMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mapped);
            mapped.Write(cubeVertices);
            VulkanAPI.vkUnmapMemory(device, m_vertexBufferMemory);
            VulkanAPI.vkMapMemory(device, m_indexBufferMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mapped);
            mapped.Write(cubeIndices);
            VulkanAPI.vkUnmapMemory(device, m_indexBufferMemory);

            m_resourceManager.Regist(m_vertexBuffer, m_vertexBufferMemory);
            m_resourceManager.Regist(m_indexBuffer, m_indexBufferMemory);
        }
Beispiel #13
0
 public MemoryAllocation(VkDeviceMemory handle, ulong off, ulong size,
                         VkMemoryPropertyFlags flags)
 {
     Handle = handle;
     Offset = off;
     Size   = size;
     Flags  = flags;
 }
 public VkVertexBuffer(
     VkRenderContext rc,
     ulong size,
     VkMemoryPropertyFlags memoryProperties,
     bool dynamic)
     : base(rc, size, VkBufferUsageFlags.VertexBuffer, memoryProperties, dynamic)
 {
 }
Beispiel #15
0
        /// <summary>
        /// Create a vulkan buffer and automatically activate it. Automatic activation on startup implies to explicitly dispose the buffer.
        /// </summary>
        /// <param name="device">Logical Device.</param>
        /// <param name="usage">a bitmask specifying allowed usages of the buffer</param>
        /// <param name="_memoryPropertyFlags">Memory property flags.</param>
        /// <param name="size">Desired size in byte of the buffer to be created.</param>
        /// <param name="sharingMode">value specifying the sharing mode of the buffer when it will be accessed by multiple queue familie</param>
        public Buffer(Device device, VkBufferUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags, UInt64 size, VkSharingMode sharingMode = VkSharingMode.Exclusive)
            : base(device, _memoryPropertyFlags)
        {
            createInfo.size        = size;
            createInfo.usage       = usage;
            createInfo.sharingMode = VkSharingMode.Exclusive;

            Activate();
        }
Beispiel #16
0
        public Buffer(Device device, VkBufferUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags, UInt64 size)
            : base(device, _memoryPropertyFlags)
        {
            createInfo.size        = size;
            createInfo.usage       = usage;
            createInfo.sharingMode = VkSharingMode.Exclusive;

            Activate(); //DONT OVERRIDE Activate in derived classes!!!!
        }
Beispiel #17
0
        public VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, ulong size, out VkBuffer buffer, out VkDeviceMemory memory, void *data = null)
        {
            VkBuffer       b;
            VkDeviceMemory dm;
            VkResult       result = createBuffer(usageFlags, memoryPropertyFlags, size, &b, &dm, data);

            buffer = b;
            memory = dm;
            return(result);
        }
Beispiel #18
0
 public SharedBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropFlags, ulong size,
                     VkSharingMode sharingMode = VkSharingMode.Exclusive, uint[] queueFamilyIndices = null)
 {
     buffers[0] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[0].Map(0, size);
     buffers[1] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[1].Map(0, size);
     buffers[2] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[2].Map(0, size);
 }
        internal unsafe void AllocateOneTimeUploadBuffer(int size, out UploadBuffer uploadBuffer)
        {
            var bufferCreateInfo = new VkBufferCreateInfo
            {
                sType = VkStructureType.BufferCreateInfo,
                size  = (ulong)size,
                flags = VkBufferCreateFlags.None,
                usage = VkBufferUsageFlags.TransferSrc,
            };

            uploadBuffer = new UploadBuffer
            {
                size = size
            };

            vkCreateBuffer(NativeDevice, &bufferCreateInfo, null, out uploadBuffer.buffer);

            // figure out the memory type
            if (properType == uint.MaxValue)
            {
                VkMemoryPropertyFlags memoryProperties = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent;
                vkGetBufferMemoryRequirements(nativeDevice, uploadBuffer.buffer, out var memoryRequirements);
                vkGetPhysicalDeviceMemoryProperties(NativePhysicalDevice, out var physicalDeviceMemoryProperties);
                var typeBits = memoryRequirements.memoryTypeBits;
                for (uint i = 0; i < physicalDeviceMemoryProperties.memoryTypeCount; i++)
                {
                    if ((typeBits & 1) == 1)
                    {
                        // Type is available, does it match user properties?
                        var memoryType = *(&physicalDeviceMemoryProperties.memoryTypes_0 + i);
                        if ((memoryType.propertyFlags & memoryProperties) == memoryProperties)
                        {
                            properType = i;
                            break;
                        }
                    }
                    typeBits >>= 1;
                }
            }

            var allocateInfo = new VkMemoryAllocateInfo
            {
                sType           = VkStructureType.MemoryAllocateInfo,
                allocationSize  = (ulong)size,
                memoryTypeIndex = properType
            };

            fixed(VkDeviceMemory *nativeUploadBufferMemoryPtr = &uploadBuffer.memory)
            vkAllocateMemory(NativeDevice, &allocateInfo, null, nativeUploadBufferMemoryPtr);

            vkBindBufferMemory(NativeDevice, uploadBuffer.buffer, uploadBuffer.memory, 0);

            fixed(IntPtr *nativeUploadBufferStartPtr = &uploadBuffer.address)
            vkMapMemory(NativeDevice, uploadBuffer.memory, 0, (ulong)size, VkMemoryMapFlags.None, (void **)nativeUploadBufferStartPtr);
        }
 internal VulkanMemorySlice(VulkanMemoryPool originPool, ulong size, ulong offset, ulong alignOffset, VkDeviceMemory vkDeviceMemory, uint memoryTypeIndex, VkMemoryPropertyFlags memoryPropertyFlags)
 {
     this.originPool          = originPool;
     this.memoryTypeIndex     = memoryTypeIndex;
     this.memoryPropertyFlags = memoryPropertyFlags;
     this.vkDeviceMemory      = vkDeviceMemory;
     this.size        = size;
     this.offset      = offset;
     this.alignOffset = alignOffset;
     disposed         = false;
     hostVisible      = (memoryPropertyFlags & VkMemoryPropertyFlags.HostVisible) != 0;
 }
Beispiel #21
0
        protected unsafe void AllocateMemory(VkMemoryPropertyFlags memoryProperties, VkMemoryRequirements memoryRequirements)
        {
            if (NativeMemory != VkDeviceMemory.Null)
            {
                return;
            }

            if (memoryRequirements.size == 0)
            {
                return;
            }

            var allocateInfo = new VkMemoryAllocateInfo
            {
                sType          = VkStructureType.MemoryAllocateInfo,
                allocationSize = memoryRequirements.size,
            };

            VkPhysicalDeviceMemoryProperties localProps;

            if (!gotProps)
            {
                gotProps = true;
                vkGetPhysicalDeviceMemoryProperties(GraphicsDevice.NativePhysicalDevice, out physicalDeviceMemoryProperties);
            }
            localProps = physicalDeviceMemoryProperties;

            var typeBits = memoryRequirements.memoryTypeBits;

            for (uint i = 0; i < localProps.memoryTypeCount; i++)
            {
                if ((typeBits & 1) == 1)
                {
                    // Type is available, does it match user properties?
                    var memoryType = *(&localProps.memoryTypes_0 + i);
                    if ((memoryType.propertyFlags & memoryProperties) == memoryProperties)
                    {
                        allocateInfo.memoryTypeIndex = i;
                        break;
                    }
                }
                typeBits >>= 1;
            }

            var result = vkAllocateMemory(GraphicsDevice.NativeDevice, &allocateInfo, null, out NativeMemory);

            if (result != VkResult.Success)
            {
                string err = "Couldn't allocate memory: " + result + ", NativeMemory: " + NativeMemory + ", type: " + allocateInfo.memoryTypeIndex + ", size: " + memoryRequirements.size;
                Xenko.Core.ErrorFileLogger.WriteLogToFile(err);
                throw new Exception(err);
            }
        }
Beispiel #22
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));
        }
        public VkMemoryBlock Allocate(
            VkPhysicalDeviceMemoryProperties memProperties,
            uint memoryTypeBits,
            VkMemoryPropertyFlags flags,
            bool persistentMapped,
            ulong size,
            ulong alignment)
        {
            lock (_lock)
            {
                uint memoryTypeIndex = FindMemoryType(memProperties, memoryTypeBits, flags);

                ulong minDedicatedAllocationSize = persistentMapped
                    ? MinDedicatedAllocationSizeDynamic
                    : MinDedicatedAllocationSizeNonDynamic;

                if (size >= minDedicatedAllocationSize)
                {
                    VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();
                    allocateInfo.allocationSize  = size;
                    allocateInfo.memoryTypeIndex = memoryTypeIndex;
                    VkResult allocationResult = vkAllocateMemory(_device, ref allocateInfo, null, out VkDeviceMemory memory);
                    if (allocationResult != VkResult.Success)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    void *mappedPtr = null;
                    if (persistentMapped)
                    {
                        VkResult mapResult = vkMapMemory(_device, memory, 0, size, 0, &mappedPtr);
                        if (mapResult != VkResult.Success)
                        {
                            throw new VeldridException("Unable to map newly-allocated Vulkan memory.");
                        }
                    }

                    return(new VkMemoryBlock(memory, 0, size, memoryTypeBits, null, true));
                }
                else
                {
                    ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex, persistentMapped);
                    bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret);
                    if (!result)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    return(ret);
                }
            }
        }
 public VulkanMemoryPool(GraphicsDevice device, ulong size, uint memoryTypeIndex, VkMemoryPropertyFlags memProps, bool hostVisible)
 {
     this.device              = device;
     this.max_size            = size;
     this.memoryPropertyFlags = memProps;
     this.hostVisible         = hostVisible;
     freeSlices = new List <FreeSlice>();
     freeSlices.Add(new FreeSlice()
     {
         length = max_size, startIndex = 0
     });
     this.memoryTypeIndex = memoryTypeIndex;
 }
Beispiel #25
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);
        }
Beispiel #26
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);
        }
Beispiel #27
0
        int FindMemoryType(uint filter, VkMemoryPropertyFlags flags)
        {
            var props = physicalDevice.MemoryProperties;

            for (int i = 0; i < props.MemoryTypes.Count; i++)
            {
                if ((filter & (1 << i)) != 0 && (props.MemoryTypes[i].propertyFlags & flags) == flags)
                {
                    return(i);
                }
            }

            throw new Exception("Failed to find suitable memory type");
        }
Beispiel #28
0
        public static uint GetMemoryType(uint typeBits, VkMemoryPropertyFlags properties)
        {
            for (uint i = 0; i < MemoryProperties.memoryTypeCount; i++)
            {
                if ((typeBits & 1) == 1)
                {
                    if ((MemoryProperties.GetMemoryType(i).propertyFlags & properties) == properties)
                    {
                        return(i);
                    }
                }
                typeBits >>= 1;
            }

            return(0);
        }
Beispiel #29
0
 MemoryPool GetMemoryPool(uint typeBits, VkMemoryPropertyFlags properties)
 {
     // Iterate over all memory types available for the Device used in this example
     for (uint i = 0; i < memoryProperties.memoryTypeCount; i++)
     {
         if ((typeBits & 1) == 1)
         {
             if ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
             {
                 return(memoryPools[i]);
             }
         }
         typeBits >>= 1;
     }
     throw new InvalidOperationException("Could not find a suitable memory type!");
 }
Beispiel #30
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);
        }