turnip: Require DRM device version >= 1.3
[mesa.git] / src / freedreno / vulkan / tu_device.c
index e0c27166818ac709f4bf5747850ab691bf573e1a..f32868e9c812f42ebcbba1cbca0d64658db524a7 100644 (file)
@@ -34,6 +34,7 @@
 #include <fcntl.h>
 #include <stdbool.h>
 #include <string.h>
+#include <sys/sysinfo.h>
 #include <unistd.h>
 #include <xf86drm.h>
 
@@ -67,11 +68,11 @@ tu_get_device_uuid(void *uuid)
 
 static VkResult
 tu_physical_device_init(struct tu_physical_device *device,
-                         struct tu_instance *instance,
-                         drmDevicePtr drm_device)
+                        struct tu_instance *instance,
+                        drmDevicePtr drm_device)
 {
    const char *path = drm_device->nodes[DRM_NODE_RENDER];
-   VkResult result;
+   VkResult result = VK_SUCCESS;
    drmVersionPtr version;
    int fd;
    int master_fd = -1;
@@ -86,6 +87,10 @@ tu_physical_device_init(struct tu_physical_device *device,
       return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
    }
 
+   /* Version 1.3 added MSM_INFO_IOVA. */
+   const int min_version_major = 1;
+   const int min_version_minor = 3;
+
    version = drmGetVersion(fd);
    if (!version) {
       close(fd);
@@ -111,6 +116,19 @@ tu_physical_device_init(struct tu_physical_device *device,
 
       return VK_ERROR_INCOMPATIBLE_DRIVER;
    }
+
+   if (version->version_major != 1 || version->version_minor < 3) {
+      result = vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
+                         "kernel driver for device %s has version %d.%d, "
+                         "but Vulkan requires version >= %d.%d",
+                         path,
+                         version->version_major, version->version_minor,
+                         min_version_major, min_version_minor);
+      drmFreeVersion(version);
+      close(fd);
+      return result;
+   }
+
    drmFreeVersion(version);
 
    if (instance->debug_flags & TU_DEBUG_STARTUP)
@@ -279,8 +297,8 @@ tu_get_instance_extension_index(const char *name)
 
 VkResult
 tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
-                   const VkAllocationCallbacks *pAllocator,
-                   VkInstance *pInstance)
+                  const VkAllocationCallbacks *pAllocator,
+                  VkInstance *pInstance)
 {
    struct tu_instance *instance;
    VkResult result;
@@ -348,7 +366,7 @@ tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
 
 void
 tu_DestroyInstance(VkInstance _instance,
-                    const VkAllocationCallbacks *pAllocator)
+                   const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_instance, instance, _instance);
 
@@ -392,8 +410,8 @@ tu_enumerate_devices(struct tu_instance *instance)
 
          result = tu_physical_device_init(instance->physical_devices +
                                              instance->physical_device_count,
-                                           instance,
-                                           devices[i]);
+                                          instance,
+                                          devices[i]);
          if (result == VK_SUCCESS)
             ++instance->physical_device_count;
          else if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
