Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@ public unsafe void Recreate(IntPtr dataPointer)
NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader;
}

if ((ViewFlags & BufferFlags.StructuredBuffer) != 0)
{
createInfo.usage |= VkBufferUsageFlags.StorageBuffer;
NativeAccessMask |= VkAccessFlags.UniformRead;
NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader;

if ((ViewFlags & BufferFlags.UnorderedAccess) != 0)
{
NativeAccessMask |= VkAccessFlags.ShaderWrite;
}
}

if ((ViewFlags & BufferFlags.ShaderResource) != 0)
{
createInfo.usage |= VkBufferUsageFlags.UniformTexelBuffer;
Expand Down
59 changes: 43 additions & 16 deletions sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ private unsafe void FlushInternal(bool wait)

if (activePipeline != null)
{
vkCmdBindPipeline(currentCommandList.NativeCommandBuffer, VkPipelineBindPoint.Graphics, activePipeline.NativePipeline);
vkCmdBindPipeline(currentCommandList.NativeCommandBuffer, activePipeline.IsCompute ? VkPipelineBindPoint.Compute : VkPipelineBindPoint.Graphics, activePipeline.NativePipeline);
var descriptorSetCopy = descriptorSet;
vkCmdBindDescriptorSets(currentCommandList.NativeCommandBuffer, VkPipelineBindPoint.Graphics, activePipeline.NativeLayout, firstSet: 0, descriptorSetCount: 1, &descriptorSetCopy, dynamicOffsetCount: 0, dynamicOffsets: null);
vkCmdBindDescriptorSets(currentCommandList.NativeCommandBuffer, activePipeline.IsCompute ? VkPipelineBindPoint.Compute : VkPipelineBindPoint.Graphics, activePipeline.NativeLayout, firstSet: 0, descriptorSetCount: 1, &descriptorSetCopy, dynamicOffsetCount: 0, dynamicOffsets: null);
}
SetRenderTargetsImpl(depthStencilBuffer, renderTargetCount, renderTargets);
}
Expand Down Expand Up @@ -249,7 +249,11 @@ private unsafe void PrepareDraw()

// Lazily set the render pass and frame buffer
EnsureRenderPass();
BindDescriptorSets();
}

private unsafe void BindDescriptorSets()
{
// Keep track of descriptor pool usage
bool isPoolExhausted = ++allocatedSetCount > GraphicsDevice.MaxDescriptorSetCount;
for (int i = 0; i < DescriptorSetLayout.DescriptorTypeCount; i++)
Expand Down Expand Up @@ -328,18 +332,28 @@ private unsafe void PrepareDraw()
sType = VkStructureType.WriteDescriptorSet,
descriptorType = mapping.DescriptorType,
dstSet = localDescriptorSet,
dstBinding = (uint) mapping.DestinationBinding,
dstBinding = (uint)mapping.DestinationBinding,
dstArrayElement = 0,
descriptorCount = 1
};

switch (mapping.DescriptorType)
{
case VkDescriptorType.SampledImage:
var texture = heapObject.Value as Texture;
descriptorData->ImageInfo = new VkDescriptorImageInfo { imageView = texture?.NativeImageView ?? GraphicsDevice.EmptyTexture.NativeImageView, imageLayout = VkImageLayout.ShaderReadOnlyOptimal };
write->pImageInfo = &descriptorData->ImageInfo;
break;
{
var texture = heapObject.Value as Texture;
descriptorData->ImageInfo = new VkDescriptorImageInfo { imageView = texture?.NativeImageView ?? GraphicsDevice.EmptyTexture.NativeImageView, imageLayout = VkImageLayout.ShaderReadOnlyOptimal };
write->pImageInfo = &descriptorData->ImageInfo;
break;
}

case VkDescriptorType.StorageImage:
{
var texture = heapObject.Value as Texture;
descriptorData->ImageInfo = new VkDescriptorImageInfo { imageView = texture?.NativeImageView ?? GraphicsDevice.EmptyTexture.NativeImageView, imageLayout = VkImageLayout.General };
write->pImageInfo = &descriptorData->ImageInfo;
break;
}

case VkDescriptorType.Sampler:
var samplerState = heapObject.Value as SamplerState;
Expand All @@ -349,7 +363,7 @@ private unsafe void PrepareDraw()

case VkDescriptorType.UniformBuffer:
var buffer = heapObject.Value as Buffer;
descriptorData->BufferInfo = new VkDescriptorBufferInfo { buffer = buffer?.NativeBuffer ?? VkBuffer.Null, offset = (ulong) heapObject.Offset, range = (ulong) heapObject.Size };
descriptorData->BufferInfo = new VkDescriptorBufferInfo { buffer = buffer?.NativeBuffer ?? VkBuffer.Null, offset = (ulong)heapObject.Offset, range = (ulong)heapObject.Size };
write->pBufferInfo = &descriptorData->BufferInfo;
break;

Expand All @@ -359,14 +373,20 @@ private unsafe void PrepareDraw()
write->pTexelBufferView = &descriptorData->BufferView;
break;

case VkDescriptorType.StorageBuffer:
buffer = heapObject.Value as Buffer;
descriptorData->BufferInfo = new VkDescriptorBufferInfo { buffer = buffer?.NativeBuffer ?? VkBuffer.Null, offset = (ulong)heapObject.Offset, range = (ulong)(buffer?.SizeInBytes ?? 0)};
write->pBufferInfo = &descriptorData->BufferInfo;
break;

default:
throw new InvalidOperationException();
}
}

