Missing warning about buffer access and usage flags mismatch
Describe the situation in which you encountered the missing validation Issue description: Currently there is no VVL message when a uniform buffer is bound and then synchronized with VK_ACCESS_2_SHADER_STORAGE_READ_BIT instead of VK_ACCESS_2_UNIFORM_READ_BIT.
I didn't check if its happening in other combinations (eg storage buffer with uniform read bit).
If missing, this should be a core check, syncval detects race conditions assuming that API is used correclty.
@StefanPoelloth I'm not sure if that's violation of the spec either, can't find that there is a VUID that prohibits this. I think you can specify any accesses supported on specific stages. Then if you do not specify access that actually takes place then it's missing synchronization (and this can be detected by syncval), and if specified access does not happen (as described in this issue) then it's no op but still valid to specify.
This can be about that there is no special type for uniform buffers in vulkan. The same buffer can have different usages. Yes, probably it's possible to have a check for buffers with only uniform usage, but it looks like the specification does not prohibit such mismatch. Then if we add such check then it can break some existing apps that use less conservative masks that cover multiple use cases.
@artem-lunarg I dont think it validates the spec. Thats why i think it should be in the syncval, though it doesnt make any sense to me to sync a uniform with storage read and i cant think of any legitimate use. In my case the uniform buffers where actually accessed but there was no syncval error. In fact, since we generate barriers, all our uniform buffers were only synced with storage reads with no error from syncval.
Thats why i think it should be in the syncval
That's not in the scope of syncval, syncval detects race conditions based on syncrhonization specified using API commands, syncval does not validate correctness of API usage. I'll ask on khronos board about this but I think sometimes it happens in the spec that some combinations of values makes no sense (like some stage-access pairs). Maybe such things can be checked in best practices.
Internal link to question on khronos board: https://gitlab.khronos.org/vulkan/vulkan/-/issues/4282
@StefanPoelloth is synchronization specified via VkBufferMemoryBarrier?
The barrier in question is BufferMemoryBarrier2 used in CmdPipelineBarrier2 and the barrier created is:
(DescriptorType.UniformBuffer, PipelineStageFlags2.PipelineStage2ComputeShaderBitKhr, AccessFlags2.Access2ShaderStorageReadBitKhr, 1), // CameraFrustumUBO
The types are Silk.Net types but they map to their expected cpp types.
In my case the uniform buffers where actually accessed but there was no syncval error. In fact, since we generate barriers, all our uniform buffers were only synced with storage reads with no error from syncval.
If uniform buffers were accessed from the shader then by default we don't validate descriptor accesses since it can cause false positives in current implementation and that option is disabled by default (the plan is to improve this in the future, needs gpu-av support). If you have "shader accesses heuristic" turned off you can check how it works with this option enabed, but again shader access validation does not work correctly in general, that's why it's optional and "heuristic":
Yeah, usually I test with every check enabled (core, sync... its fast enough). Heuristics didn't catch it either. I was hoping it could be implemented in a way that doesnt rely on gpu-av. The shader, descriptor type (from layout) and barrier are known, so it should be possible. But if its intended to be used like this (eg buffer not accessed) its probably not possible without gpu-av.
The shader, descriptor type (from layout) and barrier are known, so it should be possible.
Yes, I'd expect false positive in case heuristic does not work, not false negative (but maybe that's also possible)
I'd like to write a test to reproduce this, but need a help to understand this scenario better. From what I understood there is a uniform buffer read. There should be a write that causes race condition. When does this write happen?
The buffer is a small buffer living in BAR memory, device local, host visible and mapped. each frame the buffer is updated with new values and a barrier is placed with PipelineStageFlags2.HostBit, AccessFlags2.HostWriteBit.
I can provide a repro through share.lunarg.com if needed.
each frame the buffer is updated with new values and a barrier is placed with PipelineStageFlags2.HostBit, AccessFlags2.HostWriteBit
@StefanPoelloth I'm affraid this is one of the limitations of syncval: (https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/syncval_usage.md#known-limitations)
Host memory accesses are not tracked. Corresponding race conditions are not reported.
But, if update happens before QueueSubmit then there is a guarantee that data written by the host will be visible to device after submit, accoring to https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#synchronization-submission-host-writes, so no barrier is needed in this case (I'm not sure about the details of BAR memory though)
The first access scope includes all host writes to mappable device memory that are available to the host memory domain.
I myself had host barriers not long ago in my program, but then realized they are not needed: https://github.com/kennyalive/Quake-III-Arena-Kenny-Edition/commit/2b9197b8afa06fec93232ec884bc13cb14ae243a
The board suggested that combinations that result in no-op can be checked in Best Practices, so I'll try to add that as part of this issue.