@@ -407,10 +425,12 @@ tu_enumerate_devices(struct tu_instance *instance)
 
 VkResult
 tu_EnumeratePhysicalDevices(VkInstance _instance,
-                             uint32_t *pPhysicalDeviceCount,
-                             VkPhysicalDevice *pPhysicalDevices)
+                            uint32_t *pPhysicalDeviceCount,
+                            VkPhysicalDevice *pPhysicalDevices)
 {
    TU_FROM_HANDLE(tu_instance, instance, _instance);
+   VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
+
    VkResult result;
 
    if (instance->physical_device_count < 0) {
@@ -419,28 +439,24 @@ tu_EnumeratePhysicalDevices(VkInstance _instance,
          return result;
    }
 
-   if (!pPhysicalDevices) {
-      *pPhysicalDeviceCount = instance->physical_device_count;
-   } else {
-      *pPhysicalDeviceCount =
-        MIN2(*pPhysicalDeviceCount, instance->physical_device_count);
-      for (unsigned i = 0; i < *pPhysicalDeviceCount; ++i)
-         pPhysicalDevices[i] =
-           tu_physical_device_to_handle(instance->physical_devices + i);
+   for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
+      vk_outarray_append(&out, p) {
+         *p = tu_physical_device_to_handle(instance->physical_devices + i);
+      }
+
    }
 
-   return *pPhysicalDeviceCount < instance->physical_device_count
-            ? VK_INCOMPLETE
-            : VK_SUCCESS;
+   return vk_outarray_status(&out);
 }
 
 VkResult
 tu_EnumeratePhysicalDeviceGroups(
-  VkInstance _instance,
-  uint32_t *pPhysicalDeviceGroupCount,
-  VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
+   VkInstance _instance,
+   uint32_t *pPhysicalDeviceGroupCount,
+   VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
 {
    TU_FROM_HANDLE(tu_instance, instance, _instance);
+   VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties, pPhysicalDeviceGroupCount);
    VkResult result;
 
    if (instance->physical_device_count < 0) {
@@ -449,26 +465,21 @@ tu_EnumeratePhysicalDeviceGroups(
          return result;
    }
 
-   if (!pPhysicalDeviceGroupProperties) {
-      *pPhysicalDeviceGroupCount = instance->physical_device_count;
-   } else {
-      *pPhysicalDeviceGroupCount =
-        MIN2(*pPhysicalDeviceGroupCount, instance->physical_device_count);
-      for (unsigned i = 0; i < *pPhysicalDeviceGroupCount; ++i) {
-         pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
-         pPhysicalDeviceGroupProperties[i].physicalDevices[0] =
+   for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
+      vk_outarray_append(&out, p) {
+         p->physicalDeviceCount = 1;
+         p->physicalDevices[0] =
            tu_physical_device_to_handle(instance->physical_devices + i);
-         pPhysicalDeviceGroupProperties[i].subsetAllocation = false;
+         p->subsetAllocation = false;
       }
    }
-   return *pPhysicalDeviceGroupCount < instance->physical_device_count
-            ? VK_INCOMPLETE
-            : VK_SUCCESS;
+
+   return vk_outarray_status(&out);
 }
 
 void
 tu_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
-                              VkPhysicalDeviceFeatures *pFeatures)
+                             VkPhysicalDeviceFeatures *pFeatures)
 {
    memset(pFeatures, 0, sizeof(*pFeatures));
 
@@ -523,29 +534,29 @@ tu_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
 
 void
 tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
-                               VkPhysicalDeviceFeatures2KHR *pFeatures)
+                              VkPhysicalDeviceFeatures2KHR *pFeatures)
 {
    vk_foreach_struct(ext, pFeatures->pNext)
    {
       switch (ext->sType) {
          case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR: {
             VkPhysicalDeviceVariablePointerFeaturesKHR *features = (void *)ext;
-            features->variablePointersStorageBuffer = true;
+            features->variablePointersStorageBuffer = false;
             features->variablePointers = false;
             break;
          }
          case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR: {
             VkPhysicalDeviceMultiviewFeaturesKHR *features =
               (VkPhysicalDeviceMultiviewFeaturesKHR *)ext;
-            features->multiview = true;
-            features->multiviewGeometryShader = true;
-            features->multiviewTessellationShader = true;
+            features->multiview = false;
+            features->multiviewGeometryShader = false;
+            features->multiviewTessellationShader = false;
             break;
          }
          case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES: {
             VkPhysicalDeviceShaderDrawParameterFeatures *features =
               (VkPhysicalDeviceShaderDrawParameterFeatures *)ext;
-            features->shaderDrawParameters = true;
+            features->shaderDrawParameters = false;
             break;
          }
          case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
@@ -572,9 +583,9 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
          case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
             VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features =
               (VkPhysicalDeviceDescriptorIndexingFeaturesEXT *)ext;
-            features->shaderInputAttachmentArrayDynamicIndexing = true;
-            features->shaderUniformTexelBufferArrayDynamicIndexing = true;
-            features->shaderStorageTexelBufferArrayDynamicIndexing = true;
+            features->shaderInputAttachmentArrayDynamicIndexing = false;
+            features->shaderUniformTexelBufferArrayDynamicIndexing = false;
+            features->shaderStorageTexelBufferArrayDynamicIndexing = false;
             features->shaderUniformBufferArrayNonUniformIndexing = false;
             features->shaderSampledImageArrayNonUniformIndexing = false;
             features->shaderStorageBufferArrayNonUniformIndexing = false;
@@ -582,22 +593,22 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
             features->shaderInputAttachmentArrayNonUniformIndexing = false;
             features->shaderUniformTexelBufferArrayNonUniformIndexing = false;
             features->shaderStorageTexelBufferArrayNonUniformIndexing = false;
-            features->descriptorBindingUniformBufferUpdateAfterBind = true;
-            features->descriptorBindingSampledImageUpdateAfterBind = true;
-            features->descriptorBindingStorageImageUpdateAfterBind = true;
-            features->descriptorBindingStorageBufferUpdateAfterBind = true;
-            features->descriptorBindingUniformTexelBufferUpdateAfterBind = true;
-            features->descriptorBindingStorageTexelBufferUpdateAfterBind = true;
-            features->descriptorBindingUpdateUnusedWhilePending = true;
-            features->descriptorBindingPartiallyBound = true;
-            features->descriptorBindingVariableDescriptorCount = true;
-            features->runtimeDescriptorArray = true;
+            features->descriptorBindingUniformBufferUpdateAfterBind = false;
+            features->descriptorBindingSampledImageUpdateAfterBind = false;
+            features->descriptorBindingStorageImageUpdateAfterBind = false;
+            features->descriptorBindingStorageBufferUpdateAfterBind = false;
+            features->descriptorBindingUniformTexelBufferUpdateAfterBind = false;
+            features->descriptorBindingStorageTexelBufferUpdateAfterBind = false;
+            features->descriptorBindingUpdateUnusedWhilePending = false;
+            features->descriptorBindingPartiallyBound = false;
+            features->descriptorBindingVariableDescriptorCount = false;
+            features->runtimeDescriptorArray = false;
             break;
          }
          case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
             VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
               (VkPhysicalDeviceConditionalRenderingFeaturesEXT *)ext;
-            features->conditionalRendering = true;
+            features->conditionalRendering = false;
             features->inheritedConditionalRendering = false;
             break;
          }
@@ -610,7 +621,7 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
 
 void
 tu_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
-                                VkPhysicalDeviceProperties *pProperties)
+                               VkPhysicalDeviceProperties *pProperties)
 {
    TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
    VkSampleCountFlags sample_counts = 0xf;
@@ -753,7 +764,7 @@ tu_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
 
 void
 tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
-                                 VkPhysicalDeviceProperties2KHR *pProperties)
+                                VkPhysicalDeviceProperties2KHR *pProperties)
 {
    TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
    tu_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
@@ -805,87 +816,82 @@ tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
    }
 }
 
