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. --- src/gallium/drivers/vc5/vc5_rcl.c | 22 +++++++++ src/gallium/drivers/vc5/vc5_resource.c | 85 ++++++++++++++++++++++++++++++++-- src/gallium/drivers/vc5/vc5_resource.h | 6 +++ src/gallium/drivers/vc5/vc5_screen.c | 6 +++ 4 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/src/gallium/drivers/vc5/vc5_rcl.c b/src/gallium/drivers/vc5/vc5_rcl.c index 22d6eed781c7..2c82eece9a6b 100644 --- a/src/gallium/drivers/vc5/vc5_rcl.c +++ b/src/gallium/drivers/vc5/vc5_rcl.c @@ -331,6 +331,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 04aeb0e008b9..7a26c5afde48 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,52 @@ 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); + return u_transfer_map_z32f_s8_helper(pctx, prsc, + &rsc->separate_stencil->base, + level, usage, + box, pptrans, vc5_resource_transfer_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) { + u_transfer_unmap_z32f_s8_helper(pctx, ptrans, + vc5_resource_transfer_unmap); + } 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); } @@ -434,7 +476,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); @@ -522,6 +570,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; @@ -634,6 +693,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); @@ -648,6 +711,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)) { @@ -675,6 +747,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; @@ -709,9 +788,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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev