Exemplo n.º 1
0
        /// <inheritdoc />
        /// <exception cref="ExternalException">The call to <see cref="vkMapMemory(IntPtr, ulong, ulong, ulong, uint, void**)" /> failed.</exception>
        public override T *Map <T>(nuint readRangeOffset, nuint readRangeLength)
        {
            var vulkanGraphicsHeap = VulkanGraphicsHeap;
            var vulkanDeviceMemory = vulkanGraphicsHeap.VulkanDeviceMemory;

            var vulkanGraphicsDevice = vulkanGraphicsHeap.VulkanGraphicsDevice;
            var vulkanDevice         = vulkanGraphicsDevice.VulkanDevice;

            void *pDestination;

            ThrowExternalExceptionIfNotSuccess(nameof(vkMapMemory), vkMapMemory(vulkanDevice, vulkanDeviceMemory, Offset, Size, flags: 0, &pDestination));

            if (readRangeLength != 0)
            {
                var vulkanGraphicsAdapter = vulkanGraphicsDevice.VulkanGraphicsAdapter;
                var nonCoherentAtomSize   = vulkanGraphicsAdapter.VulkanPhysicalDeviceProperties.limits.nonCoherentAtomSize;

                var offset = Offset + readRangeOffset;
                var size   = (readRangeLength + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1);

                var mappedMemoryRange = new VkMappedMemoryRange {
                    sType  = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
                    memory = vulkanDeviceMemory,
                    offset = offset,
                    size   = size,
                };
                ThrowExternalExceptionIfNotSuccess(nameof(vkInvalidateMappedMemoryRanges), vkInvalidateMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange));
            }
            return((T *)pDestination);
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        /// <exception cref="ExternalException">The call to <see cref="vkMapMemory(IntPtr, ulong, ulong, ulong, uint, void**)" /> failed.</exception>
        /// <exception cref="ExternalException">The call to <see cref="vkFlushMappedMemoryRanges(IntPtr, uint, VkMappedMemoryRange*)" /> failed.</exception>
        public override void Write(ReadOnlySpan <byte> bytes)
        {
            var vulkanDevice       = VulkanGraphicsDevice.VulkanDevice;
            var vulkanDeviceMemory = VulkanDeviceMemory;
            var bytesWritten       = bytes.Length;

            void *pDestination;

            ThrowExternalExceptionIfNotSuccess(nameof(vkMapMemory), vkMapMemory(vulkanDevice, vulkanDeviceMemory, offset: 0, size: unchecked ((ulong)bytesWritten), flags: 0, &pDestination));

            var destination = new Span <byte>(pDestination, bytesWritten);

            bytes.CopyTo(destination);

            var mappedMemoryRange = new VkMappedMemoryRange {
                sType  = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
                memory = vulkanDeviceMemory,
                offset = 0,
                size   = VK_WHOLE_SIZE,
            };

            ThrowExternalExceptionIfNotSuccess(nameof(vkFlushMappedMemoryRanges), vkFlushMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange));

            vkUnmapMemory(vulkanDevice, vulkanDeviceMemory);
        }
Exemplo n.º 3
0
        /// <inheritdoc />
        /// <exception cref="ExternalException">The call to <see cref="vkFlushMappedMemoryRanges(IntPtr, uint, VkMappedMemoryRange*)" /> failed.</exception>
        public override void Unmap(nuint writtenRangeOffset, nuint writtenRangeLength)
        {
            var vulkanGraphicsHeap = VulkanGraphicsHeap;
            var vulkanDeviceMemory = vulkanGraphicsHeap.VulkanDeviceMemory;

            var vulkanGraphicsDevice = vulkanGraphicsHeap.VulkanGraphicsDevice;
            var vulkanDevice         = vulkanGraphicsDevice.VulkanDevice;

            if (writtenRangeLength != 0)
            {
                var vulkanGraphicsAdapter = vulkanGraphicsDevice.VulkanGraphicsAdapter;
                var nonCoherentAtomSize   = vulkanGraphicsAdapter.VulkanPhysicalDeviceProperties.limits.nonCoherentAtomSize;

                var offset = Offset + writtenRangeOffset;
                var size   = (writtenRangeLength + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1);

                var mappedMemoryRange = new VkMappedMemoryRange {
                    sType  = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
                    memory = vulkanDeviceMemory,
                    offset = offset,
                    size   = size,
                };
                ThrowExternalExceptionIfNotSuccess(nameof(vkFlushMappedMemoryRanges), vkFlushMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange));
            }
            vkUnmapMemory(vulkanDevice, vulkanDeviceMemory);
        }
Exemplo n.º 4
0
        public static void Flush(Device device, MappedMemoryRange ranges)
        {
            VkMappedMemoryRange rangeNative = Marshal(ranges);

            unsafe
            {
                FlushInternal(device, 1, &rangeNative);
            }
        }
Exemplo n.º 5
0
        public static void Invalidate(Device device, MappedMemoryRange ranges)
        {
            VkMappedMemoryRange rangeNative = Marshal(ranges);

            unsafe
            {
                InvalidateInternal(device, 1, &rangeNative);
            }
        }
