radeonsi: support alloc a sparse texture
authorQiang Yu <yuq825@gmail.com>
Fri, 10 Dec 2021 02:48:47 +0000 (10:48 +0800)
committerQiang Yu <yuq825@gmail.com>
Thu, 30 Dec 2021 08:11:19 +0000 (16:11 +0800)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14223>

src/gallium/drivers/radeonsi/si_buffer.c
src/gallium/drivers/radeonsi/si_texture.c

index d9c0c25..c66c525 100644 (file)
@@ -136,6 +136,9 @@ void si_init_resource_fields(struct si_screen *sscreen, struct si_resource *res,
    if (res->b.b.flags & SI_RESOURCE_FLAG_DRIVER_INTERNAL)
       res->flags |= RADEON_FLAG_DRIVER_INTERNAL;
 
+   if (res->b.b.flags & PIPE_RESOURCE_FLAG_SPARSE)
+      res->flags |= RADEON_FLAG_SPARSE;
+
    /* For higher throughput and lower latency over PCIe assuming sequential access.
     * Only CP DMA and optimized compute benefit from this.
     * GFX8 and older don't support RADEON_FLAG_UNCACHED.
@@ -588,9 +591,6 @@ static struct pipe_resource *si_buffer_create(struct pipe_screen *screen,
 
    si_init_resource_fields(sscreen, buf, templ->width0, alignment);
 
-   if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE)
-      buf->flags |= RADEON_FLAG_SPARSE;
-
    buf->b.buffer_id_unique = util_idalloc_mt_alloc(&sscreen->buffer_ids);
 
    if (!si_alloc_resource(sscreen, buf)) {
index 728b077..4c60c10 100644 (file)
@@ -279,6 +279,14 @@ static int si_init_surface(struct si_screen *sscreen, struct radeon_surf *surfac
          surface->u.gfx9.swizzle_mode = ADDR_SW_64KB_R_X;
    }
 
+   if (ptex->flags & PIPE_RESOURCE_FLAG_SPARSE) {
+      flags |=
+         RADEON_SURF_PRT |
+         RADEON_SURF_NO_FMASK |
+         RADEON_SURF_NO_HTILE |
+         RADEON_SURF_DISABLE_DCC;
+   }
+
    surface->modifier = modifier;
 
    r = sscreen->ws->surface_init(sscreen->ws, ptex, flags, bpe, array_mode, surface);
@@ -996,6 +1004,9 @@ static struct si_texture *si_texture_create_object(struct pipe_screen *screen,
       radeon_bo_reference(sscreen->ws, &resource->buf, plane0->buffer.buf);
       resource->gpu_address = plane0->buffer.gpu_address;
    } else if (!(surface->flags & RADEON_SURF_IMPORTED)) {
+      if (base->flags & PIPE_RESOURCE_FLAG_SPARSE)
+         resource->b.b.flags |= SI_RESOURCE_FLAG_UNMAPPABLE;
+
       /* Create the backing buffer. */
       si_init_resource_fields(sscreen, resource, alloc_size, alignment);
 
@@ -1266,6 +1277,8 @@ si_texture_create_with_modifier(struct pipe_screen *screen,
                           is_flushed_depth, tc_compatible_htile))
          return NULL;
 
+      plane_templ[i].nr_sparse_levels = surface[i].first_mip_tail_level;
+
       plane_offset[i] = align64(total_size, 1 << surface[i].surf_alignment_log2);
       total_size = plane_offset[i] + surface[i].total_size;
       max_alignment = MAX2(max_alignment, 1 << surface[i].surf_alignment_log2);