anv: Swap ordering of memory types on non-LLC platforms to work around application...
authorFrancisco Jerez <currojerez@riseup.net>
Tue, 13 Jun 2023 00:53:35 +0000 (20:53 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 27 Jun 2023 22:06:19 +0000 (22:06 +0000)
The Vulkan specification indicates that if memory types have
properties which are a strict subset of another type's, then they
should appear before that memory type.  Otherwise the specification
does not require a specific ordering of memory types.

But, it appears that Aztec Ruins and the Vulkan CTS make an assumption
that the first host-accessible memory type is host-coherent and select
it when they expect data written by the CPU to become visible without
calling vkFlushMappedMemoryRanges(), even though flushing is required
by the spec, which leads to misrendering and hangs on MTL platforms.

We found that other drivers also put a host-coherent, but not cached
memory type as the first host-accessible memory type, so let's do the
same in order to match the expectations of such broken applications.

Host-coherent uncached memory types are currently implemented with a
WC CPU map on non-LLC platforms, so there shouldn't be a huge
performance penalty from this: If an application intends to do heavy
R/W CPU access on a memory range it's expected to loop over the
available memory types and select one marked as host-cached -- If an
application fails to do that and simply selects the first available
type it seems more robust to stay on the safe side and give them a
host-coherent type rather than a cached one.

Rework:
 * Jordan: Add initial explanation to body of commmit message.
 * Curro: Add additional comments to commit message.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22878>

src/intel/vulkan/i915/anv_device.c

index fbaec65..d666455 100644 (file)
@@ -190,13 +190,13 @@ anv_i915_physical_device_init_memory_types(struct anv_physical_device *device)
       device->memory.types[0] = (struct anv_memory_type) {
          .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                           VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
-                          VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+                          VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
          .heapIndex = 0,
       };
       device->memory.types[1] = (struct anv_memory_type) {
          .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                           VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
-                          VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+                          VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
          .heapIndex = 0,
       };
    }