Exemplo n.º 6
0
        /**
         * Invalidate a memory range of the buffer to make it visible to the host
         *
         * @note Only required for non-coherent memory
         *
         * @param size (Optional) Size of the memory range to invalidate. Pass WholeSize to invalidate the complete buffer range.
         * @param offset (Optional) Byte offset from beginning
         *
         * @return VkResult of the invalidate call
         */
        public VkResult invalidate(VkDeviceSize size = WholeSize, VkDeviceSize offset = 0)
        {
            VkMappedMemoryRange mappedRange = VkMappedMemoryRange.New();

            mappedRange.memory = memory;
            mappedRange.offset = offset;
            mappedRange.size   = size;
            return(vkInvalidateMappedMemoryRanges(device, 1, &mappedRange));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Flush a memory range of the buffer to make it visible to the device.
        /// </summary>
        /// <param name="size">(Optional) Size of the memory range to flush. Pass WholeSize to flush the complete buffer range.</param>
        /// <param name="offset">(Optional) Byte offset from beginning.</param>
        /// <returns>VkResult of the flush call.</returns>
        public VkResult flush(VkDeviceSize size = WholeSize, VkDeviceSize offset = 0)
        {
            VkMappedMemoryRange mappedRange = new VkMappedMemoryRange();

            mappedRange.sType  = MappedMemoryRange;
            mappedRange.memory = memory;
            mappedRange.offset = offset;
            mappedRange.size   = size;
            return(vkFlushMappedMemoryRanges(device, 1, &mappedRange));
        }
Exemplo n.º 8
0
        public void Invalidate(MappedMemoryRange ranges)
        {
            ranges.memory = this;
            VkMappedMemoryRange rangeNative = Marshal(ranges);

            unsafe
            {
                InvalidateInternal(Device, 1, &rangeNative);
            }
        }
Exemplo n.º 9
0
        public void Flush(MappedMemoryRange ranges)
        {
            ranges.memory = this;
            VkMappedMemoryRange rangeNative = Marshal(ranges);

            unsafe
            {
                FlushInternal(Device, 1, &rangeNative);
            }
        }
Exemplo n.º 10
0
        static VkMappedMemoryRange Marshal(MappedMemoryRange range)
        {
            var result = new VkMappedMemoryRange();

            result.sType  = VkStructureType.MappedMemoryRange;
            result.memory = range.memory.Native;
            result.offset = range.offset;
            result.size   = range.size;

            return(result);
        }
Exemplo n.º 11
0
        public void Flush(uint startIndex, uint endIndex)
        {
            VkMappedMemoryRange mr = new VkMappedMemoryRange
            {
                sType  = VkStructureType.MappedMemoryRange,
                memory = memoryPool.vkMemory,
                offset = poolOffset + (ulong)(startIndex * TSize),
                size   = (ulong)((endIndex - startIndex) * TSize)
            };

            vkFlushMappedMemoryRanges(Dev.VkDev, 1, ref mr);
        }
Exemplo n.º 12
0
        public void Invalidate(ulong offset, ulong size)
        {
            VkMappedMemoryRange rangeNative = new VkMappedMemoryRange();

            rangeNative.sType  = VkStructureType.MappedMemoryRange;
            rangeNative.memory = deviceMemory;
            rangeNative.offset = offset;
            rangeNative.size   = size;

            unsafe
            {
                InvalidateInternal(Device, 1, &rangeNative);
            }
        }
        void updateDynamicUniformBuffer(bool force = false)
        {
            // Update at max. 60 fps
            animationTimer += (frameTimer * 100.0f);
            if ((animationTimer <= 1.0f / 60.0f) && (!force))
            {
                return;
            }

            // Dynamic ubo with per-object model matrices indexed by offsets in the command buffer
            uint    dim    = (uint)(Math.Pow(OBJECT_INSTANCES, (1.0f / 3.0f)));
            Vector3 offset = new Vector3(5.0f);

            for (uint x = 0; x < dim; x++)
            {
                for (uint y = 0; y < dim; y++)
                {
                    for (uint z = 0; z < dim; z++)
                    {
                        uint index = x * dim * dim + y * dim + z;

                        // Aligned offset
                        Matrix4x4 *modelMat = (Matrix4x4 *)(((ulong)uboDataDynamic_model + (index * (ulong)dynamicAlignment)));

                        // Update rotations
                        rotations[index] += animationTimer * rotationSpeeds[index];

                        // Update matrices
                        Vector3 pos      = new Vector3(-((dim * offset.X) / 2.0f) + offset.X / 2.0f + x * offset.X, -((dim * offset.Y) / 2.0f) + offset.Y / 2.0f + y * offset.Y, -((dim * offset.Z) / 2.0f) + offset.Z / 2.0f + z * offset.Z);
                        *       modelMat = Matrix4x4.CreateTranslation(pos);
                        *       modelMat = Matrix4x4.CreateRotationX(Util.DegreesToRadians(rotations[index].X)) * *modelMat;
                        *       modelMat = Matrix4x4.CreateRotationY(Util.DegreesToRadians(rotations[index].Y)) * *modelMat;
                        *       modelMat = Matrix4x4.CreateRotationZ(Util.DegreesToRadians(rotations[index].Z)) * *modelMat;
                    }
                }
            }

            animationTimer = 0.0f;

            Unsafe.CopyBlock(uniformBuffers_dynamic.mapped, uboDataDynamic_model, (uint)uniformBuffers_dynamic.size);
            // Flush to make changes visible to the host
            VkMappedMemoryRange memoryRange = Initializers.mappedMemoryRange();

            memoryRange.memory = uniformBuffers_dynamic.memory;
            memoryRange.size   = uniformBuffers_dynamic.size;
            vkFlushMappedMemoryRanges(device, 1, &memoryRange);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Flush memory, note that coherent memory desn't need it.
        /// </summary>
        /// <param name="startIndex">index of the first T element to flush</param>
        /// <param name="endIndex">index of the last T element to flush</param>
        public void Flush(uint startIndex, uint endIndex)
        {
            //TODO: vulkan has some alignement constrains on flushing!
            VkMappedMemoryRange mr = new VkMappedMemoryRange {
                sType = VkStructureType.MappedMemoryRange,
#if MEMORY_POOLS
                memory = memoryPool.vkMemory,
                offset = poolOffset + (ulong)(startIndex * TSize),
#else
                memory = vkMemory,
                offset = (ulong)(startIndex * TSize),
#endif
                size = (ulong)((endIndex - startIndex) * TSize)
            };

            vkFlushMappedMemoryRanges(Dev.VkDev, 1, ref mr);
        }
Exemplo n.º 15
0
        /**
         * Create a buffer on the device
         *
         * @param usageFlags Usage flag bitmask for the buffer (i.e. index, vertex, uniform buffer)
         * @param memoryPropertyFlags Memory properties for this buffer (i.e. device local, host visible, coherent)
         * @param size Size of the buffer in byes
         * @param buffer Pointer to the buffer handle acquired by the function
         * @param memory Pointer to the memory handle acquired by the function
         * @param data Pointer to the data that should be copied to the buffer after creation (optional, if not set, no data is copied over)
         *
         * @return Success if buffer handle and memory have been created and (optionally passed) data has been copied
         */
        public VkResult createBuffer(VkBufferUsageFlagBits usageFlags, VkMemoryPropertyFlagBits memoryPropertyFlags, ulong size, VkBuffer *buffer, VkDeviceMemory *memory, void *data = null)
        {
            // Create the buffer handle
            VkBufferCreateInfo bufferCreateInfo = new VkBufferCreateInfo();

            bufferCreateInfo.sType       = BufferCreateInfo;
            bufferCreateInfo.usage       = usageFlags;
            bufferCreateInfo.size        = size;
            bufferCreateInfo.sharingMode = VkSharingMode.Exclusive;
            vkCreateBuffer(LogicalDevice, &bufferCreateInfo, null, buffer);

            // Create the memory backing up the buffer handle
            VkMemoryRequirements memReqs;
            VkMemoryAllocateInfo memAlloc = new VkMemoryAllocateInfo();

            memAlloc.sType = MemoryAllocateInfo;
            vkGetBufferMemoryRequirements(LogicalDevice, *buffer, &memReqs);
            memAlloc.allocationSize = memReqs.size;
            // Find a memory type index that fits the properties of the buffer
            memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, memoryPropertyFlags);
            vkAllocateMemory(LogicalDevice, &memAlloc, null, memory);

            // If a pointer to the buffer data has been passed, map the buffer and copy over the data
            if (data != null)
            {
                IntPtr mapped;
                vkMapMemory(LogicalDevice, *memory, 0, size, 0, &mapped);
                Unsafe.CopyBlock(mapped, data, (uint)size);
                // If host coherency hasn't been requested, do a manual flush to make writes visible
                if ((memoryPropertyFlags & VkMemoryPropertyFlagBits.HostCoherent) == 0)
                {
                    VkMappedMemoryRange mappedRange = new VkMappedMemoryRange();
                    mappedRange.memory = *memory;
                    mappedRange.offset = 0;
                    mappedRange.size   = size;
                    vkFlushMappedMemoryRanges(LogicalDevice, 1, &mappedRange);
                }
                vkUnmapMemory(LogicalDevice, *memory);
            }

            // Attach the memory to the buffer object
            vkBindBufferMemory(LogicalDevice, *buffer, *memory, 0);

            return(VkResult.Success);
        }
Exemplo n.º 16
0
        public void Flush()
        {
            VkMappedMemoryRange range = MapRange;

            vkFlushMappedMemoryRanges(Dev.VkDev, 1, ref range);
        }
Exemplo n.º 17
0
 public static VkResult vkFlushMappedMemoryRanges(VkDevice device, VkMappedMemoryRange memoryRange)
 {
     return(vkFlushMappedMemoryRanges(device, 1, &memoryRange));
 }
Exemplo n.º 18
0
        public static VkMappedMemoryRange mappedMemoryRange()
        {
            VkMappedMemoryRange mappedMemoryRange = VkMappedMemoryRange.New();

            return(mappedMemoryRange);
        }