[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