asahi: Implement stencil texturing
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sat, 22 Oct 2022 15:36:47 +0000 (11:36 -0400)
committerMarge Bot <emma+marge@anholt.net>
Sat, 19 Nov 2022 04:27:10 +0000 (04:27 +0000)
Stencil texturing is easy: S8_UINT is textured like R8_UINT (with a
little swizzle fixup), and stencil is always S8_UINT thanks to
u_transfer_helper. So we just need to do some fixups to make
u_transfer_helper's seperate_stencil work and everything will work out.

Passes dEQP-GLES31.functional.stencil_texturing.*

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19811>

src/asahi/lib/agx_formats.c
src/gallium/drivers/asahi/agx_pipe.c
src/gallium/drivers/asahi/agx_state.c
src/gallium/drivers/asahi/agx_state.h

index 187a4b6..a6297ef 100644 (file)
@@ -109,8 +109,9 @@ const struct agx_pixel_format_entry agx_pixel_format[PIPE_FORMAT_COUNT] = {
    AGX_FMT(Z16_UNORM,               R16,           UNORM,  F, _),
    AGX_FMT(Z32_FLOAT,               R32,           FLOAT,  F, _),
    AGX_FMT(Z32_FLOAT_S8X24_UINT,    R32,           FLOAT,  F, _),
+   AGX_FMT(S8_UINT,                 R8,            UINT,   F, _),
 
-   /* These must be lowered by u_transfer_helper to Z32F */
+   /* These must be lowered by u_transfer_helper to Z32F + S8 */
    AGX_FMT(Z24X8_UNORM,             R32,           FLOAT,  F, _),
    AGX_FMT(Z24_UNORM_S8_UINT,       R32,           FLOAT,  F, _),
 
index 7daca7a..ff66f01 100644 (file)
@@ -1322,9 +1322,18 @@ agx_is_format_supported(struct pipe_screen* pscreen,
       return false;
 
    if (usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) {
-      struct agx_pixel_format_entry ent = agx_pixel_format[format];
+      enum pipe_format tex_format = format;
 
-      if (!agx_is_valid_pixel_format(format))
+      /* Mimic the fixup done in create_sampler_view and u_transfer_helper so we
+       * advertise GL_OES_texture_stencil8. Alternatively, we could make mesa/st
+       * less stupid?
+       */
+      if (tex_format == PIPE_FORMAT_X24S8_UINT)
+         tex_format = PIPE_FORMAT_S8_UINT;
+
+      struct agx_pixel_format_entry ent = agx_pixel_format[tex_format];
+
+      if (!agx_is_valid_pixel_format(tex_format))
          return false;
 
       if ((usage & PIPE_BIND_RENDER_TARGET) && !ent.renderable)
index d463922..3d0b513 100644 (file)
@@ -441,17 +441,46 @@ agx_translate_texture_dimension(enum pipe_texture_target dim)
 
 static struct pipe_sampler_view *
 agx_create_sampler_view(struct pipe_context *pctx,
-                        struct pipe_resource *texture,
+                        struct pipe_resource *orig_texture,
                         const struct pipe_sampler_view *state)
 {
-   struct agx_resource *rsrc = agx_resource(texture);
+   struct agx_resource *rsrc = agx_resource(orig_texture);
    struct agx_sampler_view *so = CALLOC_STRUCT(agx_sampler_view);
 
    if (!so)
       return NULL;
 
+   struct pipe_resource *texture = orig_texture;
+   enum pipe_format format = state->format;
+
+   /* Use stencil attachment, separate stencil always used on G13 */
+   if (rsrc->separate_stencil) {
+      rsrc = rsrc->separate_stencil;
+      texture = &rsrc->base;
+      format = texture->format;
+   }
+
+   /* Save off the BO that we actually use, with the stencil fixed up */
+   so->bo = rsrc->bo;
+
    const struct util_format_description *desc =
-      util_format_description(state->format);
+      util_format_description(format);
+
+   assert(agx_is_valid_pixel_format(format));
+
+   uint8_t format_swizzle[4] = {
+      desc->swizzle[0], desc->swizzle[1], desc->swizzle[2], desc->swizzle[3],
+   };
+
+   if (util_format_has_stencil(desc)) {
+      assert(!util_format_has_depth(desc) && "separate stencil always used");
+
+      /* Broadcast stencil */
+      format_swizzle[0] = 0;
+      format_swizzle[1] = 0;
+      format_swizzle[2] = 0;
+      format_swizzle[3] = 0;
+   }
 
    /* We only have a single swizzle for the user swizzle and the format fixup,
     * so compose them now. */
@@ -461,7 +490,7 @@ agx_create_sampler_view(struct pipe_context *pctx,
       state->swizzle_b, state->swizzle_a
    };
 
-   util_format_compose_swizzles(desc->swizzle, view_swizzle, out_swizzle);
+   util_format_compose_swizzles(format_swizzle, view_swizzle, out_swizzle);
 
    assert(state->u.tex.first_layer == 0);
 
@@ -473,8 +502,8 @@ agx_create_sampler_view(struct pipe_context *pctx,
    agx_pack(&so->desc, TEXTURE, cfg) {
       cfg.dimension = agx_translate_texture_dimension(state->target);
       cfg.layout = agx_translate_layout(rsrc->layout.tiling);
-      cfg.channels = agx_pixel_format[state->format].channels;
-      cfg.type = agx_pixel_format[state->format].type;
+      cfg.channels = agx_pixel_format[format].channels;
+      cfg.type = agx_pixel_format[format].type;
       cfg.swizzle_r = agx_channel_from_pipe(out_swizzle[0]);
       cfg.swizzle_g = agx_channel_from_pipe(out_swizzle[1]);
       cfg.swizzle_b = agx_channel_from_pipe(out_swizzle[2]);
@@ -507,10 +536,9 @@ agx_create_sampler_view(struct pipe_context *pctx,
       }
    }
 
-   /* Initialize base object */
    so->base = *state;
    so->base.texture = NULL;
-   pipe_resource_reference(&so->base.texture, texture);
+   pipe_resource_reference(&so->base.texture, orig_texture);
    pipe_reference_init(&so->base.reference, 1);
    so->base.context = pctx;
    return &so->base;
index e4dd62d..4d92dcc 100644 (file)
@@ -250,6 +250,9 @@ struct agx_sampler_state {
 struct agx_sampler_view {
    struct pipe_sampler_view base;
 
+   /* BO, may differ from base.texture's BO in case of separate stencil */
+   struct agx_bo *bo;
+
    /* Prepared descriptor */
    struct agx_texture_packed desc;
 };