diff --git a/src/Veldrid/GraphicsDevice.cs b/src/Veldrid/GraphicsDevice.cs index ee20164f..52cbf9fe 100644 --- a/src/Veldrid/GraphicsDevice.cs +++ b/src/Veldrid/GraphicsDevice.cs @@ -793,6 +793,9 @@ public void UpdateBuffer( $"The data size given to UpdateBuffer is too large. The given buffer can only hold {buffer.SizeInBytes} total bytes. The requested update would require {bufferOffsetInBytes + sizeInBytes} bytes."); } + if (sizeInBytes == 0) + return; + UpdateBufferCore(buffer, bufferOffsetInBytes, source, sizeInBytes); } diff --git a/src/Veldrid/Vk/CommonStrings.cs b/src/Veldrid/Vk/CommonStrings.cs index 57f3caaf..639ebf3b 100644 --- a/src/Veldrid/Vk/CommonStrings.cs +++ b/src/Veldrid/Vk/CommonStrings.cs @@ -19,5 +19,6 @@ internal static class CommonStrings public static FixedUtf8String Main { get; } = "main"; public static FixedUtf8String VkKhrGetPhysicalDeviceProperties2 { get; } = "VK_KHR_get_physical_device_properties2"; public static FixedUtf8String VkKhrPortabilitySubset { get; } = "VK_KHR_portability_subset"; + public static FixedUtf8String VkKhrPortabilityEnumeration { get; } = "VK_KHR_portability_enumeration"; } } diff --git a/src/Veldrid/Vk/VkCommandList.cs b/src/Veldrid/Vk/VkCommandList.cs index 621f6a61..4dcdb53e 100644 --- a/src/Veldrid/Vk/VkCommandList.cs +++ b/src/Veldrid/Vk/VkCommandList.cs @@ -226,6 +226,81 @@ public override void SetViewport(uint index, ref Viewport viewport) } } + private protected override void UpdateBufferCore(DeviceBuffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes) + { + VkBuffer stagingBuffer = getStagingBuffer(sizeInBytes); + gd.UpdateBuffer(stagingBuffer, 0, source, sizeInBytes); + CopyBuffer(stagingBuffer, 0, buffer, bufferOffsetInBytes, sizeInBytes); + } + + protected override void CopyBufferCore( + DeviceBuffer source, + uint sourceOffset, + DeviceBuffer destination, + uint destinationOffset, + uint sizeInBytes) + { + ensureNoRenderPass(); + + VkBuffer srcVkBuffer = Util.AssertSubtype(source); + currentStagingInfo.Resources.Add(srcVkBuffer.RefCount); + VkBuffer dstVkBuffer = Util.AssertSubtype(destination); + currentStagingInfo.Resources.Add(dstVkBuffer.RefCount); + + VkBufferCopy region = new VkBufferCopy + { + srcOffset = sourceOffset, + dstOffset = destinationOffset, + size = sizeInBytes + }; + + vkCmdCopyBuffer(CommandBuffer, srcVkBuffer.DeviceBuffer, dstVkBuffer.DeviceBuffer, 1, ref region); + + bool needToProtectUniform = destination.Usage.HasFlag(BufferUsage.UniformBuffer); + + VkMemoryBarrier barrier; + barrier.sType = VkStructureType.MemoryBarrier; + barrier.srcAccessMask = VkAccessFlags.TransferWrite; + barrier.dstAccessMask = needToProtectUniform ? VkAccessFlags.UniformRead : VkAccessFlags.VertexAttributeRead; + barrier.pNext = null; + vkCmdPipelineBarrier( + CommandBuffer, + VkPipelineStageFlags.Transfer, needToProtectUniform + ? VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.ComputeShader | + VkPipelineStageFlags.FragmentShader | VkPipelineStageFlags.GeometryShader | + VkPipelineStageFlags.TessellationControlShader | VkPipelineStageFlags.TessellationEvaluationShader + : VkPipelineStageFlags.VertexInput, + VkDependencyFlags.None, + 1, ref barrier, + 0, null, + 0, null); + } + + protected override void CopyTextureCore( + Texture source, + uint srcX, uint srcY, uint srcZ, + uint srcMipLevel, + uint srcBaseArrayLayer, + Texture destination, + uint dstX, uint dstY, uint dstZ, + uint dstMipLevel, + uint dstBaseArrayLayer, + uint width, uint height, uint depth, + uint layerCount) + { + ensureNoRenderPass(); + CopyTextureCore_VkCommandBuffer( + CommandBuffer, + source, srcX, srcY, srcZ, srcMipLevel, srcBaseArrayLayer, + destination, dstX, dstY, dstZ, dstMipLevel, dstBaseArrayLayer, + width, height, depth, layerCount); + + VkTexture srcVkTexture = Util.AssertSubtype(source); + currentStagingInfo.Resources.Add(srcVkTexture.RefCount); + VkTexture dstVkTexture = Util.AssertSubtype(destination); + currentStagingInfo.Resources.Add(dstVkTexture.RefCount); + } + internal static void CopyTextureCore_VkCommandBuffer( VkCommandBuffer cb, Texture source, @@ -633,68 +708,6 @@ protected override void SetComputeResourceSetCore(uint slot, ResourceSet rs, uin } } - protected override void CopyBufferCore( - DeviceBuffer source, - uint sourceOffset, - DeviceBuffer destination, - uint destinationOffset, - uint sizeInBytes) - { - ensureNoRenderPass(); - - var srcVkBuffer = Util.AssertSubtype(source); - currentStagingInfo.Resources.Add(srcVkBuffer.RefCount); - var dstVkBuffer = Util.AssertSubtype(destination); - currentStagingInfo.Resources.Add(dstVkBuffer.RefCount); - - var region = new VkBufferCopy - { - srcOffset = sourceOffset, - dstOffset = destinationOffset, - size = sizeInBytes - }; - - vkCmdCopyBuffer(CommandBuffer, srcVkBuffer.DeviceBuffer, dstVkBuffer.DeviceBuffer, 1, ref region); - - VkMemoryBarrier barrier; - barrier.sType = VkStructureType.MemoryBarrier; - barrier.srcAccessMask = VkAccessFlags.TransferWrite; - barrier.dstAccessMask = VkAccessFlags.VertexAttributeRead; - barrier.pNext = null; - vkCmdPipelineBarrier( - CommandBuffer, - VkPipelineStageFlags.Transfer, VkPipelineStageFlags.VertexInput, - VkDependencyFlags.None, - 1, ref barrier, - 0, null, - 0, null); - } - - protected override void CopyTextureCore( - Texture source, - uint srcX, uint srcY, uint srcZ, - uint srcMipLevel, - uint srcBaseArrayLayer, - Texture destination, - uint dstX, uint dstY, uint dstZ, - uint dstMipLevel, - uint dstBaseArrayLayer, - uint width, uint height, uint depth, - uint layerCount) - { - ensureNoRenderPass(); - CopyTextureCore_VkCommandBuffer( - CommandBuffer, - source, srcX, srcY, srcZ, srcMipLevel, srcBaseArrayLayer, - destination, dstX, dstY, dstZ, dstMipLevel, dstBaseArrayLayer, - width, height, depth, layerCount); - - var srcVkTexture = Util.AssertSubtype(source); - currentStagingInfo.Resources.Add(srcVkTexture.RefCount); - var dstVkTexture = Util.AssertSubtype(destination); - currentStagingInfo.Resources.Add(dstVkTexture.RefCount); - } - private VkCommandBuffer getNextCommandBuffer() { lock (commandBufferListLock) @@ -1190,13 +1203,6 @@ private protected override void SetPipelineCore(Pipeline pipeline) currentStagingInfo.Resources.Add(vkPipeline.RefCount); } - private protected override void UpdateBufferCore(DeviceBuffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes) - { - var stagingBuffer = getStagingBuffer(sizeInBytes); - gd.UpdateBuffer(stagingBuffer, 0, source, sizeInBytes); - CopyBuffer(stagingBuffer, 0, buffer, bufferOffsetInBytes, sizeInBytes); - } - private protected override void GenerateMipmapsCore(Texture texture) { ensureNoRenderPass(); diff --git a/src/Veldrid/Vk/VkGraphicsDevice.cs b/src/Veldrid/Vk/VkGraphicsDevice.cs index 825da5fd..d3bb8552 100644 --- a/src/Veldrid/Vk/VkGraphicsDevice.cs +++ b/src/Veldrid/Vk/VkGraphicsDevice.cs @@ -13,6 +13,8 @@ namespace Veldrid.Vk { internal unsafe class VkGraphicsDevice : GraphicsDevice { + private const uint vk_instance_create_enumerate_portability_bit_khr = 0x00000001; + public override string DeviceName => deviceName; public override string VendorName => vendorName; @@ -770,9 +772,17 @@ private void createInstance(bool debug, VulkanDeviceOptions options) var instanceExtensions = new StackList(); var instanceLayers = new StackList(); - if (availableInstanceExtensions.Contains(CommonStrings.VkKhrPortabilitySubset)) surfaceExtensions.Add(CommonStrings.VkKhrPortabilitySubset); + if (availableInstanceExtensions.Contains(CommonStrings.VkKhrPortabilitySubset)) + surfaceExtensions.Add(CommonStrings.VkKhrPortabilitySubset); + + if (availableInstanceExtensions.Contains(CommonStrings.VkKhrSurfaceExtensionName)) + surfaceExtensions.Add(CommonStrings.VkKhrSurfaceExtensionName); - if (availableInstanceExtensions.Contains(CommonStrings.VkKhrSurfaceExtensionName)) surfaceExtensions.Add(CommonStrings.VkKhrSurfaceExtensionName); + if (availableInstanceExtensions.Contains(CommonStrings.VkKhrPortabilityEnumeration)) + { + instanceExtensions.Add(CommonStrings.VkKhrPortabilityEnumeration); + instanceCi.flags |= vk_instance_create_enumerate_portability_bit_khr; + } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {