[Mesa-dev] [PATCH v2 5/5] broadcom/vc5: Start adding support for rendering to Z32F_S8X24_UINT.

Eric Anholt eric at anholt.net
Tue Nov 21 21:13:08 UTC 2017


There may be some more RCL work to be done (I think I need to split my Z/S
stores when doing separate stencil), but this gets piglit's "texwrap
GL_ARB_depth_buffer_float" working.

v2: Unwrap the z32f_wrapper before calling the helper, rather than having
    the helper have a callback.
---
 src/gallium/drivers/vc5/vc5_rcl.c      | 22 +++++++++
 src/gallium/drivers/vc5/vc5_resource.c | 89 ++++++++++++++++++++++++++++++++--
 src/gallium/drivers/vc5/vc5_resource.h |  6 +++
 src/gallium/drivers/vc5/vc5_screen.c   |  6 +++
 4 files changed, 120 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/vc5/vc5_rcl.c b/src/gallium/drivers/vc5/vc5_rcl.c
index 1fa00b2e8101..89ae44660f5b 100644
--- a/src/gallium/drivers/vc5/vc5_rcl.c
+++ b/src/gallium/drivers/vc5/vc5_rcl.c
@@ -348,6 +348,28 @@ vc5_emit_rcl(struct vc5_job *job)
 
                 if (job->resolve & PIPE_CLEAR_DEPTHSTENCIL)
                         rsc->writes++;
+
+                /* Emit the separate stencil packet if we have a resource for
+                 * it.  The HW will only load/store this buffer if the
+                 * Z/Stencil config doesn't have stencil in its format.
+                 */
+                if (rsc->separate_stencil) {
+                        cl_emit(&job->rcl,
+                                TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG,
+                                zs) {
+                                zs.address =
+                                        cl_address(rsc->separate_stencil->bo,
+                                                   surf->separate_stencil_offset);
+
+                                zs.z_stencil_id = 1; /* Separate stencil */
+
+                                zs.padded_height_of_output_image_in_uif_blocks =
+                                        surf->separate_stencil_padded_height_of_output_image_in_uif_blocks;
+
+                                assert(surf->tiling != VC5_TILING_RASTER);
+                                zs.memory_format = surf->separate_stencil_tiling;
+                        }
+                }
         }
 
         /* Ends rendering mode config. */
diff --git a/src/gallium/drivers/vc5/vc5_resource.c b/src/gallium/drivers/vc5/vc5_resource.c
index 0f855c17e21d..f0f7969775fc 100644
--- a/src/gallium/drivers/vc5/vc5_resource.c
+++ b/src/gallium/drivers/vc5/vc5_resource.c
@@ -28,6 +28,7 @@
 #include "util/u_inlines.h"
 #include "util/u_surface.h"
 #include "util/u_upload_mgr.h"
+#include "util/u_format_zs.h"
 
 #include "drm_fourcc.h"
 #include "vc5_screen.h"
@@ -280,11 +281,56 @@ fail:
         return NULL;
 }
 
+/* Decomposes a PIPE_FORMAT_Z32_FLOAT_S8X24_UINT transfer into mappings of
+ * each resource into a temporary buffer using the gallium helper.
+ *
+ * This has to be a separate function from vc5_resource_transfer_map() to
+ * prevent infinite recusion.
+ */
+static void *
+vc5_resource_transfer_map_z32f_wrapper(struct pipe_context *pctx,
+                                       struct pipe_resource *prsc,
+                                       unsigned level, unsigned usage,
+                                       const struct pipe_box *box,
+                                       struct pipe_transfer **pptrans)
+{
+        if (prsc->format != PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
+                return vc5_resource_transfer_map(pctx, prsc, level, usage,
+                                                 box, pptrans);
+        }
+
+        struct vc5_resource *rsc = vc5_resource(prsc);
+        pctx->transfer_map = vc5_resource_transfer_map;
+        void *map = u_transfer_map_z32f_s8_helper(pctx, prsc,
+                                                  &rsc->separate_stencil->base,
+                                                  level, usage,
+                                                  box, pptrans);
+        pctx->transfer_map = vc5_resource_transfer_map_z32f_wrapper;
+        return map;
+}
+
+static void
+vc5_resource_transfer_unmap_z32f_wrapper(struct pipe_context *pctx,
+                                         struct pipe_transfer *ptrans)
+{
+        if (ptrans->resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
+                pctx->transfer_unmap = vc5_resource_transfer_unmap;
+                u_transfer_unmap_z32f_s8_helper(pctx, ptrans);
+                pctx->transfer_unmap = vc5_resource_transfer_unmap_z32f_wrapper;
+        } else {
+                vc5_resource_transfer_unmap(pctx, ptrans);
+        }
+}
+
 static void
 vc5_resource_destroy(struct pipe_screen *pscreen,
                      struct pipe_resource *prsc)
 {
         struct vc5_resource *rsc = vc5_resource(prsc);
+
+        if (rsc->separate_stencil)
+                vc5_resource_destroy(pscreen, &rsc->separate_stencil->base);
+
         vc5_bo_unreference(&rsc->bo);
         free(rsc);
 }
