zink: batch sparse texture binds

do 10 binds per submit now (4 is enough for cts but yolo)

Acked-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14381>
This commit is contained in:
Mike Blumenkrantz 2022-01-12 15:27:17 -05:00 committed by Marge Bot
parent 30bd4ff72e
commit 7e03554af0
1 changed files with 67 additions and 62 deletions

View File

@ -827,26 +827,16 @@ out:
}
static bool
texture_commit_single(struct zink_screen *screen, struct zink_resource *res, struct zink_bo *bo,
VkImageSubresource *subresource, VkOffset3D *offset, VkExtent3D *extents, bool commit)
texture_commit_single(struct zink_screen *screen, struct zink_resource *res, VkSparseImageMemoryBind *ibind, unsigned num_binds, bool commit)
{
VkBindSparseInfo sparse = {0};
sparse.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
sparse.imageBindCount = 1;
VkSparseImageMemoryBindInfo sparse_ibind;
VkSparseImageMemoryBind ibind;
/* TODO: msaa needs miptail */
//VkSparseImageOpaqueMemoryBindInfo sparse_obind;
ibind.subresource = *subresource;
ibind.offset = *offset;
ibind.extent = *extents;
ibind.memory = commit ? (bo->mem ? bo->mem : bo->u.slab.real->mem) : VK_NULL_HANDLE;
ibind.memoryOffset = commit ? (bo->mem ? 0 : bo->offset) : 0;
ibind.flags = 0;
sparse_ibind.image = res->obj->image;
sparse_ibind.bindCount = 1;
sparse_ibind.pBinds = &ibind;
sparse_ibind.bindCount = num_binds;
sparse_ibind.pBinds = ibind;
sparse.pImageBinds = &sparse_ibind;
VkQueue queue = screen->threaded ? screen->thread_queue : screen->queue;
@ -887,25 +877,31 @@ zink_bo_commit(struct zink_screen *screen, struct zink_resource *res, unsigned l
(box->height % gheight) ? box->height % gheight : gheight,
(box->depth % gdepth) ? box->depth % gdepth : gdepth
};
/* TODO: msaa needs miptail */
//VkSparseImageOpaqueMemoryBindInfo sparse_obind;
VkSparseImageMemoryBind ibind[10];
uint32_t backing_start[10], backing_size[10];
struct zink_sparse_backing *backing[10];
unsigned i = 0;
bool commits_pending = false;
for (unsigned d = 0; d < ndepth; d++) {
for (unsigned h = 0; h < nheight; h++) {
for (unsigned w = 0; w < nwidth; w++) {
ibind[i].subresource = subresource;
ibind[i].flags = 0;
// Offset
VkOffset3D off;
off.x = w * gwidth;
off.y = h * gheight;
ibind[i].offset.x = w * gwidth;
ibind[i].offset.y = h * gheight;
if (res->base.b.target == PIPE_TEXTURE_CUBE) {
subresource.arrayLayer = d * gdepth;
off.z = 0;
ibind[i].subresource.arrayLayer = d * gdepth;
ibind[i].offset.z = 0;
} else {
off.z = d * gdepth;
ibind[i].offset.z = d * gdepth;
}
// Size of the page
VkExtent3D extent;
extent.width = (w == nwidth - 1) ? lastBlockExtent.width : gwidth;
extent.height = (h == nheight - 1) ? lastBlockExtent.height : gheight;
extent.depth = (d == ndepth - 1 && res->base.b.target != PIPE_TEXTURE_CUBE) ? lastBlockExtent.depth : gdepth;
ibind[i].extent.width = (w == nwidth - 1) ? lastBlockExtent.width : gwidth;
ibind[i].extent.height = (h == nheight - 1) ? lastBlockExtent.height : gheight;
ibind[i].extent.depth = (d == ndepth - 1 && res->base.b.target != PIPE_TEXTURE_CUBE) ? lastBlockExtent.depth : gdepth;
uint32_t va_page = (d + (box->z / gdepth)) * ((res->base.b.width0 / gwidth) * (res->base.b.height0 / gheight)) +
(h + (box->y / gheight)) * (res->base.b.width0 / gwidth) +
(w + (box->x / gwidth));
@ -929,43 +925,31 @@ zink_bo_commit(struct zink_screen *screen, struct zink_resource *res, unsigned l
/* Fill the uncommitted span with chunks of backing memory. */
while (span_va_page < va_page) {
struct zink_sparse_backing *backing;
uint32_t backing_start, backing_size;
backing_size = va_page - span_va_page;
backing = sparse_backing_alloc(screen, bo, &backing_start, &backing_size);
if (!backing) {
backing_size[i] = va_page - span_va_page;
backing[i] = sparse_backing_alloc(screen, bo, &backing_start[i], &backing_size[i]);
if (!backing[i]) {
ok = false;
goto out;
}
if (!texture_commit_single(screen, res, backing->bo, &subresource, &off, &extent, true)) {
ok = sparse_backing_free(screen, bo, backing, backing_start, backing_size);
assert(ok && "sufficient memory should already be allocated");
ibind[i].memory = backing[i]->bo->mem ? backing[i]->bo->mem : backing[i]->bo->u.slab.real->mem;
ibind[i].memoryOffset = backing[i]->bo->mem ? 0 : backing[i]->bo->offset;
ok = false;
goto out;
}
while (backing_size) {
comm[span_va_page].backing = backing;
comm[span_va_page].page = backing_start;
while (backing_size[i]) {
comm[span_va_page].backing = backing[i];
comm[span_va_page].page = backing_start[i];
span_va_page++;
backing_start++;
backing_size--;
backing_start[i]++;
backing_size[i]--;
}
commits_pending = true;
i++;
}
}
} else {
if (!texture_commit_single(screen, res, NULL, &subresource, &off, &extent, false)) {
ok = false;
goto out;
}
ibind[i].memory = VK_NULL_HANDLE;
ibind[i].memoryOffset = 0;
while (va_page < end_va_page) {
struct zink_sparse_backing *backing;
uint32_t backing_start;
uint32_t span_pages;
/* Skip pages that are already uncommitted. */
if (!comm[va_page].backing) {
va_page++;
@ -973,31 +957,52 @@ zink_bo_commit(struct zink_screen *screen, struct zink_resource *res, unsigned l
}
/* Group contiguous spans of pages. */
backing = comm[va_page].backing;
backing_start = comm[va_page].page;
backing[i] = comm[va_page].backing;
backing_start[i] = comm[va_page].page;
comm[va_page].backing = NULL;
span_pages = 1;
backing_size[i] = 1;
va_page++;
while (va_page < end_va_page &&
comm[va_page].backing == backing &&
comm[va_page].page == backing_start + span_pages) {
comm[va_page].backing == backing[i] &&
comm[va_page].page == backing_start[i] + backing_size[i]) {
comm[va_page].backing = NULL;
va_page++;
span_pages++;
}
if (!sparse_backing_free(screen, bo, backing, backing_start, span_pages)) {
/* Couldn't allocate tracking data structures, so we have to leak */
fprintf(stderr, "zink: leaking sparse backing memory\n");
ok = false;
backing_size[i]++;
}
commits_pending = true;
i++;
}
}
if (i == ARRAY_SIZE(ibind)) {
if (!texture_commit_single(screen, res, ibind, ARRAY_SIZE(ibind), commit)) {
for (unsigned s = 0; s < i; s++) {
ok = sparse_backing_free(screen, backing[s]->bo, backing[s], backing_start[s], backing_size[s]);
if (!ok) {
/* Couldn't allocate tracking data structures, so we have to leak */
fprintf(stderr, "zink: leaking sparse backing memory\n");
}
}
ok = false;
goto out;
}
commits_pending = false;
i = 0;
}
}
}
}
if (commits_pending && !texture_commit_single(screen, res, ibind, i, commit)) {
for (unsigned s = 0; s < i; s++) {
ok = sparse_backing_free(screen, backing[s]->bo, backing[s], backing_start[s], backing_size[s]);
if (!ok) {
/* Couldn't allocate tracking data structures, so we have to leak */
fprintf(stderr, "zink: leaking sparse backing memory\n");
}
}
ok = false;
}
out:
simple_mtx_unlock(&bo->lock);