anv: shrink image opaque data

Noticed renderdoc complaining about our size :

RDOC 692028: [18:08:18]          vk_core.cpp(2272) - Warning -
VkPhysicalDeviceDescriptorBufferPropertiesEXT.imageCaptureReplayDescriptorDataSizeis too large at 32
(must be <= 16), can't support capture of VK_EXT_descriptor_buffer

Since we only need 2 pointers (main + private), we can shrink this to
16bytes. The 1/2 planes have a relative offset from the base.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38625>
This commit is contained in:
Lionel Landwerlin 2025-11-24 18:29:49 +02:00 committed by Marge Bot
parent 6aabc3d5d2
commit b1e74a1bb1
5 changed files with 47 additions and 90 deletions

View file

@ -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,

View file

@ -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;
}

View file

@ -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;
};

View file

@ -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);

View file

@ -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)