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 <apinheiro@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10970>
This commit is contained in:
parent
f7ce44b6e5
commit
6a847cbe1d
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue