From ddc4069122168feb34d4a272a6ef90ba1b4a07db Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 5 Oct 2017 16:03:29 -0700 Subject: [PATCH] anv: Implement VK_KHR_maintenance3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Samuel Iglesias Gonsálvez --- src/intel/vulkan/anv_descriptor_set.c | 45 +++++++++++++++++++++++++++ src/intel/vulkan/anv_device.c | 30 +++++++----------- src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_private.h | 19 +++++++++++ 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index c1293766989..2a3c496a9f8 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -35,6 +35,51 @@ * Descriptor set layouts. */ +void anv_GetDescriptorSetLayoutSupport( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + VkDescriptorSetLayoutSupport* pSupport) +{ + uint32_t surface_count[MESA_SHADER_STAGES] = { 0, }; + + for (uint32_t b = 0; b <= pCreateInfo->bindingCount; b++) { + const VkDescriptorSetLayoutBinding *binding = &pCreateInfo->pBindings[b]; + + switch (binding->descriptorType) { + case VK_DESCRIPTOR_TYPE_SAMPLER: + /* There is no real limit on samplers */ + break; + + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + if (binding->pImmutableSamplers) { + for (uint32_t i = 0; i < binding->descriptorCount; i++) { + ANV_FROM_HANDLE(anv_sampler, sampler, + binding->pImmutableSamplers[i]); + anv_foreach_stage(s, binding->stageFlags) + surface_count[s] += sampler->n_planes; + } + } + break; + + default: + anv_foreach_stage(s, binding->stageFlags) + surface_count[s] += binding->descriptorCount; + break; + } + } + + bool supported = true; + for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) { + /* Our maximum binding table size is 250 and we need to reserve 8 for + * render targets. 240 is a nice round number. + */ + if (surface_count[s] >= 240) + supported = false; + } + + pSupport->supported = supported; +} + VkResult anv_CreateDescriptorSetLayout( VkDevice _device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 5d74b5fb55c..7b3ccc01ddc 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -990,6 +990,17 @@ void anv_GetPhysicalDeviceProperties2( break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: { + VkPhysicalDeviceMaintenance3Properties *props = + (VkPhysicalDeviceMaintenance3Properties *)ext; + /* This value doesn't matter for us today as our per-stage + * descriptors are the real limit. + */ + props->maxPerSetDescriptors = 1024; + props->maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: { VkPhysicalDeviceMultiviewProperties *properties = (VkPhysicalDeviceMultiviewProperties *)ext; @@ -1800,24 +1811,7 @@ VkResult anv_AllocateMemory( /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */ assert(pAllocateInfo->allocationSize > 0); - /* The kernel relocation API has a limitation of a 32-bit delta value - * applied to the address before it is written which, in spite of it being - * unsigned, is treated as signed . Because of the way that this maps to - * the Vulkan API, we cannot handle an offset into a buffer that does not - * fit into a signed 32 bits. The only mechanism we have for dealing with - * this at the moment is to limit all VkDeviceMemory objects to a maximum - * of 2GB each. The Vulkan spec allows us to do this: - * - * "Some platforms may have a limit on the maximum size of a single - * allocation. For example, certain systems may fail to create - * allocations with a size greater than or equal to 4GB. Such a limit is - * implementation-dependent, and if such a failure occurs then the error - * VK_ERROR_OUT_OF_DEVICE_MEMORY should be returned." - * - * We don't use vk_error here because it's not an error so much as an - * indication to the application that the allocation is too large. - */ - if (pAllocateInfo->allocationSize > (1ull << 31)) + if (pAllocateInfo->allocationSize > MAX_MEMORY_ALLOCATION_SIZE) return VK_ERROR_OUT_OF_DEVICE_MEMORY; /* FINISHME: Fail if allocation request exceeds heap size. */ diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py index ca5100fc5e5..df168dc9848 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -88,6 +88,7 @@ EXTENSIONS = [ Extension('VK_KHR_incremental_present', 1, 'ANV_HAS_SURFACE'), Extension('VK_KHR_maintenance1', 1, True), Extension('VK_KHR_maintenance2', 1, True), + Extension('VK_KHR_maintenance3', 1, True), Extension('VK_KHR_push_descriptor', 1, True), Extension('VK_KHR_relaxed_block_layout', 1, True), Extension('VK_KHR_sampler_mirror_clamp_to_edge', 1, True), diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 55bdf365014..5e384940181 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -104,6 +104,25 @@ struct gen_l3_config; #define MAX_IMAGES 8 #define MAX_PUSH_DESCRIPTORS 32 /* Minimum requirement */ +/* The kernel relocation API has a limitation of a 32-bit delta value + * applied to the address before it is written which, in spite of it being + * unsigned, is treated as signed . Because of the way that this maps to + * the Vulkan API, we cannot handle an offset into a buffer that does not + * fit into a signed 32 bits. The only mechanism we have for dealing with + * this at the moment is to limit all VkDeviceMemory objects to a maximum + * of 2GB each. The Vulkan spec allows us to do this: + * + * "Some platforms may have a limit on the maximum size of a single + * allocation. For example, certain systems may fail to create + * allocations with a size greater than or equal to 4GB. Such a limit is + * implementation-dependent, and if such a failure occurs then the error + * VK_ERROR_OUT_OF_DEVICE_MEMORY should be returned." + * + * We don't use vk_error here because it's not an error so much as an + * indication to the application that the allocation is too large. + */ +#define MAX_MEMORY_ALLOCATION_SIZE (1ull << 31) + #define ANV_SVGS_VB_INDEX MAX_VBS #define ANV_DRAWID_VB_INDEX (MAX_VBS + 1)