diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index facefe3918b..e659ceb3201 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -2088,12 +2088,9 @@ anv_descriptor_set_write_image_view(struct anv_device *device, device->physical, anv_image_view_storage_surface_state(image_view)->state), .image_depth = image_view->vk.storage.z_slice_count, - .image_address = (anv_image_is_sparse(image_view->image) ? - image_view->image->bindings[ - ANV_IMAGE_MEMORY_BINDING_MAIN].sparse_data.address : - anv_address_physical( - image_view->image->bindings[ - ANV_IMAGE_MEMORY_BINDING_MAIN].address)), + .image_address = anv_address_physical( + image_view->image->bindings[ + ANV_IMAGE_MEMORY_BINDING_MAIN].address), .tile_mode = image_view->image->planes[0].primary_surface.isl.tiling == ISL_TILING_LINEAR ? 0 : 0xffffffff, .row_pitch_B = image_view->image->planes[0].primary_surface.isl.row_pitch_B, .qpitch = image_view->image->planes[0].primary_surface.isl.array_pitch_el_rows, diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index f536a0d4a9d..b3d721303ab 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -1682,15 +1682,7 @@ anv_image_finish_sparse_bindings(struct anv_image *image) assert(anv_image_is_sparse(image)); - for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) { - struct anv_image_binding *b = &image->bindings[i]; - - if (b->sparse_data.size != 0) { - assert(b->memory_range.size == b->sparse_data.size); - assert(b->address.offset == b->sparse_data.address); - anv_free_sparse_bindings(device, &b->sparse_data); - } - } + anv_free_sparse_bindings(device, &image->sparse_data); } static VkResult MUST_CHECK @@ -1699,7 +1691,6 @@ anv_image_init_sparse_bindings(struct anv_image *image, { struct anv_device *device = container_of(image->vk.base.device, struct anv_device, vk); - VkResult result; assert(anv_image_is_sparse(image)); @@ -1715,51 +1706,35 @@ anv_image_init_sparse_bindings(struct anv_image *image, explicit_addresses = opaque_info->opaqueCaptureDescriptorData; } + uint64_t total_size = 0; for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) { struct anv_image_binding *b = &image->bindings[i]; + if (b->memory_range.size == 0) + continue; - if (b->memory_range.size != 0) { - assert(b->sparse_data.size == 0); + assert(b->memory_range.alignment == ANV_SPARSE_BLOCK_SIZE); + assert(b->memory_range.size % ANV_SPARSE_BLOCK_SIZE == 0); - uint64_t explicit_address = 0; - if (explicit_addresses) { - switch (i) { - case ANV_IMAGE_MEMORY_BINDING_MAIN: - explicit_address = explicit_addresses->planes[0]; - break; - case ANV_IMAGE_MEMORY_BINDING_PLANE_0: - case ANV_IMAGE_MEMORY_BINDING_PLANE_1: - case ANV_IMAGE_MEMORY_BINDING_PLANE_2: - explicit_address = explicit_addresses->planes[i - ANV_IMAGE_MEMORY_BINDING_PLANE_0]; - break; - case ANV_IMAGE_MEMORY_BINDING_PRIVATE: - explicit_address = explicit_addresses->private_binding; - break; - default: - UNREACHABLE("invalid binding"); - } - } + total_size = MAX2(total_size, + b->memory_range.offset + b->memory_range.size); + } - /* From the spec, Custom Sparse Image Block Shapes section: - * "... the size in bytes of the custom sparse image block shape - * will be reported in VkMemoryRequirements::alignment." - * - * ISL should have set this for us, so just assert it here. - */ - assert(b->memory_range.alignment == ANV_SPARSE_BLOCK_SIZE); - assert(b->memory_range.size % ANV_SPARSE_BLOCK_SIZE == 0); + struct anv_address base_address; + VkResult result = anv_init_sparse_bindings( + device, total_size, &image->sparse_data, alloc_flags, + explicit_addresses != NULL ? explicit_addresses->main_binding : 0, + &base_address); - result = anv_init_sparse_bindings(device, - b->memory_range.size, - &b->sparse_data, - alloc_flags, - explicit_address, - &b->address); - if (result != VK_SUCCESS) { - anv_image_finish_sparse_bindings(image); - return result; - } + if (result == VK_SUCCESS) { + for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) { + struct anv_image_binding *b = &image->bindings[i]; + if (b->memory_range.size == 0) + continue; + + b->address = anv_address_add(base_address, b->memory_range.offset); } + } else { + anv_image_finish_sparse_bindings(image); } return VK_SUCCESS; @@ -2353,28 +2328,11 @@ anv_GetImageOpaqueCaptureDescriptorDataEXT(VkDevice device, struct anv_image_opaque_capture_data *bound_addresses = pData; memset(bound_addresses, 0, sizeof(*bound_addresses)); - for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) { - struct anv_image_binding *b = &image->bindings[i]; - if (b->memory_range.size != 0) { - uint64_t addr = anv_address_physical(b->address); - switch (i) { - case ANV_IMAGE_MEMORY_BINDING_MAIN: - bound_addresses->planes[0] = addr; - break; - case ANV_IMAGE_MEMORY_BINDING_PLANE_0: - case ANV_IMAGE_MEMORY_BINDING_PLANE_1: - case ANV_IMAGE_MEMORY_BINDING_PLANE_2: - bound_addresses->planes[i - ANV_IMAGE_MEMORY_BINDING_PLANE_0] = addr; - break; - case ANV_IMAGE_MEMORY_BINDING_PRIVATE: - bound_addresses->private_binding = addr; - break; - default: - UNREACHABLE("invalid binding"); - } - } - } + bound_addresses->main_binding = + anv_address_physical(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address); + bound_addresses->private_binding = + anv_address_physical(image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].address); return VK_SUCCESS; } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 36d43c19ef3..8b0989cc6b5 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -5611,7 +5611,6 @@ struct anv_image { struct anv_image_binding { struct anv_image_memory_range memory_range; struct anv_address address; - struct anv_sparse_binding_data sparse_data; void *host_map; uint64_t map_delta; uint64_t map_size; @@ -5660,6 +5659,8 @@ struct anv_image { } aux_tt; } planes[3]; + struct anv_sparse_binding_data sparse_data; + /* Array pitch of video coding private surfaces */ uint32_t vid_dmv_top_surface_pitch_B; uint32_t av1_cdf_table_pitch_B; @@ -5674,7 +5675,7 @@ struct anv_image { }; struct anv_image_opaque_capture_data { - uint64_t planes[3]; + uint64_t main_binding; uint64_t private_binding; }; diff --git a/src/intel/vulkan/anv_rmv.c b/src/intel/vulkan/anv_rmv.c index 23131b32850..6f8ec5382df 100644 --- a/src/intel/vulkan/anv_rmv.c +++ b/src/intel/vulkan/anv_rmv.c @@ -474,17 +474,17 @@ anv_rmv_log_image_create(struct anv_device *device, vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &token); if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) { - if (image->bindings[b].sparse_data.size != 0) { + if (image->bindings[b].memory_range.size != 0) { anv_rmv_log_vma_locked(device, - image->bindings[b].sparse_data.address, - image->bindings[b].sparse_data.size, + anv_address_physical(image->bindings[b].address), + image->bindings[b].memory_range.size, false /* internal */, true /* TODO: vram */, true /* in_invisible_vram */); log_resource_bind_locked(device, resource_id_locked(device, image), NULL, - image->bindings[b].sparse_data.address, - image->bindings[b].sparse_data.size); + anv_address_physical(image->bindings[b].address), + image->bindings[b].memory_range.size); } } } @@ -498,9 +498,9 @@ anv_rmv_log_image_destroy(struct anv_device *device, simple_mtx_lock(&device->vk.memory_trace_data.token_mtx); if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) { - if (image->bindings[b].sparse_data.size != 0) { + if (image->bindings[b].memory_range.size != 0) { struct vk_rmv_virtual_free_token token = { - .address = image->bindings[b].sparse_data.address, + .address = anv_address_physical(image->bindings[b].address), }; vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_VIRTUAL_FREE, &token); diff --git a/src/intel/vulkan/anv_sparse.c b/src/intel/vulkan/anv_sparse.c index ac563969b6d..d3f7e32bc13 100644 --- a/src/intel/vulkan/anv_sparse.c +++ b/src/intel/vulkan/anv_sparse.c @@ -1349,11 +1349,12 @@ out_debug: static struct anv_vm_bind vk_bind_to_anv_vm_bind(struct anv_sparse_binding_data *sparse, + uint64_t binding_offset, const struct VkSparseMemoryBind *vk_bind) { struct anv_vm_bind anv_bind = { .bo = NULL, - .address = sparse->address + vk_bind->resourceOffset, + .address = sparse->address + binding_offset + vk_bind->resourceOffset, .bo_offset = 0, .size = vk_bind->size, .op = ANV_VM_BIND, @@ -1378,7 +1379,7 @@ anv_sparse_bind_resource_memory(struct anv_device *device, const VkSparseMemoryBind *vk_bind, struct anv_sparse_submission *submit) { - struct anv_vm_bind bind = vk_bind_to_anv_vm_bind(sparse, vk_bind); + struct anv_vm_bind bind = vk_bind_to_anv_vm_bind(sparse, 0, vk_bind); uint64_t rem = vk_bind->size % ANV_SPARSE_BLOCK_SIZE; if (rem != 0) { @@ -1425,7 +1426,7 @@ anv_sparse_bind_image_opaque(struct anv_device *device, sparse_debug("\n"); } - return anv_sparse_bind_resource_memory(device, &b->sparse_data, + return anv_sparse_bind_resource_memory(device, &image->sparse_data, b->memory_range.size, vk_bind, submit); } @@ -1446,7 +1447,7 @@ anv_sparse_bind_image_memory(struct anv_queue *queue, struct anv_image_binding *img_binding = image->disjoint ? &image->bindings[anv_image_aspect_to_binding(image, aspect)] : &image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN]; - struct anv_sparse_binding_data *sparse_data = &img_binding->sparse_data; + struct anv_sparse_binding_data *sparse_data = &image->sparse_data; const uint32_t plane = anv_image_aspect_to_plane(image, aspect); struct isl_surf *surf = &image->planes[plane].primary_surface.isl; @@ -1547,8 +1548,8 @@ anv_sparse_bind_image_memory(struct anv_queue *queue, assert(opaque_bind.resourceOffset % ANV_SPARSE_BLOCK_SIZE == 0); assert(opaque_bind.size % ANV_SPARSE_BLOCK_SIZE == 0); - struct anv_vm_bind anv_bind = vk_bind_to_anv_vm_bind(sparse_data, - &opaque_bind); + struct anv_vm_bind anv_bind = vk_bind_to_anv_vm_bind( + sparse_data, img_binding->memory_range.offset, &opaque_bind); VkResult result = anv_sparse_submission_add(device, submit, &anv_bind); if (result != VK_SUCCESS)