-static void
-tu_get_physical_device_queue_family_properties(
-  struct tu_physical_device *pdevice,
-  uint32_t *pCount,
-  VkQueueFamilyProperties **pQueueFamilyProperties)
-{
-   int num_queue_families = 1;
-   int idx;
-   if (pQueueFamilyProperties == NULL) {
-      *pCount = num_queue_families;
-      return;
-   }
-
-   if (!*pCount)
-      return;
-
-   idx = 0;
-   if (*pCount >= 1) {
-      *pQueueFamilyProperties[idx] = (VkQueueFamilyProperties){
-         .queueFlags =
-           VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT,
-         .queueCount = 1,
-         .timestampValidBits = 64,
-         .minImageTransferGranularity = (VkExtent3D){ 1, 1, 1 },
-      };
-      idx++;
-   }
-
-   *pCount = idx;
-}
+static const VkQueueFamilyProperties
+tu_queue_family_properties = {
+   .queueFlags = VK_QUEUE_GRAPHICS_BIT |
+                 VK_QUEUE_COMPUTE_BIT |
+                 VK_QUEUE_TRANSFER_BIT,
+   .queueCount = 1,
+   .timestampValidBits = 64,
+   .minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
+};
 
 void
 tu_GetPhysicalDeviceQueueFamilyProperties(
-  VkPhysicalDevice physicalDevice,
-  uint32_t *pCount,
-  VkQueueFamilyProperties *pQueueFamilyProperties)
+   VkPhysicalDevice physicalDevice,
+   uint32_t *pQueueFamilyPropertyCount,
+   VkQueueFamilyProperties *pQueueFamilyProperties)
 {
-   TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
-   if (!pQueueFamilyProperties) {
-      return tu_get_physical_device_queue_family_properties(
-        pdevice, pCount, NULL);
-      return;
+   VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
+
+   vk_outarray_append(&out, p) {
+      *p = tu_queue_family_properties;
    }
-   VkQueueFamilyProperties *properties[] = {
-      pQueueFamilyProperties + 0,
-   };
-   tu_get_physical_device_queue_family_properties(pdevice, pCount, properties);
-   assert(*pCount <= 1);
 }
 
 void
 tu_GetPhysicalDeviceQueueFamilyProperties2(
-  VkPhysicalDevice physicalDevice,
-  uint32_t *pCount,
-  VkQueueFamilyProperties2KHR *pQueueFamilyProperties)
+   VkPhysicalDevice physicalDevice,
+   uint32_t *pQueueFamilyPropertyCount,
+   VkQueueFamilyProperties2KHR *pQueueFamilyProperties)
 {
-   TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
-   if (!pQueueFamilyProperties) {
-      return tu_get_physical_device_queue_family_properties(
-        pdevice, pCount, NULL);
-      return;
+   VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
+
+   vk_outarray_append(&out, p) {
+      p->queueFamilyProperties = tu_queue_family_properties;
    }
-   VkQueueFamilyProperties *properties[] = {
-      &pQueueFamilyProperties[0].queueFamilyProperties,
-   };
-   tu_get_physical_device_queue_family_properties(pdevice, pCount, properties);
-   assert(*pCount <= 1);
+}
+
+static uint64_t
+tu_get_system_heap_size()
+{
+   struct sysinfo info;
+   sysinfo(&info);
+
+   uint64_t total_ram = (uint64_t)info.totalram * (uint64_t)info.mem_unit;
+
+   /* We don't want to burn too much ram with the GPU.  If the user has 4GiB
+    * or less, we use at most half.  If they have more than 4GiB, we use 3/4.
+    */
+   uint64_t available_ram;
+   if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
+      available_ram = total_ram / 2;
+   else
+      available_ram = total_ram * 3 / 4;
+
+   return available_ram;
 }
 
 void
 tu_GetPhysicalDeviceMemoryProperties(
-  VkPhysicalDevice physicalDevice,
-  VkPhysicalDeviceMemoryProperties *pMemoryProperties)
+   VkPhysicalDevice physicalDevice,
+   VkPhysicalDeviceMemoryProperties *pMemoryProperties)
 {
-   stub();
+   pMemoryProperties->memoryHeapCount = 1;
+   pMemoryProperties->memoryHeaps[0].size = tu_get_system_heap_size();
+   pMemoryProperties->memoryHeaps[0].flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
+
+   pMemoryProperties->memoryTypeCount = 1;
+   pMemoryProperties->memoryTypes[0].propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
+                                                     VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+                                                     VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+   pMemoryProperties->memoryTypes[0].heapIndex = 0;
 }
 
 void
 tu_GetPhysicalDeviceMemoryProperties2(
-  VkPhysicalDevice physicalDevice,
-  VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties)
+   VkPhysicalDevice physicalDevice,
+   VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties)
 {
    return tu_GetPhysicalDeviceMemoryProperties(
      physicalDevice, &pMemoryProperties->memoryProperties);
@@ -893,10 +899,10 @@ tu_GetPhysicalDeviceMemoryProperties2(
 
 static int
 tu_queue_init(struct tu_device *device,
-               struct tu_queue *queue,
-               uint32_t queue_family_index,
-               int idx,
-               VkDeviceQueueCreateFlags flags)
+              struct tu_queue *queue,
+              uint32_t queue_family_index,
+              int idx,
+              VkDeviceQueueCreateFlags flags)
 {
    queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
    queue->device = device;
@@ -924,9 +930,9 @@ tu_get_device_extension_index(const char *name)
 
 VkResult
 tu_CreateDevice(VkPhysicalDevice physicalDevice,
-                 const VkDeviceCreateInfo *pCreateInfo,
-                 const VkAllocationCallbacks *pAllocator,
-                 VkDevice *pDevice)
+                const VkDeviceCreateInfo *pCreateInfo,
+                const VkAllocationCallbacks *pAllocator,
+                VkDevice *pDevice)
 {
    TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
    VkResult result;
@@ -1057,35 +1063,25 @@ tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
 
 VkResult
 tu_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
-                                     VkLayerProperties *pProperties)
+                                    VkLayerProperties *pProperties)
 {
-   if (pProperties == NULL) {
-      *pPropertyCount = 0;
-      return VK_SUCCESS;
-   }
-
-   /* None supported at this time */
-   return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
+   *pPropertyCount = 0;
+   return VK_SUCCESS;
 }
 
 VkResult
 tu_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
