anv: Add valid_bufer_usage to the memory type metadata
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 17 May 2017 18:14:06 +0000 (11:14 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 23 May 2017 23:46:34 +0000 (16:46 -0700)
Instead of returning valid types as just a number, we now walk the list
and check the buffer's usage against the usage flags we store in the new
anv_memory_type structure.  Currently, valid_buffer_usage == ~0.

Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Cc: "17.1" <mesa-stable@lists.freedesktop.org>
src/intel/vulkan/anv_device.c
src/intel/vulkan/anv_private.h

index 4a0115ecf52ab5d839522c69e24dc610fdda1d40..8bf52ccd0e46d0fa6d0fb49116642293d390af0d 100644 (file)
@@ -117,12 +117,13 @@ anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)
        * both cached and coherent at the same time.
        */
       device->memory.type_count = 1;
-      device->memory.types[0] = (VkMemoryType) {
+      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_COHERENT_BIT |
                           VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
          .heapIndex = 0,
+         .valid_buffer_usage = ~0,
       };
    } else {
       /* The spec requires that we expose a host-visible, coherent memory
@@ -131,17 +132,19 @@ anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)
        * coherent but uncached (WC though).
        */
       device->memory.type_count = 2;
-      device->memory.types[0] = (VkMemoryType) {
+      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_COHERENT_BIT,
          .heapIndex = 0,
+         .valid_buffer_usage = ~0,
       };
-      device->memory.types[1] = (VkMemoryType) {
+      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_CACHED_BIT,
          .heapIndex = 0,
+         .valid_buffer_usage = ~0,
       };
    }
 
@@ -1727,6 +1730,7 @@ void anv_GetBufferMemoryRequirements(
 {
    ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
    ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_physical_device *pdevice = &device->instance->physicalDevice;
 
    /* The Vulkan spec (git aaed022) says:
     *
@@ -1734,13 +1738,17 @@ void anv_GetBufferMemoryRequirements(
     *    supported memory type for the resource. The bit `1<<i` is set if and
     *    only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
     *    structure for the physical device is supported.
-    *
-    * We support exactly one memory type on LLC, two on non-LLC.
     */
-   pMemoryRequirements->memoryTypeBits = device->info.has_llc ? 1 : 3;
+   uint32_t memory_types = 0;
+   for (uint32_t i = 0; i < pdevice->memory.type_count; i++) {
+      uint32_t valid_usage = pdevice->memory.types[i].valid_buffer_usage;
+      if ((valid_usage & buffer->usage) == buffer->usage)
+         memory_types |= (1u << i);
+   }
 
    pMemoryRequirements->size = buffer->size;
    pMemoryRequirements->alignment = 16;
+   pMemoryRequirements->memoryTypeBits = memory_types;
 }
 
 void anv_GetImageMemoryRequirements(
@@ -1793,6 +1801,7 @@ VkResult anv_BindBufferMemory(
    ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
 
    if (mem) {
+      assert((buffer->usage & mem->type->valid_buffer_usage) == buffer->usage);
       buffer->bo = mem->bo;
       buffer->offset = memoryOffset;
    } else {
index 90fee8fc26f26339dac1cfb505107f08940a1298..7efcda3bc6cf2d39f3233ccffba5f280746df7ac 100644 (file)
@@ -640,6 +640,15 @@ void anv_bo_cache_release(struct anv_device *device,
                           struct anv_bo_cache *cache,
                           struct anv_bo *bo);
 
+struct anv_memory_type {
+   /* Standard bits passed on to the client */
+   VkMemoryPropertyFlags   propertyFlags;
+   uint32_t                heapIndex;
+
+   /* Driver-internal book-keeping */
+   VkBufferUsageFlags      valid_buffer_usage;
+};
+
 struct anv_physical_device {
     VK_LOADER_DATA                              _loader_data;
 
@@ -667,7 +676,7 @@ struct anv_physical_device {
 
     struct {
       uint32_t                                  type_count;
-      VkMemoryType                              types[VK_MAX_MEMORY_TYPES];
+      struct anv_memory_type                    types[VK_MAX_MEMORY_TYPES];
       uint32_t                                  heap_count;
       VkMemoryHeap                              heaps[VK_MAX_MEMORY_HEAPS];
     } memory;
@@ -1002,7 +1011,7 @@ _anv_combine_address(struct anv_batch *batch, void *location,
 
 struct anv_device_memory {
    struct anv_bo *                              bo;
-   VkMemoryType *                               type;
+   struct anv_memory_type *                     type;
    VkDeviceSize                                 map_size;
    void *                                       map;
 };