X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Ffreedreno%2Fvulkan%2Ftu_device.c;h=8799f4109fb92583be7921fe590a0296797d4d26;hb=e353fd096d6db1b19305cb1a634e25f2026ab8a7;hp=01fbe9374780d15267e9043037c192d4f1c1f229;hpb=bf709dfe3f82a1b58e8d332bce7770ae4b72f6c1;p=mesa.git diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index 01fbe937478..8799f4109fb 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -21,24 +21,29 @@ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #include "tu_private.h" -#include "util/debug.h" -#include "util/disk_cache.h" -#include "util/strtod.h" -#include "vk_format.h" -#include "vk_util.h" + #include +#include #include #include #include #include #include #include -#include + +#include "compiler/glsl_types.h" +#include "util/debug.h" +#include "util/disk_cache.h" +#include "util/strtod.h" +#include "vk_format.h" +#include "vk_util.h" + +#include "drm-uapi/msm_drm.h" static int tu_device_get_cache_uuid(uint16_t family, void *uuid) @@ -51,8 +56,8 @@ tu_device_get_cache_uuid(uint16_t family, void *uuid) return -1; memcpy(uuid, &mesa_timestamp, 4); - memcpy((char *)uuid + 4, &f, 2); - snprintf((char *)uuid + 6, VK_UUID_SIZE - 10, "tu"); + memcpy((char *) uuid + 4, &f, 2); + snprintf((char *) uuid + 6, VK_UUID_SIZE - 10, "tu"); return 0; } @@ -60,13 +65,32 @@ static void tu_get_driver_uuid(void *uuid) { memset(uuid, 0, VK_UUID_SIZE); + snprintf(uuid, VK_UUID_SIZE, "freedreno"); } static void tu_get_device_uuid(void *uuid) { - tu_use_args(uuid); - tu_stub(); + memset(uuid, 0, VK_UUID_SIZE); +} + +static VkResult +tu_bo_init(struct tu_device *dev, + struct tu_bo *bo, + uint32_t gem_handle, + uint64_t size) +{ + uint64_t iova = tu_gem_info_iova(dev, gem_handle); + if (!iova) + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + + *bo = (struct tu_bo) { + .gem_handle = gem_handle, + .size = size, + .iova = iova, + }; + + return VK_SUCCESS; } VkResult @@ -77,39 +101,40 @@ tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size) */ uint32_t gem_handle = tu_gem_new(dev, size, MSM_BO_WC); if (!gem_handle) - goto fail_new; + return vk_error(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); - /* Calling DRM_MSM_GEM_INFO forces the kernel to allocate backing pages. We - * want immediate backing pages because vkAllocateMemory and friends must - * not lazily fail. - * - * TODO(chadv): Must we really call DRM_MSM_GEM_INFO to acquire backing - * pages? I infer so from reading comments in msm_bo.c:bo_allocate(), but - * maybe I misunderstand. - */ + VkResult result = tu_bo_init(dev, bo, gem_handle, size); + if (result != VK_SUCCESS) { + tu_gem_close(dev, gem_handle); + return vk_error(dev->instance, result); + } - /* TODO: Do we need 'offset' if we have 'iova'? */ - uint64_t offset = tu_gem_info_offset(dev, bo->gem_handle); - if (!offset) - goto fail_info; + return VK_SUCCESS; +} - uint64_t iova = tu_gem_info_iova(dev, bo->gem_handle); - if (!iova) - goto fail_info; +VkResult +tu_bo_init_dmabuf(struct tu_device *dev, + struct tu_bo *bo, + uint64_t size, + int fd) +{ + uint32_t gem_handle = tu_gem_import_dmabuf(dev, fd, size); + if (!gem_handle) + return vk_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE); - *bo = (struct tu_bo) { - .gem_handle = gem_handle, - .size = size, - .offset = offset, - .iova = iova, - }; + VkResult result = tu_bo_init(dev, bo, gem_handle, size); + if (result != VK_SUCCESS) { + tu_gem_close(dev, gem_handle); + return vk_error(dev->instance, result); + } return VK_SUCCESS; +} -fail_info: - tu_gem_close(dev, bo->gem_handle); -fail_new: - return vk_error(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); +int +tu_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo) +{ + return tu_gem_export_dmabuf(dev, bo->gem_handle); } VkResult @@ -118,12 +143,17 @@ tu_bo_map(struct tu_device *dev, struct tu_bo *bo) if (bo->map) return VK_SUCCESS; + uint64_t offset = tu_gem_info_offset(dev, bo->gem_handle); + if (!offset) + return vk_error(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); + /* TODO: Should we use the wrapper os_mmap() like Freedreno does? */ void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, - dev->physical_device->local_fd, bo->offset); + dev->physical_device->local_fd, offset); if (map == MAP_FAILED) return vk_error(dev->instance, VK_ERROR_MEMORY_MAP_FAILED); + bo->map = map; return VK_SUCCESS; } @@ -148,8 +178,6 @@ tu_physical_device_init(struct tu_physical_device *device, drmVersionPtr version; int fd; int master_fd = -1; - struct fd_pipe *tmp_pipe = NULL; - uint64_t val; fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) { @@ -171,19 +199,17 @@ tu_physical_device_init(struct tu_physical_device *device, if (strcmp(version->name, "msm")) { drmFreeVersion(version); - if (master_fd != -1) - close(master_fd); close(fd); return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, "device %s does not use the msm kernel driver", path); } - if (version->version_major != 1 || version->version_minor < 3) { + if (version->version_major != min_version_major || + version->version_minor < min_version_minor) { 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, + path, version->version_major, version->version_minor, min_version_major, min_version_minor); drmFreeVersion(version); close(fd); @@ -201,7 +227,8 @@ tu_physical_device_init(struct tu_physical_device *device, strncpy(device->path, path, ARRAY_SIZE(device->path)); if (instance->enabled_extensions.KHR_display) { - master_fd = open(drm_device->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC); + master_fd = + open(drm_device->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC); if (master_fd >= 0) { /* TODO: free master_fd is accel is not working? */ } @@ -210,42 +237,29 @@ tu_physical_device_init(struct tu_physical_device *device, device->master_fd = master_fd; device->local_fd = fd; - device->drm_device = fd_device_new_dup(fd); - if (!device->drm_device) { - result = vk_errorf( - instance, VK_ERROR_INITIALIZATION_FAILED, "could not create the libdrm device"); - goto fail; - } - - tmp_pipe = fd_pipe_new(device->drm_device, FD_PIPE_3D); - if (!tmp_pipe) { - result = vk_errorf( - instance, VK_ERROR_INITIALIZATION_FAILED, "could not open the 3D pipe"); - goto fail; - } - - if (fd_pipe_get_param(tmp_pipe, FD_GPU_ID, &val)) { - result = vk_errorf( - instance, VK_ERROR_INITIALIZATION_FAILED, "could not get GPU ID"); + if (tu_drm_get_gpu_id(device, &device->gpu_id)) { + if (instance->debug_flags & TU_DEBUG_STARTUP) + tu_logi("Could not query the GPU ID"); + result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED, + "could not get GPU ID"); goto fail; } - device->gpu_id = val; - if (fd_pipe_get_param(tmp_pipe, FD_GMEM_SIZE, &val)) { - result = vk_errorf( - instance, VK_ERROR_INITIALIZATION_FAILED, "could not get GMEM size"); + if (tu_drm_get_gmem_size(device, &device->gmem_size)) { + if (instance->debug_flags & TU_DEBUG_STARTUP) + tu_logi("Could not query the GMEM size"); + result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED, + "could not get GMEM size"); goto fail; } - device->gmem_size = val; - - fd_pipe_del(tmp_pipe); - tmp_pipe = NULL; memset(device->name, 0, sizeof(device->name)); sprintf(device->name, "FD%d", device->gpu_id); - switch(device->gpu_id) { - case 530: + switch (device->gpu_id) { + case 630: + device->tile_align_w = 32; + device->tile_align_h = 32; break; default: result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED, @@ -253,8 +267,8 @@ tu_physical_device_init(struct tu_physical_device *device, goto fail; } if (tu_device_get_cache_uuid(device->gpu_id, device->cache_uuid)) { - result = vk_errorf( - instance, VK_ERROR_INITIALIZATION_FAILED, "cannot generate UUID"); + result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED, + "cannot generate UUID"); goto fail; } @@ -265,9 +279,8 @@ tu_physical_device_init(struct tu_physical_device *device, disk_cache_format_hex_id(buf, device->cache_uuid, VK_UUID_SIZE * 2); device->disk_cache = disk_cache_create(device->name, buf, 0); - fprintf(stderr, - "WARNING: tu is not a conformant vulkan implementation, " - "testing use only.\n"); + fprintf(stderr, "WARNING: tu is not a conformant vulkan implementation, " + "testing use only.\n"); tu_get_driver_uuid(&device->device_uuid); tu_get_device_uuid(&device->device_uuid); @@ -279,13 +292,15 @@ tu_physical_device_init(struct tu_physical_device *device, goto fail; } + result = tu_wsi_init(device); + if (result != VK_SUCCESS) { + vk_error(instance, result); + goto fail; + } + return VK_SUCCESS; fail: - if (tmp_pipe) - fd_pipe_del(tmp_pipe); - if (device->drm_device) - fd_device_del(device->drm_device); close(fd); if (master_fd != -1) close(master_fd); @@ -295,6 +310,8 @@ fail: static void tu_physical_device_finish(struct tu_physical_device *device) { + tu_wsi_finish(device); + disk_cache_destroy(device->disk_cache); close(device->local_fd); if (device->master_fd != -1) @@ -333,9 +350,12 @@ static const VkAllocationCallbacks default_alloc = { .pfnFree = default_free_func, }; -static const struct debug_control tu_debug_options[] = { { "startup", - TU_DEBUG_STARTUP }, - { NULL, 0 } }; +static const struct debug_control tu_debug_options[] = { + { "startup", TU_DEBUG_STARTUP }, + { "nir", TU_DEBUG_NIR }, + { "ir3", TU_DEBUG_IR3 }, + { NULL, 0 } +}; const char * tu_get_debug_option_name(int id) @@ -372,10 +392,7 @@ tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, tu_EnumerateInstanceVersion(&client_version); } - instance = vk_zalloc2(&default_alloc, - pAllocator, - sizeof(*instance), - 8, + instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); if (!instance) return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -391,7 +408,7 @@ tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, instance->physical_device_count = -1; instance->debug_flags = - parse_debug_string(getenv("TU_DEBUG"), tu_debug_options); + parse_debug_string(getenv("TU_DEBUG"), tu_debug_options); if (instance->debug_flags & TU_DEBUG_STARTUP) tu_logi("Created an instance"); @@ -415,6 +432,7 @@ tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, } _mesa_locale_init(); + glsl_type_singleton_init_or_ref(); VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false)); @@ -438,6 +456,7 @@ tu_DestroyInstance(VkInstance _instance, VG(VALGRIND_DESTROY_MEMPOOL(instance)); + glsl_type_singleton_decref(); _mesa_locale_fini(); vk_debug_report_instance_destroy(&instance->debug_report_callbacks); @@ -463,14 +482,13 @@ tu_enumerate_devices(struct tu_instance *instance) if (max_devices < 1) return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER); - for (unsigned i = 0; i < (unsigned)max_devices; i++) { + for (unsigned i = 0; i < (unsigned) max_devices; i++) { if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER && devices[i]->bustype == DRM_BUS_PLATFORM) { - result = tu_physical_device_init(instance->physical_devices + - instance->physical_device_count, - instance, - devices[i]); + result = tu_physical_device_init( + instance->physical_devices + instance->physical_device_count, + instance, devices[i]); if (result == VK_SUCCESS) ++instance->physical_device_count; else if (result != VK_ERROR_INCOMPATIBLE_DRIVER) @@ -499,10 +517,10 @@ tu_EnumeratePhysicalDevices(VkInstance _instance, } for (uint32_t i = 0; i < instance->physical_device_count; ++i) { - vk_outarray_append(&out, p) { + vk_outarray_append(&out, p) + { *p = tu_physical_device_to_handle(instance->physical_devices + i); } - } return vk_outarray_status(&out); @@ -515,7 +533,8 @@ tu_EnumeratePhysicalDeviceGroups( VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) { TU_FROM_HANDLE(tu_instance, instance, _instance); - VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties, pPhysicalDeviceGroupCount); + VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties, + pPhysicalDeviceGroupCount); VkResult result; if (instance->physical_device_count < 0) { @@ -525,10 +544,11 @@ tu_EnumeratePhysicalDeviceGroups( } for (uint32_t i = 0; i < instance->physical_device_count; ++i) { - vk_outarray_append(&out, p) { + vk_outarray_append(&out, p) + { p->physicalDeviceCount = 1; p->physicalDevices[0] = - tu_physical_device_to_handle(instance->physical_devices + i); + tu_physical_device_to_handle(instance->physical_devices + i); p->subsetAllocation = false; } } @@ -542,7 +562,7 @@ tu_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, { memset(pFeatures, 0, sizeof(*pFeatures)); - *pFeatures = (VkPhysicalDeviceFeatures){ + *pFeatures = (VkPhysicalDeviceFeatures) { .robustBufferAccess = false, .fullDrawIndexUint32 = false, .imageCubeArray = false, @@ -593,86 +613,86 @@ tu_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, void tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures2KHR *pFeatures) + VkPhysicalDeviceFeatures2 *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 = false; - features->variablePointers = false; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR: { - VkPhysicalDeviceMultiviewFeaturesKHR *features = - (VkPhysicalDeviceMultiviewFeaturesKHR *)ext; - 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 = false; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: { - VkPhysicalDeviceProtectedMemoryFeatures *features = - (VkPhysicalDeviceProtectedMemoryFeatures *)ext; - features->protectedMemory = false; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: { - VkPhysicalDevice16BitStorageFeatures *features = - (VkPhysicalDevice16BitStorageFeatures *)ext; - features->storageBuffer16BitAccess = false; - features->uniformAndStorageBuffer16BitAccess = false; - features->storagePushConstant16 = false; - features->storageInputOutput16 = false; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: { - VkPhysicalDeviceSamplerYcbcrConversionFeatures *features = - (VkPhysicalDeviceSamplerYcbcrConversionFeatures *)ext; - features->samplerYcbcrConversion = false; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: { - VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features = - (VkPhysicalDeviceDescriptorIndexingFeaturesEXT *)ext; - features->shaderInputAttachmentArrayDynamicIndexing = false; - features->shaderUniformTexelBufferArrayDynamicIndexing = false; - features->shaderStorageTexelBufferArrayDynamicIndexing = false; - features->shaderUniformBufferArrayNonUniformIndexing = false; - features->shaderSampledImageArrayNonUniformIndexing = false; - features->shaderStorageBufferArrayNonUniformIndexing = false; - features->shaderStorageImageArrayNonUniformIndexing = false; - features->shaderInputAttachmentArrayNonUniformIndexing = false; - features->shaderUniformTexelBufferArrayNonUniformIndexing = false; - features->shaderStorageTexelBufferArrayNonUniformIndexing = false; - 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 = false; - features->inheritedConditionalRendering = false; - break; - } - default: - break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: { + VkPhysicalDeviceVariablePointersFeatures *features = (void *) ext; + features->variablePointersStorageBuffer = false; + features->variablePointers = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: { + VkPhysicalDeviceMultiviewFeatures *features = + (VkPhysicalDeviceMultiviewFeatures *) ext; + features->multiview = false; + features->multiviewGeometryShader = false; + features->multiviewTessellationShader = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: { + VkPhysicalDeviceShaderDrawParametersFeatures *features = + (VkPhysicalDeviceShaderDrawParametersFeatures *) ext; + features->shaderDrawParameters = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: { + VkPhysicalDeviceProtectedMemoryFeatures *features = + (VkPhysicalDeviceProtectedMemoryFeatures *) ext; + features->protectedMemory = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: { + VkPhysicalDevice16BitStorageFeatures *features = + (VkPhysicalDevice16BitStorageFeatures *) ext; + features->storageBuffer16BitAccess = false; + features->uniformAndStorageBuffer16BitAccess = false; + features->storagePushConstant16 = false; + features->storageInputOutput16 = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: { + VkPhysicalDeviceSamplerYcbcrConversionFeatures *features = + (VkPhysicalDeviceSamplerYcbcrConversionFeatures *) ext; + features->samplerYcbcrConversion = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: { + VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features = + (VkPhysicalDeviceDescriptorIndexingFeaturesEXT *) ext; + features->shaderInputAttachmentArrayDynamicIndexing = false; + features->shaderUniformTexelBufferArrayDynamicIndexing = false; + features->shaderStorageTexelBufferArrayDynamicIndexing = false; + features->shaderUniformBufferArrayNonUniformIndexing = false; + features->shaderSampledImageArrayNonUniformIndexing = false; + features->shaderStorageBufferArrayNonUniformIndexing = false; + features->shaderStorageImageArrayNonUniformIndexing = false; + features->shaderInputAttachmentArrayNonUniformIndexing = false; + features->shaderUniformTexelBufferArrayNonUniformIndexing = false; + features->shaderStorageTexelBufferArrayNonUniformIndexing = false; + 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 = false; + features->inheritedConditionalRendering = false; + break; + } + default: + break; } } return tu_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features); @@ -692,11 +712,11 @@ tu_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, * there is no set limit, so we just set a pipeline limit. I don't think * any app is going to hit this soon. */ size_t max_descriptor_set_size = - ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS) / - (32 /* uniform buffer, 32 due to potential space wasted on alignment */ + - 32 /* storage buffer, 32 due to potential space wasted on alignment */ + - 32 /* sampler, largest when combined with image */ + - 64 /* sampled image */ + 64 /* storage image */); + ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS) / + (32 /* uniform buffer, 32 due to potential space wasted on alignment */ + + 32 /* storage buffer, 32 due to potential space wasted on alignment */ + + 32 /* sampler, largest when combined with image */ + + 64 /* sampled image */ + 64 /* storage image */); VkPhysicalDeviceLimits limits = { .maxImageDimension1D = (1 << 14), @@ -807,7 +827,7 @@ tu_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, .nonCoherentAtomSize = 64, }; - *pProperties = (VkPhysicalDeviceProperties){ + *pProperties = (VkPhysicalDeviceProperties) { .apiVersion = tu_physical_device_api_version(pdevice), .driverVersion = vk_get_driver_version(), .vendorID = 0, /* TODO */ @@ -823,7 +843,7 @@ tu_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, void tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties2KHR *pProperties) + VkPhysicalDeviceProperties2 *pProperties) { TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice); tu_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties); @@ -831,58 +851,56 @@ tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, vk_foreach_struct(ext, pProperties->pNext) { switch (ext->sType) { - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: { - VkPhysicalDevicePushDescriptorPropertiesKHR *properties = - (VkPhysicalDevicePushDescriptorPropertiesKHR *)ext; - properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR: { - VkPhysicalDeviceIDPropertiesKHR *properties = - (VkPhysicalDeviceIDPropertiesKHR *)ext; - memcpy(properties->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE); - memcpy(properties->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE); - properties->deviceLUIDValid = false; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR: { - VkPhysicalDeviceMultiviewPropertiesKHR *properties = - (VkPhysicalDeviceMultiviewPropertiesKHR *)ext; - properties->maxMultiviewViewCount = MAX_VIEWS; - properties->maxMultiviewInstanceIndex = INT_MAX; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR: { - VkPhysicalDevicePointClippingPropertiesKHR *properties = - (VkPhysicalDevicePointClippingPropertiesKHR *)ext; - properties->pointClippingBehavior = - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR; - break; - } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: { - VkPhysicalDeviceMaintenance3Properties *properties = - (VkPhysicalDeviceMaintenance3Properties *)ext; - /* Make sure everything is addressable by a signed 32-bit int, and - * our largest descriptors are 96 bytes. */ - properties->maxPerSetDescriptors = (1ull << 31) / 96; - /* Our buffer size fields allow only this much */ - properties->maxMemoryAllocationSize = 0xFFFFFFFFull; - break; - } - default: - break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: { + VkPhysicalDevicePushDescriptorPropertiesKHR *properties = + (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext; + properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: { + VkPhysicalDeviceIDProperties *properties = + (VkPhysicalDeviceIDProperties *) ext; + memcpy(properties->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE); + memcpy(properties->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE); + properties->deviceLUIDValid = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: { + VkPhysicalDeviceMultiviewProperties *properties = + (VkPhysicalDeviceMultiviewProperties *) ext; + properties->maxMultiviewViewCount = MAX_VIEWS; + properties->maxMultiviewInstanceIndex = INT_MAX; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: { + VkPhysicalDevicePointClippingProperties *properties = + (VkPhysicalDevicePointClippingProperties *) ext; + properties->pointClippingBehavior = + VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: { + VkPhysicalDeviceMaintenance3Properties *properties = + (VkPhysicalDeviceMaintenance3Properties *) ext; + /* Make sure everything is addressable by a signed 32-bit int, and + * our largest descriptors are 96 bytes. */ + properties->maxPerSetDescriptors = (1ull << 31) / 96; + /* Our buffer size fields allow only this much */ + properties->maxMemoryAllocationSize = 0xFFFFFFFFull; + break; + } + default: + break; } } } -static const VkQueueFamilyProperties -tu_queue_family_properties = { - .queueFlags = VK_QUEUE_GRAPHICS_BIT | - VK_QUEUE_COMPUTE_BIT | - VK_QUEUE_TRANSFER_BIT, +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 }, + .minImageTransferGranularity = { 1, 1, 1 }, }; void @@ -893,20 +911,19 @@ tu_GetPhysicalDeviceQueueFamilyProperties( { VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount); - vk_outarray_append(&out, p) { - *p = tu_queue_family_properties; - } + vk_outarray_append(&out, p) { *p = tu_queue_family_properties; } } void tu_GetPhysicalDeviceQueueFamilyProperties2( VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, - VkQueueFamilyProperties2KHR *pQueueFamilyProperties) + VkQueueFamilyProperties2 *pQueueFamilyProperties) { VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount); - vk_outarray_append(&out, p) { + vk_outarray_append(&out, p) + { p->queueFamilyProperties = tu_queue_family_properties; } } @@ -917,7 +934,7 @@ tu_get_system_heap_size() struct sysinfo info; sysinfo(&info); - uint64_t total_ram = (uint64_t)info.totalram * (uint64_t)info.mem_unit; + 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. @@ -941,22 +958,23 @@ tu_GetPhysicalDeviceMemoryProperties( 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].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) + VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) { return tu_GetPhysicalDeviceMemoryProperties( - physicalDevice, &pMemoryProperties->memoryProperties); + physicalDevice, &pMemoryProperties->memoryProperties); } -static int +static VkResult tu_queue_init(struct tu_device *device, struct tu_queue *queue, uint32_t queue_family_index, @@ -969,12 +987,20 @@ tu_queue_init(struct tu_device *device, queue->queue_idx = idx; queue->flags = flags; + int ret = tu_drm_submitqueue_new(device, 0, &queue->msm_queue_id); + if (ret) + return VK_ERROR_INITIALIZATION_FAILED; + + tu_fence_init(&queue->submit_fence, false); + return VK_SUCCESS; } static void tu_queue_finish(struct tu_queue *queue) { + tu_fence_finish(&queue->submit_fence); + tu_drm_submitqueue_close(queue->device, queue->msm_queue_id); } static int @@ -1001,10 +1027,10 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice, if (pCreateInfo->pEnabledFeatures) { VkPhysicalDeviceFeatures supported_features; tu_GetPhysicalDeviceFeatures(physicalDevice, &supported_features); - VkBool32 *supported_feature = (VkBool32 *)&supported_features; - VkBool32 *enabled_feature = (VkBool32 *)pCreateInfo->pEnabledFeatures; + VkBool32 *supported_feature = (VkBool32 *) &supported_features; + VkBool32 *enabled_feature = (VkBool32 *) pCreateInfo->pEnabledFeatures; unsigned num_features = - sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); + sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); for (uint32_t i = 0; i < num_features; i++) { if (enabled_feature[i] && !supported_feature[i]) return vk_error(physical_device->instance, @@ -1012,11 +1038,8 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice, } } - device = vk_zalloc2(&physical_device->instance->alloc, - pAllocator, - sizeof(*device), - 8, - VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + device = vk_zalloc2(&physical_device->instance->alloc, pAllocator, + sizeof(*device), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); if (!device) return vk_error(physical_device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -1044,32 +1067,33 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice, for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { const VkDeviceQueueCreateInfo *queue_create = - &pCreateInfo->pQueueCreateInfos[i]; + &pCreateInfo->pQueueCreateInfos[i]; uint32_t qfi = queue_create->queueFamilyIndex; - device->queues[qfi] = - vk_alloc(&device->alloc, - queue_create->queueCount * sizeof(struct tu_queue), - 8, - VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + device->queues[qfi] = vk_alloc( + &device->alloc, queue_create->queueCount * sizeof(struct tu_queue), + 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); if (!device->queues[qfi]) { result = VK_ERROR_OUT_OF_HOST_MEMORY; goto fail; } - memset(device->queues[qfi], - 0, + memset(device->queues[qfi], 0, queue_create->queueCount * sizeof(struct tu_queue)); device->queue_count[qfi] = queue_create->queueCount; for (unsigned q = 0; q < queue_create->queueCount; q++) { - result = tu_queue_init( - device, &device->queues[qfi][q], qfi, q, queue_create->flags); + result = tu_queue_init(device, &device->queues[qfi][q], qfi, q, + queue_create->flags); if (result != VK_SUCCESS) goto fail; } } + device->compiler = ir3_compiler_create(NULL, physical_device->gpu_id); + if (!device->compiler) + goto fail; + VkPipelineCacheCreateInfo ci; ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; ci.pNext = NULL; @@ -1078,7 +1102,7 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice, ci.initialDataSize = 0; VkPipelineCache pc; result = - tu_CreatePipelineCache(tu_device_to_handle(device), &ci, NULL, &pc); + tu_CreatePipelineCache(tu_device_to_handle(device), &ci, NULL, &pc); if (result != VK_SUCCESS) goto fail; @@ -1095,6 +1119,9 @@ fail: vk_free(&device->alloc, device->queues[i]); } + if (device->compiler) + ralloc_free(device->compiler); + vk_free(&device->alloc, device); return result; } @@ -1114,6 +1141,9 @@ tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) vk_free(&device->alloc, device->queues[i]); } + /* the compiler does not use pAllocator */ + ralloc_free(device->compiler); + VkPipelineCache pc = tu_pipeline_cache_to_handle(device->mem_cache); tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL); @@ -1146,7 +1176,7 @@ tu_GetDeviceQueue2(VkDevice _device, struct tu_queue *queue; queue = - &device->queues[pQueueInfo->queueFamilyIndex][pQueueInfo->queueIndex]; + &device->queues[pQueueInfo->queueFamilyIndex][pQueueInfo->queueIndex]; if (pQueueInfo->flags != queue->flags) { /* From the Vulkan 1.1.70 spec: * @@ -1170,9 +1200,9 @@ tu_GetDeviceQueue(VkDevice _device, VkQueue *pQueue) { const VkDeviceQueueInfo2 info = - (VkDeviceQueueInfo2){.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2, - .queueFamilyIndex = queueFamilyIndex, - .queueIndex = queueIndex }; + (VkDeviceQueueInfo2) { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2, + .queueFamilyIndex = queueFamilyIndex, + .queueIndex = queueIndex }; tu_GetDeviceQueue2(_device, &info, pQueue); } @@ -1183,12 +1213,85 @@ tu_QueueSubmit(VkQueue _queue, const VkSubmitInfo *pSubmits, VkFence _fence) { + TU_FROM_HANDLE(tu_queue, queue, _queue); + + for (uint32_t i = 0; i < submitCount; ++i) { + const VkSubmitInfo *submit = pSubmits + i; + const bool last_submit = (i == submitCount - 1); + struct tu_bo_list bo_list; + tu_bo_list_init(&bo_list); + + uint32_t entry_count = 0; + for (uint32_t j = 0; j < submit->commandBufferCount; ++j) { + TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBuffers[j]); + entry_count += cmdbuf->cs.entry_count; + } + + struct drm_msm_gem_submit_cmd cmds[entry_count]; + uint32_t entry_idx = 0; + for (uint32_t j = 0; j < submit->commandBufferCount; ++j) { + TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBuffers[j]); + struct tu_cs *cs = &cmdbuf->cs; + for (unsigned i = 0; i < cs->entry_count; ++i, ++entry_idx) { + cmds[entry_idx].type = MSM_SUBMIT_CMD_BUF; + cmds[entry_idx].submit_idx = + tu_bo_list_add(&bo_list, cs->entries[i].bo, + MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_DUMP); + cmds[entry_idx].submit_offset = cs->entries[i].offset; + cmds[entry_idx].size = cs->entries[i].size; + cmds[entry_idx].pad = 0; + cmds[entry_idx].nr_relocs = 0; + cmds[entry_idx].relocs = 0; + } + + tu_bo_list_merge(&bo_list, &cmdbuf->bo_list); + } + + uint32_t flags = MSM_PIPE_3D0; + if (last_submit) { + flags |= MSM_SUBMIT_FENCE_FD_OUT; + } + + struct drm_msm_gem_submit req = { + .flags = flags, + .queueid = queue->msm_queue_id, + .bos = (uint64_t)(uintptr_t) bo_list.bo_infos, + .nr_bos = bo_list.count, + .cmds = (uint64_t)(uintptr_t)cmds, + .nr_cmds = entry_count, + }; + + int ret = drmCommandWriteRead(queue->device->physical_device->local_fd, + DRM_MSM_GEM_SUBMIT, + &req, sizeof(req)); + if (ret) { + fprintf(stderr, "submit failed: %s\n", strerror(errno)); + abort(); + } + + tu_bo_list_destroy(&bo_list); + + if (last_submit) { + /* no need to merge fences as queue execution is serialized */ + tu_fence_update_fd(&queue->submit_fence, req.fence_fd); + } + } + + if (_fence != VK_NULL_HANDLE) { + TU_FROM_HANDLE(tu_fence, fence, _fence); + tu_fence_copy(fence, &queue->submit_fence); + } + return VK_SUCCESS; } VkResult tu_QueueWaitIdle(VkQueue _queue) { + TU_FROM_HANDLE(tu_queue, queue, _queue); + + tu_fence_wait_idle(&queue->submit_fence); + return VK_SUCCESS; } @@ -1253,11 +1356,9 @@ tu_GetInstanceProcAddr(VkInstance _instance, const char *pName) { TU_FROM_HANDLE(tu_instance, instance, _instance); - return tu_lookup_entrypoint_checked(pName, - instance ? instance->api_version : 0, - instance ? &instance->enabled_extensions - : NULL, - NULL); + return tu_lookup_entrypoint_checked( + pName, instance ? instance->api_version : 0, + instance ? &instance->enabled_extensions : NULL, NULL); } /* The loader wants us to expose a second GetInstanceProcAddr function @@ -1279,10 +1380,9 @@ tu_GetDeviceProcAddr(VkDevice _device, const char *pName) { TU_FROM_HANDLE(tu_device, device, _device); - return tu_lookup_entrypoint_checked(pName, - device->instance->api_version, - &device->instance->enabled_extensions, - &device->enabled_extensions); + return tu_lookup_entrypoint_checked(pName, device->instance->api_version, + &device->instance->enabled_extensions, + &device->enabled_extensions); } static VkResult @@ -1302,16 +1402,39 @@ tu_alloc_memory(struct tu_device *device, return VK_SUCCESS; } - mem = vk_alloc2(&device->alloc, - pAllocator, - sizeof(*mem), - 8, + mem = vk_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (mem == NULL) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - result = tu_bo_init_new(device, &mem->bo, pAllocateInfo->allocationSize); - if (!result) { + const VkImportMemoryFdInfoKHR *fd_info = + vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR); + if (fd_info && !fd_info->handleType) + fd_info = NULL; + + if (fd_info) { + assert(fd_info->handleType == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT || + fd_info->handleType == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); + + /* + * TODO Importing the same fd twice gives us the same handle without + * reference counting. We need to maintain a per-instance handle-to-bo + * table and add reference count to tu_bo. + */ + result = tu_bo_init_dmabuf(device, &mem->bo, + pAllocateInfo->allocationSize, fd_info->fd); + if (result == VK_SUCCESS) { + /* take ownership and close the fd */ + close(fd_info->fd); + } + } else { + result = + tu_bo_init_new(device, &mem->bo, pAllocateInfo->allocationSize); + } + + if (result != VK_SUCCESS) { vk_free2(&device->alloc, pAllocator, mem); return result; } @@ -1371,11 +1494,11 @@ tu_MapMemory(VkDevice _device, if (mem->user_ptr) { *ppData = mem->user_ptr; - } else if (!mem->map){ + } else if (!mem->map) { result = tu_bo_map(device, &mem->bo); if (result != VK_SUCCESS) return result; - mem->map = mem->bo.map; + *ppData = mem->map = mem->bo.map; } else *ppData = mem->map; @@ -1419,17 +1542,17 @@ tu_GetBufferMemoryRequirements(VkDevice _device, pMemoryRequirements->memoryTypeBits = 1; pMemoryRequirements->alignment = 16; pMemoryRequirements->size = - align64(buffer->size, pMemoryRequirements->alignment); + align64(buffer->size, pMemoryRequirements->alignment); } void tu_GetBufferMemoryRequirements2( VkDevice device, - const VkBufferMemoryRequirementsInfo2KHR *pInfo, - VkMemoryRequirements2KHR *pMemoryRequirements) + const VkBufferMemoryRequirementsInfo2 *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) { - tu_GetBufferMemoryRequirements( - device, pInfo->buffer, &pMemoryRequirements->memoryRequirements); + tu_GetBufferMemoryRequirements(device, pInfo->buffer, + &pMemoryRequirements->memoryRequirements); } void @@ -1446,11 +1569,11 @@ tu_GetImageMemoryRequirements(VkDevice _device, void tu_GetImageMemoryRequirements2(VkDevice device, - const VkImageMemoryRequirementsInfo2KHR *pInfo, - VkMemoryRequirements2KHR *pMemoryRequirements) + const VkImageMemoryRequirementsInfo2 *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) { - tu_GetImageMemoryRequirements( - device, pInfo->image, &pMemoryRequirements->memoryRequirements); + tu_GetImageMemoryRequirements(device, pInfo->image, + &pMemoryRequirements->memoryRequirements); } void @@ -1466,9 +1589,9 @@ tu_GetImageSparseMemoryRequirements( void tu_GetImageSparseMemoryRequirements2( VkDevice device, - const VkImageSparseMemoryRequirementsInfo2KHR *pInfo, + const VkImageSparseMemoryRequirementsInfo2 *pInfo, uint32_t *pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements2KHR *pSparseMemoryRequirements) + VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) { tu_stub(); } @@ -1484,8 +1607,19 @@ tu_GetDeviceMemoryCommitment(VkDevice device, VkResult tu_BindBufferMemory2(VkDevice device, uint32_t bindInfoCount, - const VkBindBufferMemoryInfoKHR *pBindInfos) + const VkBindBufferMemoryInfo *pBindInfos) { + for (uint32_t i = 0; i < bindInfoCount; ++i) { + TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory); + TU_FROM_HANDLE(tu_buffer, buffer, pBindInfos[i].buffer); + + if (mem) { + buffer->bo = &mem->bo; + buffer->bo_offset = pBindInfos[i].memoryOffset; + } else { + buffer->bo = NULL; + } + } return VK_SUCCESS; } @@ -1495,8 +1629,8 @@ tu_BindBufferMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize memoryOffset) { - const VkBindBufferMemoryInfoKHR info = { - .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR, + const VkBindBufferMemoryInfo info = { + .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, .buffer = buffer, .memory = memory, .memoryOffset = memoryOffset @@ -1508,8 +1642,21 @@ tu_BindBufferMemory(VkDevice device, VkResult tu_BindImageMemory2(VkDevice device, uint32_t bindInfoCount, - const VkBindImageMemoryInfoKHR *pBindInfos) -{ + const VkBindImageMemoryInfo *pBindInfos) +{ + for (uint32_t i = 0; i < bindInfoCount; ++i) { + TU_FROM_HANDLE(tu_image, image, pBindInfos[i].image); + TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory); + + if (mem) { + image->bo = &mem->bo; + image->bo_offset = pBindInfos[i].memoryOffset; + } else { + image->bo = NULL; + image->bo_offset = 0; + } + } + return VK_SUCCESS; } @@ -1519,8 +1666,8 @@ tu_BindImageMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize memoryOffset) { - const VkBindImageMemoryInfoKHR info = { - .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR, + const VkBindImageMemoryInfo info = { + .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, .image = image, .memory = memory, .memoryOffset = memoryOffset @@ -1538,64 +1685,6 @@ tu_QueueBindSparse(VkQueue _queue, return VK_SUCCESS; } -VkResult -tu_CreateFence(VkDevice _device, - const VkFenceCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkFence *pFence) -{ - TU_FROM_HANDLE(tu_device, device, _device); - - struct tu_fence *fence = vk_alloc2(&device->alloc, - pAllocator, - sizeof(*fence), - 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - - if (!fence) - return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - - *pFence = tu_fence_to_handle(fence); - - return VK_SUCCESS; -} - -void -tu_DestroyFence(VkDevice _device, - VkFence _fence, - const VkAllocationCallbacks *pAllocator) -{ - TU_FROM_HANDLE(tu_device, device, _device); - TU_FROM_HANDLE(tu_fence, fence, _fence); - - if (!fence) - return; - - vk_free2(&device->alloc, pAllocator, fence); -} - -VkResult -tu_WaitForFences(VkDevice _device, - uint32_t fenceCount, - const VkFence *pFences, - VkBool32 waitAll, - uint64_t timeout) -{ - return VK_SUCCESS; -} - -VkResult -tu_ResetFences(VkDevice _device, uint32_t fenceCount, const VkFence *pFences) -{ - return VK_SUCCESS; -} - -VkResult -tu_GetFenceStatus(VkDevice _device, VkFence _fence) -{ - return VK_SUCCESS; -} - // Queue semaphore functions VkResult @@ -1606,11 +1695,9 @@ tu_CreateSemaphore(VkDevice _device, { TU_FROM_HANDLE(tu_device, device, _device); - struct tu_semaphore *sem = vk_alloc2(&device->alloc, - pAllocator, - sizeof(*sem), - 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + struct tu_semaphore *sem = + vk_alloc2(&device->alloc, pAllocator, sizeof(*sem), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (!sem) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -1638,11 +1725,9 @@ tu_CreateEvent(VkDevice _device, VkEvent *pEvent) { TU_FROM_HANDLE(tu_device, device, _device); - struct tu_event *event = vk_alloc2(&device->alloc, - pAllocator, - sizeof(*event), - 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + struct tu_event *event = + vk_alloc2(&device->alloc, pAllocator, sizeof(*event), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (!event) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -1704,10 +1789,7 @@ tu_CreateBuffer(VkDevice _device, assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); - buffer = vk_alloc2(&device->alloc, - pAllocator, - sizeof(*buffer), - 8, + buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (buffer == NULL) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -1739,8 +1821,8 @@ static uint32_t tu_surface_max_layer_count(struct tu_image_view *iview) { return iview->type == VK_IMAGE_VIEW_TYPE_3D - ? iview->extent.depth - : (iview->base_layer + iview->layer_count); + ? iview->extent.depth + : (iview->base_layer + iview->layer_count); } VkResult @@ -1754,11 +1836,10 @@ tu_CreateFramebuffer(VkDevice _device, assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); - size_t size = - sizeof(*framebuffer) + - sizeof(struct tu_attachment_info) * pCreateInfo->attachmentCount; - framebuffer = vk_alloc2( - &device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + size_t size = sizeof(*framebuffer) + sizeof(struct tu_attachment_info) * + pCreateInfo->attachmentCount; + framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (framebuffer == NULL) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -1774,7 +1855,7 @@ tu_CreateFramebuffer(VkDevice _device, framebuffer->width = MIN2(framebuffer->width, iview->extent.width); framebuffer->height = MIN2(framebuffer->height, iview->extent.height); framebuffer->layers = - MIN2(framebuffer->layers, tu_surface_max_layer_count(iview)); + MIN2(framebuffer->layers, tu_surface_max_layer_count(iview)); } *pFramebuffer = tu_framebuffer_to_handle(framebuffer); @@ -1812,10 +1893,7 @@ tu_CreateSampler(VkDevice _device, assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); - sampler = vk_alloc2(&device->alloc, - pAllocator, - sizeof(*sampler), - 8, + sampler = vk_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (!sampler) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -1849,45 +1927,81 @@ PUBLIC VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion) { /* For the full details on loader interface versioning, see - * . - * What follows is a condensed summary, to help you navigate the large and - * confusing official doc. - * - * - Loader interface v0 is incompatible with later versions. We don't - * support it. - * - * - In loader interface v1: - * - The first ICD entrypoint called by the loader is - * vk_icdGetInstanceProcAddr(). The ICD must statically expose this - * entrypoint. - * - The ICD must statically expose no other Vulkan symbol unless it is - * linked with -Bsymbolic. - * - Each dispatchable Vulkan handle created by the ICD must be - * a pointer to a struct whose first member is VK_LOADER_DATA. The - * ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC. - * - The loader implements vkCreate{PLATFORM}SurfaceKHR() and - * vkDestroySurfaceKHR(). The ICD must be capable of working with - * such loader-managed surfaces. - * - * - Loader interface v2 differs from v1 in: - * - The first ICD entrypoint called by the loader is - * vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must - * statically expose this entrypoint. - * - * - Loader interface v3 differs from v2 in: - * - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(), - * vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR, - * because the loader no longer does so. - */ + * . + * What follows is a condensed summary, to help you navigate the large and + * confusing official doc. + * + * - Loader interface v0 is incompatible with later versions. We don't + * support it. + * + * - In loader interface v1: + * - The first ICD entrypoint called by the loader is + * vk_icdGetInstanceProcAddr(). The ICD must statically expose this + * entrypoint. + * - The ICD must statically expose no other Vulkan symbol unless it + * is linked with -Bsymbolic. + * - Each dispatchable Vulkan handle created by the ICD must be + * a pointer to a struct whose first member is VK_LOADER_DATA. The + * ICD must initialize VK_LOADER_DATA.loadMagic to + * ICD_LOADER_MAGIC. + * - The loader implements vkCreate{PLATFORM}SurfaceKHR() and + * vkDestroySurfaceKHR(). The ICD must be capable of working with + * such loader-managed surfaces. + * + * - Loader interface v2 differs from v1 in: + * - The first ICD entrypoint called by the loader is + * vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must + * statically expose this entrypoint. + * + * - Loader interface v3 differs from v2 in: + * - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(), + * vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR, + * because the loader no longer does so. + */ *pSupportedVersion = MIN2(*pSupportedVersion, 3u); return VK_SUCCESS; } +VkResult +tu_GetMemoryFdKHR(VkDevice _device, + const VkMemoryGetFdInfoKHR *pGetFdInfo, + int *pFd) +{ + TU_FROM_HANDLE(tu_device, device, _device); + TU_FROM_HANDLE(tu_device_memory, memory, pGetFdInfo->memory); + + assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR); + + /* At the moment, we support only the below handle types. */ + assert(pGetFdInfo->handleType == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT || + pGetFdInfo->handleType == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); + + int prime_fd = tu_bo_export_dmabuf(device, &memory->bo); + if (prime_fd < 0) + return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY); + + *pFd = prime_fd; + return VK_SUCCESS; +} + +VkResult +tu_GetMemoryFdPropertiesKHR(VkDevice _device, + VkExternalMemoryHandleTypeFlagBits handleType, + int fd, + VkMemoryFdPropertiesKHR *pMemoryFdProperties) +{ + assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); + pMemoryFdProperties->memoryTypeBits = 1; + return VK_SUCCESS; +} + void tu_GetPhysicalDeviceExternalSemaphoreProperties( VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo, - VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties) + const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, + VkExternalSemaphoreProperties *pExternalSemaphoreProperties) { pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0; pExternalSemaphoreProperties->compatibleHandleTypes = 0; @@ -1897,8 +2011,8 @@ tu_GetPhysicalDeviceExternalSemaphoreProperties( void tu_GetPhysicalDeviceExternalFenceProperties( VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo, - VkExternalFencePropertiesKHR *pExternalFenceProperties) + const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, + VkExternalFenceProperties *pExternalFenceProperties) { pExternalFenceProperties->exportFromImportedHandleTypes = 0; pExternalFenceProperties->compatibleHandleTypes = 0; @@ -1914,10 +2028,8 @@ tu_CreateDebugReportCallbackEXT( { TU_FROM_HANDLE(tu_instance, instance, _instance); return vk_create_debug_report_callback(&instance->debug_report_callbacks, - pCreateInfo, - pAllocator, - &instance->alloc, - pCallback); + pCreateInfo, pAllocator, + &instance->alloc, pCallback); } void @@ -1927,9 +2039,7 @@ tu_DestroyDebugReportCallbackEXT(VkInstance _instance, { TU_FROM_HANDLE(tu_instance, instance, _instance); vk_destroy_debug_report_callback(&instance->debug_report_callbacks, - _callback, - pAllocator, - &instance->alloc); + _callback, pAllocator, &instance->alloc); } void @@ -1943,14 +2053,8 @@ tu_DebugReportMessageEXT(VkInstance _instance, const char *pMessage) { TU_FROM_HANDLE(tu_instance, instance, _instance); - vk_debug_report(&instance->debug_report_callbacks, - flags, - objectType, - object, - location, - messageCode, - pLayerPrefix, - pMessage); + vk_debug_report(&instance->debug_report_callbacks, flags, objectType, + object, location, messageCode, pLayerPrefix, pMessage); } void