-                                   uint32_t *pPropertyCount,
-                                   VkLayerProperties *pProperties)
+                                  uint32_t *pPropertyCount,
+                                  VkLayerProperties *pProperties)
 {
-   if (pProperties == NULL) {
-      *pPropertyCount = 0;
-      return VK_SUCCESS;
-   }
-
-   /* None supported at this time */
-   return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
+   *pPropertyCount = 0;
+   return VK_SUCCESS;
 }
 
 void
 tu_GetDeviceQueue2(VkDevice _device,
-                    const VkDeviceQueueInfo2 *pQueueInfo,
-                    VkQueue *pQueue)
+                   const VkDeviceQueueInfo2 *pQueueInfo,
+                   VkQueue *pQueue)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    struct tu_queue *queue;
@@ -1110,9 +1106,9 @@ tu_GetDeviceQueue2(VkDevice _device,
 
 void
 tu_GetDeviceQueue(VkDevice _device,
-                   uint32_t queueFamilyIndex,
-                   uint32_t queueIndex,
-                   VkQueue *pQueue)
+                  uint32_t queueFamilyIndex,
+                  uint32_t queueIndex,
+                  VkQueue *pQueue)
 {
    const VkDeviceQueueInfo2 info =
      (VkDeviceQueueInfo2){.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
@@ -1124,9 +1120,9 @@ tu_GetDeviceQueue(VkDevice _device,
 
 VkResult
 tu_QueueSubmit(VkQueue _queue,
-                uint32_t submitCount,
-                const VkSubmitInfo *pSubmits,
-                VkFence _fence)
+               uint32_t submitCount,
+               const VkSubmitInfo *pSubmits,
+               VkFence _fence)
 {
    return VK_SUCCESS;
 }
@@ -1152,11 +1148,15 @@ tu_DeviceWaitIdle(VkDevice _device)
 
 VkResult
 tu_EnumerateInstanceExtensionProperties(const char *pLayerName,
-                                         uint32_t *pPropertyCount,
-                                         VkExtensionProperties *pProperties)
+                                        uint32_t *pPropertyCount,
+                                        VkExtensionProperties *pProperties)
 {
    VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
 
+   /* We spport no lyaers */
+   if (pLayerName)
+      return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
+
    for (int i = 0; i < TU_INSTANCE_EXTENSION_COUNT; i++) {
       if (tu_supported_instance_extensions.extensions[i]) {
          vk_outarray_append(&out, prop) { *prop = tu_instance_extensions[i]; }
@@ -1168,13 +1168,18 @@ tu_EnumerateInstanceExtensionProperties(const char *pLayerName,
 
 VkResult
 tu_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
-                                       const char *pLayerName,
-                                       uint32_t *pPropertyCount,
-                                       VkExtensionProperties *pProperties)
+                                      const char *pLayerName,
+                                      uint32_t *pPropertyCount,
+                                      VkExtensionProperties *pProperties)
 {
+   /* We spport no lyaers */
    TU_FROM_HANDLE(tu_physical_device, device, physicalDevice);
    VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
 
+   /* We spport no lyaers */
+   if (pLayerName)
+      return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
+
    for (int i = 0; i < TU_DEVICE_EXTENSION_COUNT; i++) {
       if (device->supported_extensions.extensions[i]) {
          vk_outarray_append(&out, prop) { *prop = tu_device_extensions[i]; }
@@ -1223,9 +1228,9 @@ tu_GetDeviceProcAddr(VkDevice _device, const char *pName)
 
 static VkResult
 tu_alloc_memory(struct tu_device *device,
-                 const VkMemoryAllocateInfo *pAllocateInfo,
-                 const VkAllocationCallbacks *pAllocator,
-                 VkDeviceMemory *pMem)
+                const VkMemoryAllocateInfo *pAllocateInfo,
+                const VkAllocationCallbacks *pAllocator,
+                VkDeviceMemory *pMem)
 {
    struct tu_device_memory *mem;
 
@@ -1265,9 +1270,9 @@ tu_alloc_memory(struct tu_device *device,
 
 VkResult
 tu_AllocateMemory(VkDevice _device,
-                   const VkMemoryAllocateInfo *pAllocateInfo,
-                   const VkAllocationCallbacks *pAllocator,
-                   VkDeviceMemory *pMem)
+                  const VkMemoryAllocateInfo *pAllocateInfo,
+                  const VkAllocationCallbacks *pAllocator,
+                  VkDeviceMemory *pMem)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    return tu_alloc_memory(device, pAllocateInfo, pAllocator, pMem);
@@ -1275,8 +1280,8 @@ tu_AllocateMemory(VkDevice _device,
 
 void
 tu_FreeMemory(VkDevice _device,
-               VkDeviceMemory _mem,
-               const VkAllocationCallbacks *pAllocator)
+              VkDeviceMemory _mem,
+              const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_device_memory, mem, _mem);
@@ -1292,11 +1297,11 @@ tu_FreeMemory(VkDevice _device,
 
 VkResult
 tu_MapMemory(VkDevice _device,
-              VkDeviceMemory _memory,
-              VkDeviceSize offset,
-              VkDeviceSize size,
-              VkMemoryMapFlags flags,
-              void **ppData)
+             VkDeviceMemory _memory,
+             VkDeviceSize offset,
+             VkDeviceSize size,
+             VkMemoryMapFlags flags,
+             void **ppData)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_device_memory, mem, _memory);
@@ -1329,27 +1334,28 @@ tu_UnmapMemory(VkDevice _device, VkDeviceMemory _memory)
 
 VkResult
 tu_FlushMappedMemoryRanges(VkDevice _device,
-                            uint32_t memoryRangeCount,
-                            const VkMappedMemoryRange *pMemoryRanges)
+                           uint32_t memoryRangeCount,
+                           const VkMappedMemoryRange *pMemoryRanges)
 {
    return VK_SUCCESS;
 }
 
 VkResult
 tu_InvalidateMappedMemoryRanges(VkDevice _device,
-                                 uint32_t memoryRangeCount,
-                                 const VkMappedMemoryRange *pMemoryRanges)
+                                uint32_t memoryRangeCount,
+                                const VkMappedMemoryRange *pMemoryRanges)
 {
    return VK_SUCCESS;
 }
 
 void
 tu_GetBufferMemoryRequirements(VkDevice _device,
-                                VkBuffer _buffer,
-                                VkMemoryRequirements *pMemoryRequirements)
+                               VkBuffer _buffer,
+                               VkMemoryRequirements *pMemoryRequirements)
 {
    TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
 
+   pMemoryRequirements->memoryTypeBits = 1;
    pMemoryRequirements->alignment = 16;
    pMemoryRequirements->size =
      align64(buffer->size, pMemoryRequirements->alignment);
@@ -1357,9 +1363,9 @@ tu_GetBufferMemoryRequirements(VkDevice _device,
 
 void
 tu_GetBufferMemoryRequirements2(
-  VkDevice device,
-  const VkBufferMemoryRequirementsInfo2KHR *pInfo,
-  VkMemoryRequirements2KHR *pMemoryRequirements)
+   VkDevice device,
+   const VkBufferMemoryRequirementsInfo2KHR *pInfo,
+   VkMemoryRequirements2KHR *pMemoryRequirements)
 {
    tu_GetBufferMemoryRequirements(
      device, pInfo->buffer, &pMemoryRequirements->memoryRequirements);
@@ -1367,21 +1373,20 @@ tu_GetBufferMemoryRequirements2(
 
 void
 tu_GetImageMemoryRequirements(VkDevice _device,
-                               VkImage _image,
-                               VkMemoryRequirements *pMemoryRequirements)
+                              VkImage _image,
+                              VkMemoryRequirements *pMemoryRequirements)
 {
    TU_FROM_HANDLE(tu_image, image, _image);
 
-   /* TODO: memory type */
-
+   pMemoryRequirements->memoryTypeBits = 1;
    pMemoryRequirements->size = image->size;
    pMemoryRequirements->alignment = image->alignment;
 }
 
 void
 tu_GetImageMemoryRequirements2(VkDevice device,
-                                const VkImageMemoryRequirementsInfo2KHR *pInfo,
-                                VkMemoryRequirements2KHR *pMemoryRequirements)
+                               const VkImageMemoryRequirementsInfo2KHR *pInfo,
+                               VkMemoryRequirements2KHR *pMemoryRequirements)
 {
    tu_GetImageMemoryRequirements(
      device, pInfo->image, &pMemoryRequirements->memoryRequirements);
@@ -1389,45 +1394,45 @@ tu_GetImageMemoryRequirements2(VkDevice device,
 
 void
 tu_GetImageSparseMemoryRequirements(
-  VkDevice device,
-  VkImage image,
-  uint32_t *pSparseMemoryRequirementCount,
-  VkSparseImageMemoryRequirements *pSparseMemoryRequirements)
+   VkDevice device,
+   VkImage image,
+   uint32_t *pSparseMemoryRequirementCount,
+   VkSparseImageMemoryRequirements *pSparseMemoryRequirements)
 {
    stub();
 }
 
 void
 tu_GetImageSparseMemoryRequirements2(
-  VkDevice device,
-  const VkImageSparseMemoryRequirementsInfo2KHR *pInfo,
-  uint32_t *pSparseMemoryRequirementCount,
-  VkSparseImageMemoryRequirements2KHR *pSparseMemoryRequirements)
+   VkDevice device,
+   const VkImageSparseMemoryRequirementsInfo2KHR *pInfo,
+   uint32_t *pSparseMemoryRequirementCount,
+   VkSparseImageMemoryRequirements2KHR *pSparseMemoryRequirements)
 {
    stub();
 }
 
 void
 tu_GetDeviceMemoryCommitment(VkDevice device,
-                              VkDeviceMemory memory,
-                              VkDeviceSize *pCommittedMemoryInBytes)
+                             VkDeviceMemory memory,
+                             VkDeviceSize *pCommittedMemoryInBytes)
 {
    *pCommittedMemoryInBytes = 0;
 }
 
 VkResult
 tu_BindBufferMemory2(VkDevice device,
-                      uint32_t bindInfoCount,
-                      const VkBindBufferMemoryInfoKHR *pBindInfos)
+                     uint32_t bindInfoCount,
+                     const VkBindBufferMemoryInfoKHR *pBindInfos)
 {
    return VK_SUCCESS;
 }
 
 VkResult
 tu_BindBufferMemory(VkDevice device,
-                     VkBuffer buffer,
-                     VkDeviceMemory memory,
-                     VkDeviceSize memoryOffset)
+                    VkBuffer buffer,
+                    VkDeviceMemory memory,
+                    VkDeviceSize memoryOffset)
 {
    const VkBindBufferMemoryInfoKHR info = {
       .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR,
@@ -1441,17 +1446,17 @@ tu_BindBufferMemory(VkDevice device,
 
 VkResult
 tu_BindImageMemory2(VkDevice device,
-                     uint32_t bindInfoCount,
-                     const VkBindImageMemoryInfoKHR *pBindInfos)
+                    uint32_t bindInfoCount,
+                    const VkBindImageMemoryInfoKHR *pBindInfos)
 {
    return VK_SUCCESS;
 }
 
 VkResult
 tu_BindImageMemory(VkDevice device,
-                    VkImage image,
-                    VkDeviceMemory memory,
-                    VkDeviceSize memoryOffset)
+                   VkImage image,
+                   VkDeviceMemory memory,
+                   VkDeviceSize memoryOffset)
 {
    const VkBindImageMemoryInfoKHR info = {
       .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR,
@@ -1465,18 +1470,18 @@ tu_BindImageMemory(VkDevice device,
 
 VkResult
 tu_QueueBindSparse(VkQueue _queue,
-                    uint32_t bindInfoCount,
-                    const VkBindSparseInfo *pBindInfo,
-                    VkFence _fence)
+                   uint32_t bindInfoCount,
+                   const VkBindSparseInfo *pBindInfo,
+                   VkFence _fence)
 {
    return VK_SUCCESS;
 }
 
 VkResult
 tu_CreateFence(VkDevice _device,
-                const VkFenceCreateInfo *pCreateInfo,
-                const VkAllocationCallbacks *pAllocator,
-                VkFence *pFence)
+               const VkFenceCreateInfo *pCreateInfo,
+               const VkAllocationCallbacks *pAllocator,
+               VkFence *pFence)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
 
@@ -1496,8 +1501,8 @@ tu_CreateFence(VkDevice _device,
 
 void
 tu_DestroyFence(VkDevice _device,
-                 VkFence _fence,
-                 const VkAllocationCallbacks *pAllocator)
+                VkFence _fence,
+                const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_fence, fence, _fence);
@@ -1510,10 +1515,10 @@ tu_DestroyFence(VkDevice _device,
 
 VkResult
 tu_WaitForFences(VkDevice _device,
-                  uint32_t fenceCount,
-                  const VkFence *pFences,
-                  VkBool32 waitAll,
-                  uint64_t timeout)
+                 uint32_t fenceCount,
+                 const VkFence *pFences,
+                 VkBool32 waitAll,
+                 uint64_t timeout)
 {
    return VK_SUCCESS;
 }
@@ -1534,9 +1539,9 @@ tu_GetFenceStatus(VkDevice _device, VkFence _fence)
 
 VkResult
 tu_CreateSemaphore(VkDevice _device,
-                    const VkSemaphoreCreateInfo *pCreateInfo,
-                    const VkAllocationCallbacks *pAllocator,
-                    VkSemaphore *pSemaphore)
+                   const VkSemaphoreCreateInfo *pCreateInfo,
+                   const VkAllocationCallbacks *pAllocator,
+                   VkSemaphore *pSemaphore)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
 
@@ -1554,8 +1559,8 @@ tu_CreateSemaphore(VkDevice _device,
 
 void
 tu_DestroySemaphore(VkDevice _device,
-                     VkSemaphore _semaphore,
-                     const VkAllocationCallbacks *pAllocator)
+                    VkSemaphore _semaphore,
+                    const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_semaphore, sem, _semaphore);
@@ -1567,9 +1572,9 @@ tu_DestroySemaphore(VkDevice _device,
 
 VkResult
 tu_CreateEvent(VkDevice _device,
-                const VkEventCreateInfo *pCreateInfo,
-                const VkAllocationCallbacks *pAllocator,
-                VkEvent *pEvent)
+               const VkEventCreateInfo *pCreateInfo,
+               const VkAllocationCallbacks *pAllocator,
+               VkEvent *pEvent)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    struct tu_event *event = vk_alloc2(&device->alloc,
@@ -1588,8 +1593,8 @@ tu_CreateEvent(VkDevice _device,
 
 void
 tu_DestroyEvent(VkDevice _device,
-                 VkEvent _event,
-                 const VkAllocationCallbacks *pAllocator)
+                VkEvent _event,
+                const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_event, event, _event);
@@ -1629,9 +1634,9 @@ tu_ResetEvent(VkDevice _device, VkEvent _event)
 
 VkResult
 tu_CreateBuffer(VkDevice _device,
-                 const VkBufferCreateInfo *pCreateInfo,
-                 const VkAllocationCallbacks *pAllocator,
-                 VkBuffer *pBuffer)
+                const VkBufferCreateInfo *pCreateInfo,
+                const VkAllocationCallbacks *pAllocator,
+                VkBuffer *pBuffer)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    struct tu_buffer *buffer;
@@ -1657,8 +1662,8 @@ tu_CreateBuffer(VkDevice _device,
 
 void
 tu_DestroyBuffer(VkDevice _device,
-                  VkBuffer _buffer,
-                  const VkAllocationCallbacks *pAllocator)
+                 VkBuffer _buffer,
+                 const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
@@ -1679,9 +1684,9 @@ tu_surface_max_layer_count(struct tu_image_view *iview)
 
 VkResult
 tu_CreateFramebuffer(VkDevice _device,
-                      const VkFramebufferCreateInfo *pCreateInfo,
-                      const VkAllocationCallbacks *pAllocator,
-                      VkFramebuffer *pFramebuffer)
+                     const VkFramebufferCreateInfo *pCreateInfo,
+                     const VkAllocationCallbacks *pAllocator,
+                     VkFramebuffer *pFramebuffer)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    struct tu_framebuffer *framebuffer;
@@ -1717,8 +1722,8 @@ tu_CreateFramebuffer(VkDevice _device,
 
 void
 tu_DestroyFramebuffer(VkDevice _device,
-                       VkFramebuffer _fb,
-                       const VkAllocationCallbacks *pAllocator)
+                      VkFramebuffer _fb,
+                      const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_framebuffer, fb, _fb);
@@ -1730,16 +1735,16 @@ tu_DestroyFramebuffer(VkDevice _device,
 
 static void
 tu_init_sampler(struct tu_device *device,
-                 struct tu_sampler *sampler,
-                 const VkSamplerCreateInfo *pCreateInfo)
+                struct tu_sampler *sampler,
+                const VkSamplerCreateInfo *pCreateInfo)
 {
 }
 
 VkResult
 tu_CreateSampler(VkDevice _device,
-                  const VkSamplerCreateInfo *pCreateInfo,
-                  const VkAllocationCallbacks *pAllocator,
-                  VkSampler *pSampler)
+                 const VkSamplerCreateInfo *pCreateInfo,
+                 const VkAllocationCallbacks *pAllocator,
+                 VkSampler *pSampler)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    struct tu_sampler *sampler;
@@ -1762,8 +1767,8 @@ tu_CreateSampler(VkDevice _device,
 
 void
 tu_DestroySampler(VkDevice _device,
-                   VkSampler _sampler,
-                   const VkAllocationCallbacks *pAllocator)
+                  VkSampler _sampler,
+                  const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_device, device, _device);
    TU_FROM_HANDLE(tu_sampler, sampler, _sampler);
