Mesa (master): radv: Add sparse image queries.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Jan 11 12:20:21 UTC 2021
Module: Mesa
Branch: master
Commit: af7fb4df50fa216bc0332ec48001e67e97cacbd9
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=af7fb4df50fa216bc0332ec48001e67e97cacbd9
Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date: Sun Dec 6 21:42:35 2020 +0100
radv: Add sparse image queries.
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7953>
---
src/amd/vulkan/radv_device.c | 18 -----
src/amd/vulkan/radv_formats.c | 178 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 169 insertions(+), 27 deletions(-)
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 2dc59e04746..6a7cb1cb4e8 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -5690,24 +5690,6 @@ void radv_GetImageMemoryRequirements2(
}
}
-void radv_GetImageSparseMemoryRequirements(
- VkDevice device,
- VkImage image,
- uint32_t* pSparseMemoryRequirementCount,
- VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
-{
- stub();
-}
-
-void radv_GetImageSparseMemoryRequirements2(
- VkDevice device,
- const VkImageSparseMemoryRequirementsInfo2 *pInfo,
- uint32_t* pSparseMemoryRequirementCount,
- VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
-{
- stub();
-}
-
void radv_GetDeviceMemoryCommitment(
VkDevice device,
VkDeviceMemory memory,
diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c
index 63dd6c55056..79f9ea5b7f6 100644
--- a/src/amd/vulkan/radv_formats.c
+++ b/src/amd/vulkan/radv_formats.c
@@ -1283,6 +1283,13 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
goto unsupported;
}
+ if (info->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) {
+ if (desc->plane_count > 1 || info->type != VK_IMAGE_TYPE_2D ||
+ info->tiling != VK_IMAGE_TILING_OPTIMAL ||
+ vk_format_is_depth_or_stencil(format))
+ goto unsupported;
+ }
+
*pImageFormatProperties = (VkImageFormatProperties) {
.maxExtent = maxExtent,
.maxMipLevels = maxMipLevels,
@@ -1512,6 +1519,66 @@ fail:
return result;
}
+static void fill_sparse_image_format_properties(struct radv_physical_device *pdev,
+ VkFormat format,
+ VkSparseImageFormatProperties *prop)
+{
+ prop->aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ prop->flags = 0;
+
+ /* On GFX8 we first subdivide by level and then layer, leading to a single
+ * miptail. On GFX9+ we first subdivide by layer and then level which results
+ * in a miptail per layer. */
+ if (pdev->rad_info.chip_class < GFX9)
+ prop->flags |= VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT;
+
+ /* This assumes the sparse image tile size is always 64 KiB (1 << 16) */
+ unsigned l2_size = 16 - util_logbase2(vk_format_get_blocksize(format));
+ unsigned w = (1u << ((l2_size + 1) / 2)) * vk_format_get_blockwidth(format);
+ unsigned h = (1u << (l2_size / 2)) * vk_format_get_blockheight(format);
+
+ prop->imageGranularity = (VkExtent3D) {w, h, 1};
+}
+
+void radv_GetPhysicalDeviceSparseImageFormatProperties2(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
+ uint32_t *pPropertyCount,
+ VkSparseImageFormatProperties2 *pProperties)
+{
+ RADV_FROM_HANDLE(radv_physical_device, pdev, physicalDevice);
+ VkResult result;
+
+ if (pFormatInfo->samples > VK_SAMPLE_COUNT_1_BIT) {
+ *pPropertyCount = 0;
+ return;
+ }
+
+ const VkPhysicalDeviceImageFormatInfo2 fmt_info = {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
+ .format = pFormatInfo->format,
+ .type = pFormatInfo->type,
+ .tiling = pFormatInfo->tiling,
+ .usage = pFormatInfo->usage,
+ .flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT |
+ VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
+ };
+
+ VkImageFormatProperties fmt_props;
+ result = radv_get_image_format_properties(pdev, &fmt_info, pFormatInfo->format,
+ &fmt_props);
+ if (result != VK_SUCCESS) {
+ *pPropertyCount = 0;
+ return;
+ }
+
+ VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
+
+ vk_outarray_append(&out, prop) {
+ fill_sparse_image_format_properties(pdev, pFormatInfo->format, &prop->properties);
+ };
+}
+
void radv_GetPhysicalDeviceSparseImageFormatProperties(
VkPhysicalDevice physicalDevice,
VkFormat format,
@@ -1522,18 +1589,111 @@ void radv_GetPhysicalDeviceSparseImageFormatProperties(
uint32_t* pNumProperties,
VkSparseImageFormatProperties* pProperties)
{
- /* Sparse images are not yet supported. */
- *pNumProperties = 0;
+ const VkPhysicalDeviceSparseImageFormatInfo2 info = {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
+ .format = format,
+ .type = type,
+ .samples = samples,
+ .usage = usage,
+ .tiling = tiling
+ };
+
+ if (!pProperties) {
+ radv_GetPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &info,
+ pNumProperties, NULL);
+ return;
+ }
+
+ VkSparseImageFormatProperties2 props[4];
+ uint32_t prop_cnt = MIN2(ARRAY_SIZE(props), *pNumProperties);
+
+ memset(props, 0, sizeof(props));
+ for (unsigned i = 0; i < ARRAY_SIZE(props); ++i)
+ props[i].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
+
+ radv_GetPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &info,
+ &prop_cnt, props);
+
+ for (unsigned i = 0; i < prop_cnt; ++i)
+ pProperties[i] = props[i].properties;
+ *pNumProperties = prop_cnt;
+}
+
+void radv_GetImageSparseMemoryRequirements2(
+ VkDevice _device,
+ const VkImageSparseMemoryRequirementsInfo2 *pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+ RADV_FROM_HANDLE(radv_image, image, pInfo->image);
+
+ if (!(image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
+ *pSparseMemoryRequirementCount = 0;
+ return;
+ }
+
+ VK_OUTARRAY_MAKE(out, pSparseMemoryRequirements, pSparseMemoryRequirementCount);
+
+ vk_outarray_append(&out, req) {
+ fill_sparse_image_format_properties(device->physical_device,
+ image->vk_format,
+ &req->memoryRequirements.formatProperties);
+ req->memoryRequirements.imageMipTailFirstLod = image->planes[0].surface.first_mip_tail_level;
+
+ if (req->memoryRequirements.imageMipTailFirstLod < image->info.levels) {
+ if (device->physical_device->rad_info.chip_class >= GFX9) {
+ /* The tail is always a single tile per layer. */
+ req->memoryRequirements.imageMipTailSize = 65536;
+ req->memoryRequirements.imageMipTailOffset =
+ image->planes[0].surface.u.gfx9.prt_level_offset[req->memoryRequirements.imageMipTailFirstLod] & ~65535;
+ req->memoryRequirements.imageMipTailStride =
+ image->planes[0].surface.u.gfx9.surf_slice_size;
+ } else {
+ req->memoryRequirements.imageMipTailOffset =
+ image->planes[0].surface.u.legacy.level[req->memoryRequirements.imageMipTailFirstLod ].offset;
+ req->memoryRequirements.imageMipTailSize =
+ image->size - req->memoryRequirements.imageMipTailOffset;
+ req->memoryRequirements.imageMipTailStride = 0;
+ }
+ } else {
+ req->memoryRequirements.imageMipTailSize = 0;
+ req->memoryRequirements.imageMipTailOffset = 0;
+ req->memoryRequirements.imageMipTailStride = 0;
+ }
+ };
}
-void radv_GetPhysicalDeviceSparseImageFormatProperties2(
- VkPhysicalDevice physicalDevice,
- const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
- uint32_t *pPropertyCount,
- VkSparseImageFormatProperties2 *pProperties)
+void radv_GetImageSparseMemoryRequirements(
+ VkDevice device,
+ VkImage image,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
{
- /* Sparse images are not yet supported. */
- *pPropertyCount = 0;
+ const VkImageSparseMemoryRequirementsInfo2 info = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
+ .image = image
+ };
+
+ if (!pSparseMemoryRequirements) {
+ radv_GetImageSparseMemoryRequirements2(device, &info,
+ pSparseMemoryRequirementCount, NULL);
+ return;
+ }
+
+ VkSparseImageMemoryRequirements2 reqs[4];
+ uint32_t reqs_cnt = MIN2(ARRAY_SIZE(reqs), *pSparseMemoryRequirementCount);
+
+ memset(reqs, 0, sizeof(reqs));
+ for (unsigned i = 0; i < ARRAY_SIZE(reqs); ++i)
+ reqs[i].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2;
+
+ radv_GetImageSparseMemoryRequirements2(device, &info,
+ &reqs_cnt, reqs);
+
+ for (unsigned i = 0; i < reqs_cnt; ++i)
+ pSparseMemoryRequirements[i] = reqs[i].memoryRequirements;
+ *pSparseMemoryRequirementCount = reqs_cnt;
}
void radv_GetPhysicalDeviceExternalBufferProperties(
More information about the mesa-commit
mailing list