From 27a24cb3825d8c6dbde9485999dcb2619e85faf0 Mon Sep 17 00:00:00 2001 From: Benjamin Cheng Date: Fri, 6 May 2022 15:54:18 -0400 Subject: [PATCH] radv: implement disjoint memory for multiplane images For descriptor binding, we need to allow up to three buffers to be referenced by any image. Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 14 ++++++++++- src/amd/vulkan/radv_descriptor_set.c | 37 ++++++++++++++++++++-------- src/amd/vulkan/radv_device.c | 30 +++++++++++++++++++--- src/amd/vulkan/radv_image.c | 6 +++-- src/amd/vulkan/radv_private.h | 1 + 5 files changed, 72 insertions(+), 16 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index a46c0b3b587..f0622e10b40 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -2761,7 +2761,19 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer) radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, iview->image->bindings[0].bo); assert(iview->vk.aspects & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT | - VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)); + VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)); + + if (iview->image->disjoint && iview->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT) { + for (uint32_t plane_id = 0; plane_id < iview->image->plane_count; plane_id++) { + radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, + iview->image->bindings[plane_id].bo); + } + } else { + uint32_t plane_id = iview->image->disjoint ? iview->plane_id : 0; + radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, + iview->image->bindings[plane_id].bo); + } + radv_emit_fb_color_state(cmd_buffer, i, &cmd_buffer->state.attachments[idx].cb, iview, layout, in_render_loop); diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c index 393939172aa..d71de46003d 100644 --- a/src/amd/vulkan/radv_descriptor_set.c +++ b/src/amd/vulkan/radv_descriptor_set.c @@ -41,6 +41,12 @@ radv_descriptor_type_buffer_count(VkDescriptorType type) case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: return 0; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: + return 3; default: return 1; } @@ -1166,10 +1172,17 @@ write_image_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_b memcpy(dst, descriptor, size); - if (cmd_buffer) - radv_cs_add_buffer(device->ws, cmd_buffer->cs, iview->image->bindings[0].bo); - else - *buffer_list = iview->image->bindings[0].bo; + const uint32_t max_bindings = sizeof(iview->image->bindings) / + sizeof(iview->image->bindings[0]); + for (uint32_t b = 0; b < max_bindings; b++) { + if (cmd_buffer) { + if (iview->image->bindings[b].bo) + radv_cs_add_buffer(device->ws, cmd_buffer->cs, iview->image->bindings[b].bo); + } else { + *buffer_list = iview->image->bindings[b].bo; + buffer_list++; + } + } } static ALWAYS_INLINE void @@ -1364,13 +1377,17 @@ radv_update_descriptor_sets_impl(struct radv_device *device, struct radv_cmd_buf src_ptr += src_binding_layout->size / 4; dst_ptr += dst_binding_layout->size / 4; - if (src_binding_layout->type != VK_DESCRIPTOR_TYPE_SAMPLER && - dst_binding_layout->type != VK_DESCRIPTOR_TYPE_SAMPLER && - src_binding_layout->type != VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR && - dst_binding_layout->type != VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) { - /* Sampler/acceleration structure descriptors don't have a buffer list. */ - dst_buffer_list[j] = src_buffer_list[j]; + unsigned src_buffer_count = radv_descriptor_type_buffer_count(src_binding_layout->type); + unsigned dst_buffer_count = radv_descriptor_type_buffer_count(dst_binding_layout->type); + for (unsigned k = 0; k < dst_buffer_count; k++) { + if (k < src_buffer_count) + dst_buffer_list[k] = src_buffer_list[k]; + else + dst_buffer_list[k] = NULL; } + + dst_buffer_list += dst_buffer_count; + src_buffer_list += src_buffer_count; } } } diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 54ee6dc775c..3bbeef44749 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -5870,8 +5870,30 @@ radv_BindImageMemory2(VkDevice _device, uint32_t bindInfoCount, } } - image->bindings[0].bo = mem->bo; - image->bindings[0].offset = pBindInfos[i].memoryOffset; + if (image->disjoint) { + const VkBindImagePlaneMemoryInfo *plane_info = + vk_find_struct_const(pBindInfos[i].pNext, BIND_IMAGE_PLANE_MEMORY_INFO); + + switch (plane_info->planeAspect) { + case VK_IMAGE_ASPECT_PLANE_0_BIT: + image->bindings[0].bo = mem->bo; + image->bindings[0].offset = pBindInfos[i].memoryOffset; + break; + case VK_IMAGE_ASPECT_PLANE_1_BIT: + image->bindings[1].bo = mem->bo; + image->bindings[1].offset = pBindInfos[i].memoryOffset; + break; + case VK_IMAGE_ASPECT_PLANE_2_BIT: + image->bindings[2].bo = mem->bo; + image->bindings[2].offset = pBindInfos[i].memoryOffset; + break; + default: + break; + } + } else { + image->bindings[0].bo = mem->bo; + image->bindings[0].offset = pBindInfos[i].memoryOffset; + } } return VK_SUCCESS; } @@ -6209,7 +6231,9 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff else cb->cb_color_attrib = S_028C74_FORCE_DST_ALPHA_1_GFX6(desc->swizzle[3] == PIPE_SWIZZLE_1); - va = radv_buffer_get_va(iview->image->bindings[0].bo) + iview->image->bindings[0].offset; + uint32_t plane_id = iview->image->disjoint ? iview->plane_id : 0; + va = radv_buffer_get_va(iview->image->bindings[plane_id].bo) + + iview->image->bindings[plane_id].offset; cb->cb_color_base = va >> 8; diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 51ce6c53571..487d1cf059c 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -766,7 +766,7 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image *im bool enable_write_compression, uint32_t *state) { struct radv_image_plane *plane = &image->planes[plane_id]; - struct radv_image_binding *binding = &image->bindings[0]; + struct radv_image_binding *binding = image->disjoint ? &image->bindings[plane_id] : &image->bindings[0]; uint64_t gpu_address = binding->bo ? radv_buffer_get_va(binding->bo) + binding->offset : 0; uint64_t va = gpu_address; enum amd_gfx_level gfx_level = device->physical_device->rad_info.gfx_level; @@ -1684,7 +1684,8 @@ radv_image_create_layout(struct radv_device *device, struct radv_image_create_in offset = mod_info->pPlaneLayouts[plane].offset; stride = mod_info->pPlaneLayouts[plane].rowPitch / image->planes[plane].surface.bpe; } else { - offset = align64(image->size, 1 << image->planes[plane].surface.alignment_log2); + offset = image->disjoint ? 0 : + align64(image->size, 1 << image->planes[plane].surface.alignment_log2); stride = 0; /* 0 means no override */ } @@ -1850,6 +1851,7 @@ radv_image_create(VkDevice _device, const struct radv_image_create_info *create_ image->info.num_channels = vk_format_get_nr_components(format); image->plane_count = vk_format_get_plane_count(format); + image->disjoint = image->plane_count > 1 && pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT; image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE; if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) { diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 77122242d44..f2b1fbf7a04 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -2412,6 +2412,7 @@ struct radv_image { VkDeviceMemory owned_memory; unsigned plane_count; + bool disjoint; struct radv_image_plane planes[0]; };