vkUpdateDescriptorSets(GraphicsDevice.NativeDevice, (uint) bindingCount, writes, descriptorCopyCount: 0, descriptorCopies: null);
vkUpdateDescriptorSets(GraphicsDevice.NativeDevice, (uint)bindingCount, writes, descriptorCopyCount: 0, descriptorCopies: null);
#endif
vkCmdBindDescriptorSets(currentCommandList.NativeCommandBuffer, VkPipelineBindPoint.Graphics, activePipeline.NativeLayout, firstSet: 0, descriptorSetCount: 1, &localDescriptorSet, dynamicOffsetCount: 0, dynamicOffsets: null);
vkCmdBindDescriptorSets(currentCommandList.NativeCommandBuffer, activePipeline.IsCompute ? VkPipelineBindPoint.Compute : VkPipelineBindPoint.Graphics, activePipeline.NativeLayout, firstSet: 0, descriptorSetCount: 1, &localDescriptorSet, dynamicOffsetCount: 0, dynamicOffsets: null);
}

private readonly FastList<VkCopyDescriptorSet> copies = new();
Expand All @@ -390,7 +410,7 @@ public void SetPipelineState(PipelineState pipelineState)

activePipeline = pipelineState;

vkCmdBindPipeline(currentCommandList.NativeCommandBuffer, VkPipelineBindPoint.Graphics, pipelineState.NativePipeline);
vkCmdBindPipeline(currentCommandList.NativeCommandBuffer, activePipeline.IsCompute ? VkPipelineBindPoint.Compute : VkPipelineBindPoint.Graphics, pipelineState.NativePipeline);
}

