X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Ffreedreno%2Fvulkan%2Ftu_device.c;h=43ed5f6e4a8c8dc7e7092957e7b94f8c2dbaeaf1;hb=aba8c579a9780f9d3ad2d677f9ef625df7726479;hp=467d56da5c4aa54c4316680dac016ad453c34354;hpb=3e11f04d4e09bf71d2e5899f0afa9d04e8f6196e;p=mesa.git diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index 467d56da5c4..43ed5f6e4a8 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -48,6 +48,10 @@ /* for fd_get_driver/device_uuid() */ #include "freedreno/common/freedreno_uuid.h" +static void +tu_semaphore_remove_temp(struct tu_device *device, + struct tu_semaphore *sem); + static int tu_device_get_cache_uuid(uint16_t family, void *uuid) { @@ -206,6 +210,9 @@ tu_physical_device_init(struct tu_physical_device *device, return result; } + device->msm_major_version = version->version_major; + device->msm_minor_version = version->version_minor; + drmFreeVersion(version); if (instance->debug_flags & TU_DEBUG_STARTUP) @@ -586,16 +593,16 @@ tu_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, .imageCubeArray = true, .independentBlend = true, .geometryShader = true, - .tessellationShader = false, + .tessellationShader = true, .sampleRateShading = true, .dualSrcBlend = true, .logicOp = true, - .multiDrawIndirect = false, - .drawIndirectFirstInstance = false, + .multiDrawIndirect = true, + .drawIndirectFirstInstance = true, .depthClamp = true, .depthBiasClamp = false, - .fillModeNonSolid = false, - .depthBounds = false, + .fillModeNonSolid = true, + .depthBounds = true, .wideLines = false, .largePoints = false, .alphaToOne = true, @@ -636,6 +643,22 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, vk_foreach_struct(ext, pFeatures->pNext) { switch (ext->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: { + VkPhysicalDeviceVulkan11Features *features = (void *) ext; + features->storageBuffer16BitAccess = false; + features->uniformAndStorageBuffer16BitAccess = false; + features->storagePushConstant16 = false; + features->storageInputOutput16 = false; + features->multiview = false; + features->multiviewGeometryShader = false; + features->multiviewTessellationShader = false; + features->variablePointersStorageBuffer = false; + features->variablePointers = false; + features->protectedMemory = false; + features->samplerYcbcrConversion = true; + features->shaderDrawParameters = true; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: { VkPhysicalDeviceVariablePointersFeatures *features = (void *) ext; features->variablePointersStorageBuffer = false; @@ -653,7 +676,7 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: { VkPhysicalDeviceShaderDrawParametersFeatures *features = (VkPhysicalDeviceShaderDrawParametersFeatures *) ext; - features->shaderDrawParameters = false; + features->shaderDrawParameters = true; break; } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: { @@ -716,6 +739,19 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, features->geometryStreams = false; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: { + VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features = + (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext; + features->indexTypeUint8 = true; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: { + VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features = + (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext; + features->vertexAttributeInstanceRateDivisor = true; + features->vertexAttributeInstanceRateZeroDivisor = true; + break; + } default: break; } @@ -948,7 +984,22 @@ tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, properties->filterMinmaxSingleComponentFormats = true; break; } - + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: { + VkPhysicalDeviceSubgroupProperties *properties = + (VkPhysicalDeviceSubgroupProperties *)ext; + properties->subgroupSize = 64; + properties->supportedStages = VK_SHADER_STAGE_COMPUTE_BIT; + properties->supportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT | + VK_SUBGROUP_FEATURE_VOTE_BIT; + properties->quadOperationsInAllStages = false; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: { + VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props = + (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext; + props->maxVertexAttribDivisor = UINT32_MAX; + break; + } default: break; } @@ -1302,8 +1353,7 @@ tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) tu_bo_finish(device, &device->scratch_bos[i].bo); } - /* the compiler does not use pAllocator */ - ralloc_free(device->compiler); + ir3_compiler_destroy(device->compiler); VkPipelineCache pc = tu_pipeline_cache_to_handle(device->mem_cache); tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL); @@ -1413,6 +1463,65 @@ tu_GetDeviceQueue(VkDevice _device, tu_GetDeviceQueue2(_device, &info, pQueue); } +static VkResult +tu_get_semaphore_syncobjs(const VkSemaphore *sems, + uint32_t sem_count, + bool wait, + struct drm_msm_gem_submit_syncobj **out, + uint32_t *out_count) +{ + uint32_t syncobj_count = 0; + struct drm_msm_gem_submit_syncobj *syncobjs; + + for (uint32_t i = 0; i < sem_count; ++i) { + TU_FROM_HANDLE(tu_semaphore, sem, sems[i]); + + struct tu_semaphore_part *part = + sem->temporary.kind != TU_SEMAPHORE_NONE ? + &sem->temporary : &sem->permanent; + + if (part->kind == TU_SEMAPHORE_SYNCOBJ) + ++syncobj_count; + } + + *out = NULL; + *out_count = syncobj_count; + if (!syncobj_count) + return VK_SUCCESS; + + *out = syncobjs = calloc(syncobj_count, sizeof (*syncobjs)); + if (!syncobjs) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + for (uint32_t i = 0, j = 0; i < sem_count; ++i) { + TU_FROM_HANDLE(tu_semaphore, sem, sems[i]); + + struct tu_semaphore_part *part = + sem->temporary.kind != TU_SEMAPHORE_NONE ? + &sem->temporary : &sem->permanent; + + if (part->kind == TU_SEMAPHORE_SYNCOBJ) { + syncobjs[j].handle = part->syncobj; + syncobjs[j].flags = wait ? MSM_SUBMIT_SYNCOBJ_RESET : 0; + ++j; + } + } + + return VK_SUCCESS; +} + + +static void +tu_semaphores_remove_temp(struct tu_device *device, + const VkSemaphore *sems, + uint32_t sem_count) +{ + for (uint32_t i = 0; i < sem_count; ++i) { + TU_FROM_HANDLE(tu_semaphore, sem, sems[i]); + tu_semaphore_remove_temp(device, sem); + } +} + VkResult tu_QueueSubmit(VkQueue _queue, uint32_t submitCount, @@ -1420,13 +1529,34 @@ tu_QueueSubmit(VkQueue _queue, VkFence _fence) { TU_FROM_HANDLE(tu_queue, queue, _queue); + VkResult result; for (uint32_t i = 0; i < submitCount; ++i) { const VkSubmitInfo *submit = pSubmits + i; const bool last_submit = (i == submitCount - 1); + struct drm_msm_gem_submit_syncobj *in_syncobjs = NULL, *out_syncobjs = NULL; + uint32_t nr_in_syncobjs, nr_out_syncobjs; struct tu_bo_list bo_list; tu_bo_list_init(&bo_list); + result = tu_get_semaphore_syncobjs(pSubmits[i].pWaitSemaphores, + pSubmits[i].waitSemaphoreCount, + false, &in_syncobjs, &nr_in_syncobjs); + if (result != VK_SUCCESS) { + /* TODO: emit VK_ERROR_DEVICE_LOST */ + fprintf(stderr, "failed to allocate space for semaphore submission\n"); + abort(); + } + + result = tu_get_semaphore_syncobjs(pSubmits[i].pSignalSemaphores, + pSubmits[i].signalSemaphoreCount, + false, &out_syncobjs, &nr_out_syncobjs); + if (result != VK_SUCCESS) { + /* TODO: emit VK_ERROR_DEVICE_LOST */ + fprintf(stderr, "failed to allocate space for semaphore submission\n"); + abort(); + } + uint32_t entry_count = 0; for (uint32_t j = 0; j < submit->commandBufferCount; ++j) { TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBuffers[j]); @@ -1454,6 +1584,13 @@ tu_QueueSubmit(VkQueue _queue, } uint32_t flags = MSM_PIPE_3D0; + if (nr_in_syncobjs) { + flags |= MSM_SUBMIT_SYNCOBJ_IN; + } + if (nr_out_syncobjs) { + flags |= MSM_SUBMIT_SYNCOBJ_OUT; + } + if (last_submit) { flags |= MSM_SUBMIT_FENCE_FD_OUT; } @@ -1465,6 +1602,11 @@ tu_QueueSubmit(VkQueue _queue, .nr_bos = bo_list.count, .cmds = (uint64_t)(uintptr_t)cmds, .nr_cmds = entry_count, + .in_syncobjs = (uint64_t)(uintptr_t)in_syncobjs, + .out_syncobjs = (uint64_t)(uintptr_t)out_syncobjs, + .nr_in_syncobjs = nr_in_syncobjs, + .nr_out_syncobjs = nr_out_syncobjs, + .syncobj_stride = sizeof(struct drm_msm_gem_submit_syncobj), }; int ret = drmCommandWriteRead(queue->device->physical_device->local_fd, @@ -1476,10 +1618,16 @@ tu_QueueSubmit(VkQueue _queue, } tu_bo_list_destroy(&bo_list); + free(in_syncobjs); + free(out_syncobjs); + tu_semaphores_remove_temp(queue->device, pSubmits[i].pWaitSemaphores, + pSubmits[i].waitSemaphoreCount); if (last_submit) { /* no need to merge fences as queue execution is serialized */ tu_fence_update_fd(&queue->submit_fence, req.fence_fd); + } else if (last_submit) { + close(req.fence_fd); } } @@ -1514,44 +1662,6 @@ tu_DeviceWaitIdle(VkDevice _device) return VK_SUCCESS; } -VkResult -tu_ImportSemaphoreFdKHR(VkDevice _device, - const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) -{ - tu_stub(); - - return VK_SUCCESS; -} - -VkResult -tu_GetSemaphoreFdKHR(VkDevice _device, - const VkSemaphoreGetFdInfoKHR *pGetFdInfo, - int *pFd) -{ - tu_stub(); - - return VK_SUCCESS; -} - -VkResult -tu_ImportFenceFdKHR(VkDevice _device, - const VkImportFenceFdInfoKHR *pImportFenceFdInfo) -{ - tu_stub(); - - return VK_SUCCESS; -} - -VkResult -tu_GetFenceFdKHR(VkDevice _device, - const VkFenceGetFdInfoKHR *pGetFdInfo, - int *pFd) -{ - tu_stub(); - - return VK_SUCCESS; -} - VkResult tu_EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, @@ -1931,6 +2041,30 @@ tu_QueueBindSparse(VkQueue _queue, // Queue semaphore functions + +static void +tu_semaphore_part_destroy(struct tu_device *device, + struct tu_semaphore_part *part) +{ + switch(part->kind) { + case TU_SEMAPHORE_NONE: + break; + case TU_SEMAPHORE_SYNCOBJ: + drmSyncobjDestroy(device->physical_device->local_fd, part->syncobj); + break; + } + part->kind = TU_SEMAPHORE_NONE; +} + +static void +tu_semaphore_remove_temp(struct tu_device *device, + struct tu_semaphore *sem) +{ + if (sem->temporary.kind != TU_SEMAPHORE_NONE) { + tu_semaphore_part_destroy(device, &sem->temporary); + } +} + VkResult tu_CreateSemaphore(VkDevice _device, const VkSemaphoreCreateInfo *pCreateInfo, @@ -1945,6 +2079,21 @@ tu_CreateSemaphore(VkDevice _device, if (!sem) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + const VkExportSemaphoreCreateInfo *export = + vk_find_struct_const(pCreateInfo->pNext, EXPORT_SEMAPHORE_CREATE_INFO); + VkExternalSemaphoreHandleTypeFlags handleTypes = + export ? export->handleTypes : 0; + + sem->permanent.kind = TU_SEMAPHORE_NONE; + sem->temporary.kind = TU_SEMAPHORE_NONE; + + if (handleTypes) { + if (drmSyncobjCreate(device->physical_device->local_fd, 0, &sem->permanent.syncobj) < 0) { + vk_free2(&device->alloc, pAllocator, sem); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + sem->permanent.kind = TU_SEMAPHORE_SYNCOBJ; + } *pSemaphore = tu_semaphore_to_handle(sem); return VK_SUCCESS; } @@ -1959,6 +2108,9 @@ tu_DestroySemaphore(VkDevice _device, if (!_semaphore) return; + tu_semaphore_part_destroy(device, &sem->permanent); + tu_semaphore_part_destroy(device, &sem->temporary); + vk_free2(&device->alloc, pAllocator, sem); } @@ -2122,57 +2274,6 @@ tu_DestroyFramebuffer(VkDevice _device, vk_free2(&device->alloc, pAllocator, fb); } -static enum a6xx_tex_clamp -tu6_tex_wrap(VkSamplerAddressMode address_mode) -{ - switch (address_mode) { - case VK_SAMPLER_ADDRESS_MODE_REPEAT: - return A6XX_TEX_REPEAT; - case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: - return A6XX_TEX_MIRROR_REPEAT; - case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: - return A6XX_TEX_CLAMP_TO_EDGE; - case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: - return A6XX_TEX_CLAMP_TO_BORDER; - case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: - /* only works for PoT.. need to emulate otherwise! */ - return A6XX_TEX_MIRROR_CLAMP; - default: - unreachable("illegal tex wrap mode"); - break; - } -} - -static enum a6xx_tex_filter -tu6_tex_filter(VkFilter filter, unsigned aniso) -{ - switch (filter) { - case VK_FILTER_NEAREST: - return A6XX_TEX_NEAREST; - case VK_FILTER_LINEAR: - return aniso ? A6XX_TEX_ANISO : A6XX_TEX_LINEAR; - case VK_FILTER_CUBIC_EXT: - return A6XX_TEX_CUBIC; - default: - unreachable("illegal texture filter"); - break; - } -} - -static inline enum adreno_compare_func -tu6_compare_func(VkCompareOp op) -{ - return (enum adreno_compare_func) op; -} - -static inline enum a6xx_reduction_mode -tu6_reduction_mode(VkSamplerReductionMode reduction_mode) -{ - /* note: vulkan enum matches hw */ - - return (enum a6xx_reduction_mode) reduction_mode; -} - static void tu_init_sampler(struct tu_device *device, struct tu_sampler *sampler, @@ -2347,15 +2448,132 @@ tu_GetMemoryFdPropertiesKHR(VkDevice _device, return VK_SUCCESS; } +VkResult +tu_ImportSemaphoreFdKHR(VkDevice _device, + const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) +{ + TU_FROM_HANDLE(tu_device, device, _device); + TU_FROM_HANDLE(tu_semaphore, sem, pImportSemaphoreFdInfo->semaphore); + int ret; + struct tu_semaphore_part *dst = NULL; + + if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) { + dst = &sem->temporary; + } else { + dst = &sem->permanent; + } + + uint32_t syncobj = dst->kind == TU_SEMAPHORE_SYNCOBJ ? dst->syncobj : 0; + + switch(pImportSemaphoreFdInfo->handleType) { + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: { + uint32_t old_syncobj = syncobj; + ret = drmSyncobjFDToHandle(device->physical_device->local_fd, pImportSemaphoreFdInfo->fd, &syncobj); + if (ret == 0) { + close(pImportSemaphoreFdInfo->fd); + if (old_syncobj) + drmSyncobjDestroy(device->physical_device->local_fd, old_syncobj); + } + break; + } + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: { + if (!syncobj) { + ret = drmSyncobjCreate(device->physical_device->local_fd, 0, &syncobj); + if (ret) + break; + } + if (pImportSemaphoreFdInfo->fd == -1) { + ret = drmSyncobjSignal(device->physical_device->local_fd, &syncobj, 1); + } else { + ret = drmSyncobjImportSyncFile(device->physical_device->local_fd, syncobj, pImportSemaphoreFdInfo->fd); + } + if (!ret) + close(pImportSemaphoreFdInfo->fd); + break; + } + default: + unreachable("Unhandled semaphore handle type"); + } + + if (ret) { + return VK_ERROR_INVALID_EXTERNAL_HANDLE; + } + dst->syncobj = syncobj; + dst->kind = TU_SEMAPHORE_SYNCOBJ; + + return VK_SUCCESS; +} + +VkResult +tu_GetSemaphoreFdKHR(VkDevice _device, + const VkSemaphoreGetFdInfoKHR *pGetFdInfo, + int *pFd) +{ + TU_FROM_HANDLE(tu_device, device, _device); + TU_FROM_HANDLE(tu_semaphore, sem, pGetFdInfo->semaphore); + int ret; + uint32_t syncobj_handle; + + if (sem->temporary.kind != TU_SEMAPHORE_NONE) { + assert(sem->temporary.kind == TU_SEMAPHORE_SYNCOBJ); + syncobj_handle = sem->temporary.syncobj; + } else { + assert(sem->permanent.kind == TU_SEMAPHORE_SYNCOBJ); + syncobj_handle = sem->permanent.syncobj; + } + + switch(pGetFdInfo->handleType) { + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: + ret = drmSyncobjHandleToFD(device->physical_device->local_fd, syncobj_handle, pFd); + break; + case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: + ret = drmSyncobjExportSyncFile(device->physical_device->local_fd, syncobj_handle, pFd); + if (!ret) { + if (sem->temporary.kind != TU_SEMAPHORE_NONE) { + tu_semaphore_part_destroy(device, &sem->temporary); + } else { + drmSyncobjReset(device->physical_device->local_fd, &syncobj_handle, 1); + } + } + break; + default: + unreachable("Unhandled semaphore handle type"); + } + + if (ret) + return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE); + return VK_SUCCESS; +} + + +static bool tu_has_syncobj(struct tu_physical_device *pdev) +{ + uint64_t value; + if (drmGetCap(pdev->local_fd, DRM_CAP_SYNCOBJ, &value)) + return false; + return value && pdev->msm_major_version == 1 && pdev->msm_minor_version >= 6; +} + void tu_GetPhysicalDeviceExternalSemaphoreProperties( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties) { - pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0; - pExternalSemaphoreProperties->compatibleHandleTypes = 0; - pExternalSemaphoreProperties->externalSemaphoreFeatures = 0; + TU_FROM_HANDLE(tu_physical_device, pdev, physicalDevice); + + if (tu_has_syncobj(pdev) && + (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT || + pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) { + pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; + pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; + pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT; + } else { + pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0; + pExternalSemaphoreProperties->compatibleHandleTypes = 0; + pExternalSemaphoreProperties->externalSemaphoreFeatures = 0; + } } void