From: Iago Toral Quiroga Date: Tue, 25 May 2021 08:49:06 +0000 (+0200) Subject: v3dv: implement VK_KHR_maintenance3 X-Git-Tag: upstream/21.2.3~2911 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6a847cbe1d74010a1214591e8d0963db82bd93db;p=platform%2Fupstream%2Fmesa.git v3dv: implement VK_KHR_maintenance3 We don't have any special restrictions associated with the number of descriptors in a set other than maybe not exceeding what we can put in a single memory allocation, so in practice, applications will be limited by the per-stage contraints defined by other Vulkan limits. Reviewed-by: Alejandro PiƱeiro Part-of: --- diff --git a/docs/features.txt b/docs/features.txt index 28eb5ac..9a50e06 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -437,7 +437,7 @@ Vulkan 1.1 -- all DONE: anv, lvp, radv, tu, vn VK_KHR_get_physical_device_properties2 DONE (anv, lvp, radv, tu, v3dv, vn) VK_KHR_maintenance1 DONE (anv, lvp, radv, tu, v3dv, vn) VK_KHR_maintenance2 DONE (anv, lvp, radv, tu, v3dv, vn) - VK_KHR_maintenance3 DONE (anv, lvp, radv, tu, vn) + VK_KHR_maintenance3 DONE (anv, lvp, radv, tu, v3dv, vn) VK_KHR_multiview DONE (anv, lvp, radv, tu, vn) VK_KHR_relaxed_block_layout DONE (anv, lvp, radv, tu, vn) VK_KHR_sampler_ycbcr_conversion DONE (anv, radv, tu, vn) diff --git a/src/broadcom/vulkan/v3dv_descriptor_set.c b/src/broadcom/vulkan/v3dv_descriptor_set.c index 3487d70..72a0683 100644 --- a/src/broadcom/vulkan/v3dv_descriptor_set.c +++ b/src/broadcom/vulkan/v3dv_descriptor_set.c @@ -49,6 +49,14 @@ descriptor_bo_size(VkDescriptorType type) } } +uint32_t +v3dv_max_descriptor_bo_size() +{ + return MAX3(sizeof(struct v3dv_sampler_descriptor), + sizeof(struct v3dv_combined_image_sampler_descriptor), + sizeof(struct v3dv_sampled_image_descriptor)); +} + /* * For a given descriptor defined by the descriptor_set it belongs, its * binding layout, and array_index, it returns the map region assigned to it @@ -1096,3 +1104,46 @@ v3dv_UpdateDescriptorSets(VkDevice _device, } } } + +void +v3dv_GetDescriptorSetLayoutSupport( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo *pCreateInfo, + VkDescriptorSetLayoutSupport *pSupport) +{ + VkDescriptorSetLayoutBinding *bindings = NULL; + VkResult result = vk_create_sorted_bindings( + pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings); + if (result != VK_SUCCESS) { + pSupport->supported = false; + return; + } + + bool supported = true; + + uint32_t desc_host_size = sizeof(struct v3dv_descriptor); + uint32_t host_size = sizeof(struct v3dv_descriptor_set); + uint32_t bo_size = 0; + for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { + const VkDescriptorSetLayoutBinding *binding = bindings + i; + + if ((UINT32_MAX - host_size) / desc_host_size < binding->descriptorCount) { + supported = false; + break; + } + + uint32_t desc_bo_size = descriptor_bo_size(binding->descriptorType); + if (desc_bo_size > 0 && + (UINT32_MAX - bo_size) / desc_bo_size < binding->descriptorCount) { + supported = false; + break; + } + + host_size += binding->descriptorCount * desc_host_size; + bo_size += binding->descriptorCount * desc_bo_size; + } + + free(bindings); + + pSupport->supported = supported; +} diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 338b2df..ff758ad 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -134,6 +134,7 @@ get_device_extensions(const struct v3dv_physical_device *device, .KHR_external_memory_fd = true, .KHR_maintenance1 = true, .KHR_maintenance2 = true, + .KHR_maintenance3 = true, #ifdef V3DV_HAS_SURFACE .KHR_swapchain = true, #endif @@ -1250,6 +1251,29 @@ v3dv_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: { + VkPhysicalDeviceMaintenance3Properties *props = + (VkPhysicalDeviceMaintenance3Properties *)ext; + /* We don't really have special restrictions for the maximum + * descriptors per set, other than maybe not exceeding the limits + * of addressable memory in a single allocation on either the host + * or the GPU. This will be a much larger limit than any of the + * per-stage limits already available in Vulkan though, so in practice, + * it is not expected to limit anything beyond what is already + * constrained through per-stage limits. + */ + uint32_t max_host_descriptors = + (UINT32_MAX - sizeof(struct v3dv_descriptor_set)) / + sizeof(struct v3dv_descriptor); + uint32_t max_gpu_descriptors = + (UINT32_MAX / v3dv_max_descriptor_bo_size()); + props->maxPerSetDescriptors = + MIN2(max_host_descriptors, max_gpu_descriptors); + + /* Minimum required by the spec */ + props->maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE; + break; + } default: v3dv_debug_ignored_stype(ext->sType); break; @@ -1586,8 +1610,7 @@ device_alloc(struct v3dv_device *device, VkDeviceSize size) { /* Our kernel interface is 32-bit */ - if (size > UINT32_MAX) - return VK_ERROR_OUT_OF_DEVICE_MEMORY; + assert(size <= UINT32_MAX); mem->bo = v3dv_bo_alloc(device, size, "device_alloc", false); if (!mem->bo) @@ -1828,20 +1851,28 @@ v3dv_AllocateMemory(VkDevice _device, } VkResult result = VK_SUCCESS; - if (wsi_info) { - result = device_alloc_for_wsi(device, pAllocator, mem, - pAllocateInfo->allocationSize); - } else if (fd_info && fd_info->handleType) { - assert(fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT || - fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); - result = device_import_bo(device, pAllocator, - fd_info->fd, pAllocateInfo->allocationSize, - &mem->bo); - mem->has_bo_ownership = false; - if (result == VK_SUCCESS) - close(fd_info->fd); + + /* We always allocate device memory in multiples of a page, so round up + * requested size to that. + */ + VkDeviceSize alloc_size = ALIGN(pAllocateInfo->allocationSize, 4096); + + if (unlikely(alloc_size > MAX_MEMORY_ALLOCATION_SIZE)) { + result = VK_ERROR_OUT_OF_DEVICE_MEMORY; } else { - result = device_alloc(device, mem, pAllocateInfo->allocationSize); + if (wsi_info) { + result = device_alloc_for_wsi(device, pAllocator, mem, alloc_size); + } else if (fd_info && fd_info->handleType) { + assert(fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT || + fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); + result = device_import_bo(device, pAllocator, + fd_info->fd, alloc_size, &mem->bo); + mem->has_bo_ownership = false; + if (result == VK_SUCCESS) + close(fd_info->fd); + } else { + result = device_alloc(device, mem, alloc_size); + } } if (result != VK_SUCCESS) { diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 852febe..90a1420 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -124,6 +124,9 @@ struct v3dv_instance; struct v3d_simulator_file; +/* Minimum required by the Vulkan 1.1 spec */ +#define MAX_MEMORY_ALLOCATION_SIZE (1ull << 30) + struct v3dv_physical_device { struct vk_physical_device vk; @@ -1516,6 +1519,8 @@ struct v3dv_descriptor_set { struct v3dv_descriptor descriptors[0]; }; +uint32_t v3dv_max_descriptor_bo_size(void); + struct v3dv_descriptor_set_binding_layout { VkDescriptorType type;