public unsafe void SetVertexBuffer(int index, Buffer buffer, int offset, int stride)
Expand Down Expand Up @@ -446,7 +466,7 @@ public unsafe void ResourceBarrierTransition(GraphicsResource resource, Graphics
case GraphicsResourceState.PixelShaderResource:
texture.NativeLayout = VkImageLayout.ShaderReadOnlyOptimal;
texture.NativeAccessMask = VkAccessFlags.ShaderRead;
texture.NativePipelineStageMask = VkPipelineStageFlags.FragmentShader;
texture.NativePipelineStageMask = VkPipelineStageFlags.FragmentShader | VkPipelineStageFlags.ComputeShader;
break;
case GraphicsResourceState.GenericRead:
texture.NativeLayout = VkImageLayout.General;
Expand Down Expand Up @@ -503,6 +523,9 @@ public void SetDescriptorSets(int index, DescriptorSet[] descriptorSets)
/// <inheritdoc />
public void Dispatch(int threadCountX, int threadCountY, int threadCountZ)
{
CleanupRenderPass();
BindDescriptorSets();
vkCmdDispatch(currentCommandList.NativeCommandBuffer, (uint)threadCountX, (uint)threadCountY, (uint)threadCountZ);
}

/// <summary>
Expand All @@ -512,6 +535,9 @@ public void Dispatch(int threadCountX, int threadCountY, int threadCountZ)
/// <param name="offsetInBytes">The offset information bytes.</param>
public void Dispatch(Buffer indirectBuffer, int offsetInBytes)
{
CleanupRenderPass();
BindDescriptorSets();
vkCmdDispatchIndirect(currentCommandList.NativeCommandBuffer, indirectBuffer.NativeBuffer, (ulong)offsetInBytes);
}

/// <summary>
Expand Down Expand Up @@ -1301,10 +1327,11 @@ public unsafe MappedResource MapSubresource(GraphicsResource resource, int subRe
throw new InvalidOperationException();
}

if (mapMode == MapMode.WriteDiscard)
{
throw new InvalidOperationException("Can't use WriteDiscard on Graphics API that doesn't support renaming");
}
// Maybe it just works if removed?
//if (mapMode == MapMode.WriteDiscard)
//{
// throw new InvalidOperationException("Can't use WriteDiscard on Graphics API that doesn't support renaming");
//}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, does it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to work, but there are probably scenarios that still fail, but I think it should be fine for now. To be fair I was certain I had removed this and not just commented it out but I guess it came back during all my rebases and cherry-picks ...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep an eye on this one in the future.


if (mapMode != MapMode.WriteNoOverwrite && mapMode != MapMode.Write)
{
Expand Down
41 changes: 35 additions & 6 deletions sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,20 @@ public partial class GraphicsDevice

internal HeapPool DescriptorPools;
internal const uint MaxDescriptorSetCount = 256;
internal readonly uint[] MaxDescriptorTypeCounts = new uint[DescriptorSetLayout.DescriptorTypeCount]
{
internal uint[] MaxDescriptorTypeCounts =
[
Comment thread
johang88 marked this conversation as resolved.
256, // Sampler
0, // CombinedImageSampler
512, // SampledImage
0, // StorageImage
64, // StorageImage
64, // UniformTexelBuffer
0, // StorageTexelBuffer
64, // StorageTexelBuffer
512, // UniformBuffer
0, // StorageBuffer
64, // StorageBuffer
0, // UniformBufferDynamic
0, // StorageBufferDynamic
0 // InputAttachment
};
];

internal Buffer EmptyTexelBufferInt, EmptyTexelBufferFloat;
internal Texture EmptyTexture;
Expand Down Expand Up @@ -264,6 +264,22 @@ private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles,
ConstantBufferDataPlacementAlignment = (int)physicalDeviceProperties.limits.minUniformBufferOffsetAlignment;
TimestampFrequency = (long)(1.0e9 / physicalDeviceProperties.limits.timestampPeriod); // Resolution in nanoseconds

// Configure descriptor type max counts
void SetMaxDescriptorTypeCount(VkDescriptorType type, uint limit)
=> MaxDescriptorTypeCounts[(int)type] = Math.Min(MaxDescriptorTypeCounts[(int)type], limit);

SetMaxDescriptorTypeCount(VkDescriptorType.Sampler, physicalDeviceProperties.limits.maxDescriptorSetSamplers);
SetMaxDescriptorTypeCount(VkDescriptorType.CombinedImageSampler, 0); // Not defined.
SetMaxDescriptorTypeCount(VkDescriptorType.SampledImage, physicalDeviceProperties.limits.maxDescriptorSetSampledImages);
SetMaxDescriptorTypeCount(VkDescriptorType.StorageImage, physicalDeviceProperties.limits.maxDescriptorSetStorageImages);
SetMaxDescriptorTypeCount(VkDescriptorType.UniformTexelBuffer, physicalDeviceProperties.limits.maxDescriptorSetSampledImages); // No individual limit
SetMaxDescriptorTypeCount(VkDescriptorType.StorageTexelBuffer, physicalDeviceProperties.limits.maxDescriptorSetStorageImages); // No individual limit
SetMaxDescriptorTypeCount(VkDescriptorType.UniformBuffer, physicalDeviceProperties.limits.maxDescriptorSetUniformBuffers);
SetMaxDescriptorTypeCount(VkDescriptorType.StorageBuffer, physicalDeviceProperties.limits.maxDescriptorSetStorageBuffers);
SetMaxDescriptorTypeCount(VkDescriptorType.UniformBufferDynamic, physicalDeviceProperties.limits.maxDescriptorSetUniformBuffersDynamic);
SetMaxDescriptorTypeCount(VkDescriptorType.StorageBufferDynamic, physicalDeviceProperties.limits.maxDescriptorSetStorageBuffersDynamic);
SetMaxDescriptorTypeCount(VkDescriptorType.InputAttachment, physicalDeviceProperties.limits.maxDescriptorSetInputAttachments);

RequestedProfile = graphicsProfiles.First();

var queueProperties = vkGetPhysicalDeviceQueueFamilyProperties(NativePhysicalDevice);
Expand Down Expand Up @@ -292,11 +308,24 @@ private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles,
depthClamp = true,
};

vkGetPhysicalDeviceFeatures(NativePhysicalDevice, out var deviceFeatures);

if (deviceFeatures.shaderStorageImageReadWithoutFormat)
{
enabledFeature.shaderStorageImageReadWithoutFormat = true;
}

if (deviceFeatures.shaderStorageImageWriteWithoutFormat)
{
enabledFeature.shaderStorageImageWriteWithoutFormat = true;
}

Span<VkUtf8String> supportedExtensionProperties = stackalloc VkUtf8String[]
{
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_DEBUG_MARKER_EXTENSION_NAME,
};

var availableExtensionProperties = GetAvailableExtensionProperties(supportedExtensionProperties);
ValidateExtensionPropertiesAvailability(availableExtensionProperties);
var desiredExtensionProperties = new HashSet<VkUtf8String>
Expand Down
Loading
Loading