@@ -1819,9 +1824,9 @@ vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion)
 
 void
 tu_GetPhysicalDeviceExternalSemaphoreProperties(
-  VkPhysicalDevice physicalDevice,
-  const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo,
-  VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties)
+   VkPhysicalDevice physicalDevice,
+   const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo,
+   VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties)
 {
    pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
    pExternalSemaphoreProperties->compatibleHandleTypes = 0;
@@ -1830,9 +1835,9 @@ tu_GetPhysicalDeviceExternalSemaphoreProperties(
 
 void
 tu_GetPhysicalDeviceExternalFenceProperties(
-  VkPhysicalDevice physicalDevice,
-  const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo,
-  VkExternalFencePropertiesKHR *pExternalFenceProperties)
+   VkPhysicalDevice physicalDevice,
+   const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo,
+   VkExternalFencePropertiesKHR *pExternalFenceProperties)
 {
    pExternalFenceProperties->exportFromImportedHandleTypes = 0;
    pExternalFenceProperties->compatibleHandleTypes = 0;
@@ -1841,10 +1846,10 @@ tu_GetPhysicalDeviceExternalFenceProperties(
 
 VkResult
 tu_CreateDebugReportCallbackEXT(
-  VkInstance _instance,
-  const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
-  const VkAllocationCallbacks *pAllocator,
-  VkDebugReportCallbackEXT *pCallback)
+   VkInstance _instance,
+   const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+   const VkAllocationCallbacks *pAllocator,
+   VkDebugReportCallbackEXT *pCallback)
 {
    TU_FROM_HANDLE(tu_instance, instance, _instance);
    return vk_create_debug_report_callback(&instance->debug_report_callbacks,
@@ -1856,8 +1861,8 @@ tu_CreateDebugReportCallbackEXT(
 
 void
 tu_DestroyDebugReportCallbackEXT(VkInstance _instance,
-                                  VkDebugReportCallbackEXT _callback,
-                                  const VkAllocationCallbacks *pAllocator)
+                                 VkDebugReportCallbackEXT _callback,
+                                 const VkAllocationCallbacks *pAllocator)
 {
    TU_FROM_HANDLE(tu_instance, instance, _instance);
    vk_destroy_debug_report_callback(&instance->debug_report_callbacks,
@@ -1868,13 +1873,13 @@ tu_DestroyDebugReportCallbackEXT(VkInstance _instance,
 
 void
 tu_DebugReportMessageEXT(VkInstance _instance,
-                          VkDebugReportFlagsEXT flags,
-                          VkDebugReportObjectTypeEXT objectType,
-                          uint64_t object,
-                          size_t location,
-                          int32_t messageCode,
-                          const char *pLayerPrefix,
-                          const char *pMessage)
+                         VkDebugReportFlagsEXT flags,
+                         VkDebugReportObjectTypeEXT objectType,
+                         uint64_t object,
+                         size_t location,
+                         int32_t messageCode,
+                         const char *pLayerPrefix,
+                         const char *pMessage)
 {
    TU_FROM_HANDLE(tu_instance, instance, _instance);
    vk_debug_report(&instance->debug_report_callbacks,
@@ -1889,11 +1894,11 @@ tu_DebugReportMessageEXT(VkInstance _instance,
 
 void
 tu_GetDeviceGroupPeerMemoryFeatures(
-  VkDevice device,
-  uint32_t heapIndex,
-  uint32_t localDeviceIndex,
-  uint32_t remoteDeviceIndex,
-  VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
+   VkDevice device,
+   uint32_t heapIndex,
+   uint32_t localDeviceIndex,
+   uint32_t remoteDeviceIndex,
+   VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
 {
    assert(localDeviceIndex == remoteDeviceIndex);