public unsafe void DestroyNow() { GraphicsDevice.RegisterBufferMemoryUsage(-SizeInBytes); if (NativeBufferView != VkBufferView.Null) { vkDestroyBufferView(GraphicsDevice.NativeDevice, NativeBufferView, null); NativeBufferView = VkBufferView.Null; } if (NativeBuffer != VkBuffer.Null) { vkDestroyBuffer(GraphicsDevice.NativeDevice, NativeBuffer, null); NativeBuffer = VkBuffer.Null; } if (NativeMemory != VkDeviceMemory.Null) { if (NativeMemoryOffset.HasValue) { VulkanMemoryPool.Free(this, NativeMemoryOffset.Value); } else { vkFreeMemory(GraphicsDevice.NativeDevice, NativeMemory, null); } NativeMemory = VkDeviceMemory.Null; } base.OnDestroyed(); }
/// <inheritdoc/> protected internal override void OnDestroyed() { Ready = false; GraphicsDevice.RegisterBufferMemoryUsage(-SizeInBytes); if (NativeBufferView != VkBufferView.Null) { GraphicsDevice.Collect(NativeBufferView); NativeBufferView = VkBufferView.Null; } if (NativeBuffer != VkBuffer.Null) { GraphicsDevice.Collect(NativeBuffer); NativeBuffer = VkBuffer.Null; } if (NativeMemory != VkDeviceMemory.Null) { if (NativeMemoryOffset.HasValue) { VulkanMemoryPool.Free(this, NativeMemoryOffset.Value); } else { GraphicsDevice.Collect(NativeMemory); } NativeMemory = VkDeviceMemory.Null; } base.OnDestroyed(); }
/// <summary> /// Explicitly recreate buffer with given data. Usually called after a <see cref="GraphicsDevice"/> reset. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dataPointer"></param> public unsafe void Recreate(IntPtr dataPointer) { // capture vertex information for possible later easy batching or physics mesh generation if (dataPointer != IntPtr.Zero && (ViewFlags == BufferFlags.VertexBuffer && (CaptureAllModelBuffers || bufferDescription.SizeInBytes <= CaptureVertexBuffersOfSize) || ViewFlags == BufferFlags.IndexBuffer && (CaptureAllModelBuffers || bufferDescription.SizeInBytes <= CaptureIndexBuffersOfSize))) { VertIndexData = new byte[Description.SizeInBytes]; fixed(byte *vid = &VertIndexData[0]) { Utilities.CopyMemory((IntPtr)vid, dataPointer, VertIndexData.Length); } } else { VertIndexData = null; } var createInfo = new VkBufferCreateInfo { sType = VkStructureType.BufferCreateInfo, size = (ulong)bufferDescription.SizeInBytes, flags = VkBufferCreateFlags.None, }; createInfo.usage |= VkBufferUsageFlags.TransferSrc; createInfo.usage |= VkBufferUsageFlags.TransferDst; if (Usage == GraphicsResourceUsage.Staging) { NativeAccessMask = VkAccessFlags.HostRead | VkAccessFlags.HostWrite; NativePipelineStageMask |= VkPipelineStageFlags.Host; } else { if ((ViewFlags & BufferFlags.VertexBuffer) != 0) { createInfo.usage |= VkBufferUsageFlags.VertexBuffer; NativeAccessMask |= VkAccessFlags.VertexAttributeRead; NativePipelineStageMask |= VkPipelineStageFlags.VertexInput; } if ((ViewFlags & BufferFlags.IndexBuffer) != 0) { createInfo.usage |= VkBufferUsageFlags.IndexBuffer; NativeAccessMask |= VkAccessFlags.IndexRead; NativePipelineStageMask |= VkPipelineStageFlags.VertexInput; } if ((ViewFlags & BufferFlags.ConstantBuffer) != 0) { createInfo.usage |= VkBufferUsageFlags.UniformBuffer; NativeAccessMask |= VkAccessFlags.UniformRead; NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader; } if ((ViewFlags & BufferFlags.ShaderResource) != 0) { createInfo.usage |= VkBufferUsageFlags.UniformTexelBuffer; NativeAccessMask |= VkAccessFlags.ShaderRead; NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader; if ((ViewFlags & BufferFlags.UnorderedAccess) != 0) { createInfo.usage |= VkBufferUsageFlags.StorageTexelBuffer; NativeAccessMask |= VkAccessFlags.ShaderWrite; } } } // Create buffer vkCreateBuffer(GraphicsDevice.NativeDevice, &createInfo, null, out NativeBuffer); // Allocate memory var memoryProperties = VkMemoryPropertyFlags.DeviceLocal; if (bufferDescription.Usage == GraphicsResourceUsage.Staging || Usage == GraphicsResourceUsage.Dynamic) { memoryProperties = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent; } vkGetBufferMemoryRequirements(GraphicsDevice.NativeDevice, NativeBuffer, out var memoryRequirements); if (bufferDescription.Usage == GraphicsResourceUsage.Staging || Usage == GraphicsResourceUsage.Dynamic) { AllocateMemory(memoryProperties, memoryRequirements); // special case that doesn't use a pool } else if (VulkanMemoryPool.TryAllocateMemoryForBuffer(createInfo.size, GraphicsDevice.NativeDevice, GraphicsDevice.NativePhysicalDevice, ref memoryRequirements, ref memoryProperties, out var memOffset, out var devmem)) { NativeMemory = devmem; NativeMemoryOffset = memOffset; }