@@ -436,7 +482,13 @@ vc5_resource_setup(struct pipe_screen *pscreen,
         prsc->screen = pscreen;
 
         if (prsc->nr_samples <= 1) {
-                rsc->cpp = util_format_get_blocksize(prsc->format);
+                /* For Z32F+S8X24, the stencil is stored separately and this
+                 * rsc will just be the Z32F.
+                 */
+                if (prsc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
+                        rsc->cpp = 4;
+                else
+                        rsc->cpp = util_format_get_blocksize(prsc->format);
         } else {
                 assert(vc5_rt_format_supported(prsc->format));
                 uint32_t output_image_format = vc5_get_rt_format(prsc->format);
@@ -524,6 +576,17 @@ vc5_resource_create_with_modifiers(struct pipe_screen *pscreen,
                 return NULL;
         }
 
+        if (prsc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
+                struct pipe_resource ss_tmpl = *tmpl;
+                ss_tmpl.format = PIPE_FORMAT_S8_UINT;
+
+                struct pipe_resource *ss = vc5_resource_create(pscreen,
+                                                               &ss_tmpl);
+                if (!ss)
+                        goto fail;
+                rsc->separate_stencil = vc5_resource(ss);
+        }
+
         vc5_setup_slices(rsc);
         if (!vc5_resource_bo_alloc(rsc))
                 goto fail;
@@ -636,6 +699,10 @@ vc5_create_surface(struct pipe_context *pctx,
         unsigned level = surf_tmpl->u.tex.level;
         struct vc5_resource_slice *slice = &rsc->slices[level];
 
+        struct vc5_resource_slice *separate_stencil_slice = NULL;
+        if (rsc->separate_stencil)
+                separate_stencil_slice = &rsc->separate_stencil->slices[level];
+
         pipe_reference_init(&psurf->reference, 1);
         pipe_resource_reference(&psurf->texture, ptex);
 
@@ -650,6 +717,15 @@ vc5_create_surface(struct pipe_context *pctx,
         surface->offset = (slice->offset +
                            psurf->u.tex.first_layer * rsc->cube_map_stride);
         surface->tiling = slice->tiling;
+        if (separate_stencil_slice) {
+                surface->separate_stencil_offset =
+                        (separate_stencil_slice->offset +
+                         psurf->u.tex.first_layer *
+                         rsc->separate_stencil->cube_map_stride);
+                surface->separate_stencil_tiling =
+                        separate_stencil_slice->tiling;
+        }
+
         surface->format = vc5_get_rt_format(psurf->format);
 
         if (util_format_is_depth_or_stencil(psurf->format)) {
@@ -677,6 +753,13 @@ vc5_create_surface(struct pipe_context *pctx,
                 surface->padded_height_of_output_image_in_uif_blocks =
                         ((slice->size / slice->stride) /
                          (2 * vc5_utile_height(rsc->cpp)));
+
+                if (separate_stencil_slice) {
+                        surface->separate_stencil_padded_height_of_output_image_in_uif_blocks =
+                        ((separate_stencil_slice->size /
+                          separate_stencil_slice->stride) /
+                         (2 * vc5_utile_height(rsc->separate_stencil->cpp)));
+                }
         }
 
         return &surface->base;
@@ -711,9 +794,9 @@ vc5_resource_screen_init(struct pipe_screen *pscreen)
 void
 vc5_resource_context_init(struct pipe_context *pctx)
 {
-        pctx->transfer_map = vc5_resource_transfer_map;
+        pctx->transfer_map = vc5_resource_transfer_map_z32f_wrapper;
         pctx->transfer_flush_region = u_default_transfer_flush_region;
-        pctx->transfer_unmap = vc5_resource_transfer_unmap;
+        pctx->transfer_unmap = vc5_resource_transfer_unmap_z32f_wrapper;
         pctx->buffer_subdata = u_default_buffer_subdata;
         pctx->texture_subdata = u_default_texture_subdata;
         pctx->create_surface = vc5_create_surface;
diff --git a/src/gallium/drivers/vc5/vc5_resource.h b/src/gallium/drivers/vc5/vc5_resource.h
index 38f04e1392fe..1c9f38cb6e53 100644
--- a/src/gallium/drivers/vc5/vc5_resource.h
+++ b/src/gallium/drivers/vc5/vc5_resource.h
@@ -80,7 +80,9 @@ struct vc5_resource_slice {
 struct vc5_surface {
         struct pipe_surface base;
         uint32_t offset;
+        uint32_t separate_stencil_offset;
         enum vc5_tiling_mode tiling;
+        enum vc5_tiling_mode separate_stencil_tiling;
         /**
          * Output image format for TILE_RENDERING_MODE_CONFIGURATION
          */
@@ -99,6 +101,7 @@ struct vc5_surface {
         uint8_t internal_bpp;
 
         uint32_t padded_height_of_output_image_in_uif_blocks;
+        uint32_t separate_stencil_padded_height_of_output_image_in_uif_blocks;
 };
 
 struct vc5_resource {
@@ -127,6 +130,9 @@ struct vc5_resource {
          * buffer) may get marked.
          */
         uint32_t initialized_buffers;
+
+        /* Resource storing the S8 part of a Z32F_S8 resource, or NULL. */
+        struct vc5_resource *separate_stencil;
 };
 
 static inline struct vc5_resource *
diff --git a/src/gallium/drivers/vc5/vc5_screen.c b/src/gallium/drivers/vc5/vc5_screen.c
index 36e34dedd59f..acc188658474 100644
--- a/src/gallium/drivers/vc5/vc5_screen.c
+++ b/src/gallium/drivers/vc5/vc5_screen.c
@@ -507,6 +507,12 @@ vc5_screen_is_format_supported(struct pipe_screen *pscreen,
                 retval |= PIPE_BIND_INDEX_BUFFER;
         }
 
+        /* We don't have the layered support necessary for resolving the
+         * separate stencil to single sample.
+         */
+        if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && sample_count > 1)
+                return FALSE;
+
 #if 0
         if (retval != usage) {
                 fprintf(stderr,
-- 
2.15.0



More information about the mesa-dev mailing list