/// <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); }
/// <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); }
/// <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); }
public static void Flush(Device device, MappedMemoryRange ranges) { VkMappedMemoryRange rangeNative = Marshal(ranges); unsafe { FlushInternal(device, 1, &rangeNative); } }
public static void Invalidate(Device device, MappedMemoryRange ranges) { VkMappedMemoryRange rangeNative = Marshal(ranges); unsafe { InvalidateInternal(device, 1, &rangeNative); } }
/** * 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)); }
/// <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)); }
public void Invalidate(MappedMemoryRange ranges) { ranges.memory = this; VkMappedMemoryRange rangeNative = Marshal(ranges); unsafe { InvalidateInternal(Device, 1, &rangeNative); } }
public void Flush(MappedMemoryRange ranges) { ranges.memory = this; VkMappedMemoryRange rangeNative = Marshal(ranges); unsafe { FlushInternal(Device, 1, &rangeNative); } }
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); }
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); }
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); }
/// <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); }
/** * 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); }
public void Flush() { VkMappedMemoryRange range = MapRange; vkFlushMappedMemoryRanges(Dev.VkDev, 1, ref range); }
public static VkResult vkFlushMappedMemoryRanges(VkDevice device, VkMappedMemoryRange memoryRange) { return(vkFlushMappedMemoryRanges(device, 1, &memoryRange)); }
public static VkMappedMemoryRange mappedMemoryRange() { VkMappedMemoryRange mappedMemoryRange = VkMappedMemoryRange.New(); return(mappedMemoryRange); }