From dea902c93352b875178fef9b8a65fd53e52696b3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Jan 2018 16:44:53 -0800 Subject: broadcom/vc5: Simplify separate stencil surface setup. If we just make another gallium surface for the separate stencil, it's a lot easier to keep track of which set of fields we're using in RCL setup. This also incidentally fixes a little bug in setting up the surface's padded height for separate stencil when the UIF-ness changes at different levels of Z versus stencil. --- src/gallium/drivers/vc5/vc5_rcl.c | 140 +++++++++++++++------------------ src/gallium/drivers/vc5/vc5_resource.c | 28 +++---- src/gallium/drivers/vc5/vc5_resource.h | 8 +- 3 files changed, 77 insertions(+), 99 deletions(-) diff --git a/src/gallium/drivers/vc5/vc5_rcl.c b/src/gallium/drivers/vc5/vc5_rcl.c index 8018bfdcba..86ea22628d 100644 --- a/src/gallium/drivers/vc5/vc5_rcl.c +++ b/src/gallium/drivers/vc5/vc5_rcl.c @@ -38,39 +38,29 @@ static void load_general(struct vc5_cl *cl, struct pipe_surface *psurf, int buffer) { struct vc5_surface *surf = vc5_surface(psurf); - struct vc5_resource *rsc = vc5_resource(psurf->texture); + bool separate_stencil = surf->separate_stencil && buffer == STENCIL; + if (separate_stencil) { + psurf = surf->separate_stencil; + surf = vc5_surface(psurf); + } - struct vc5_resource *separate_stencil = NULL; - if (rsc->separate_stencil && buffer == STENCIL) - separate_stencil = rsc->separate_stencil; + struct vc5_resource *rsc = vc5_resource(psurf->texture); cl_emit(cl, LOAD_TILE_BUFFER_GENERAL, load) { load.buffer_to_load = buffer; - if (separate_stencil) { - load.address = cl_address(separate_stencil->bo, - surf->separate_stencil_offset); - } else { - load.address = cl_address(rsc->bo, surf->offset); - } + load.address = cl_address(rsc->bo, surf->offset); #if V3D_VERSION >= 40 - if (separate_stencil) { + load.memory_format = surf->tiling; + if (separate_stencil) load.input_image_format = V3D_OUTPUT_IMAGE_FORMAT_S8; - load.memory_format = surf->separate_stencil_tiling; - } else { + else load.input_image_format = surf->format; - load.memory_format = surf->tiling; - } if (surf->tiling == VC5_TILING_UIF_NO_XOR || surf->tiling == VC5_TILING_UIF_XOR) { - if (separate_stencil) { - load.height_in_ub_or_stride = - surf->separate_stencil_padded_height_of_output_image_in_uif_blocks; - } else { - load.height_in_ub_or_stride = - surf->padded_height_of_output_image_in_uif_blocks; - } + load.height_in_ub_or_stride = + surf->padded_height_of_output_image_in_uif_blocks; } else if (surf->tiling == VC5_TILING_RASTER) { struct vc5_resource_slice *slice = &rsc->slices[psurf->u.tex.level]; @@ -92,24 +82,19 @@ store_general(struct vc5_job *job, int pipe_bit, bool last_store, bool general_color_clear) { struct vc5_surface *surf = vc5_surface(psurf); + bool separate_stencil = surf->separate_stencil && buffer == STENCIL; + if (separate_stencil) { + psurf = surf->separate_stencil; + surf = vc5_surface(psurf); + } + struct vc5_resource *rsc = vc5_resource(psurf->texture); - struct vc5_resource *separate_stencil = NULL; - if (rsc->separate_stencil && buffer == STENCIL) { - separate_stencil = rsc->separate_stencil; - separate_stencil->writes++; - } else { - rsc->writes++; - } + rsc->writes++; cl_emit(cl, STORE_TILE_BUFFER_GENERAL, store) { store.buffer_to_store = buffer; - if (separate_stencil) { - store.address = cl_address(separate_stencil->bo, - surf->separate_stencil_offset); - } else { - store.address = cl_address(rsc->bo, surf->offset); - } + store.address = cl_address(rsc->bo, surf->offset); #if V3D_VERSION >= 40 store.clear_buffer_being_stored = @@ -117,23 +102,17 @@ store_general(struct vc5_job *job, (general_color_clear || !(pipe_bit & PIPE_CLEAR_COLOR_BUFFERS))); - if (separate_stencil) { + if (separate_stencil) store.output_image_format = V3D_OUTPUT_IMAGE_FORMAT_S8; - store.memory_format = surf->separate_stencil_tiling; - } else { + else store.output_image_format = surf->format; - store.memory_format = surf->tiling; - } + + store.memory_format = surf->tiling; if (surf->tiling == VC5_TILING_UIF_NO_XOR || surf->tiling == VC5_TILING_UIF_XOR) { - if (separate_stencil) { - store.height_in_ub_or_stride = - surf->separate_stencil_padded_height_of_output_image_in_uif_blocks; - } else { - store.height_in_ub_or_stride = - surf->padded_height_of_output_image_in_uif_blocks; - } + store.height_in_ub_or_stride = + surf->padded_height_of_output_image_in_uif_blocks; } else if (surf->tiling == VC5_TILING_RASTER) { struct vc5_resource_slice *slice = &rsc->slices[psurf->u.tex.level]; @@ -433,7 +412,37 @@ v3d_setup_render_target(struct vc5_job *job, int cbuf, *rt_type = surf->internal_type; *rt_clamp = V3D_RENDER_TARGET_CLAMP_NONE; } -#endif /* V3D_VERSION >= 40 */ + +#else /* V3D_VERSION < 40 */ + +static void +v3d_emit_z_stencil_config(struct vc5_job *job, struct vc5_surface *surf, + struct vc5_resource *rsc, bool is_separate_stencil) +{ + cl_emit(&job->rcl, TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG, zs) { + zs.address = cl_address(rsc->bo, surf->offset); + + if (!is_separate_stencil) { + zs.internal_type = surf->internal_type; + zs.output_image_format = surf->format; + } else { + zs.z_stencil_id = 1; /* Separate stencil */ + } + + zs.padded_height_of_output_image_in_uif_blocks = + surf->padded_height_of_output_image_in_uif_blocks; + + assert(surf->tiling != VC5_TILING_RASTER); + zs.memory_format = surf->tiling; + } + + if (job->resolve & (is_separate_stencil ? + PIPE_CLEAR_STENCIL : + PIPE_CLEAR_DEPTHSTENCIL)) { + rsc->writes++; + } +} +#endif /* V3D_VERSION < 40 */ #define div_round_up(a, b) (((a) + (b) - 1) / b) @@ -584,41 +593,16 @@ v3dX(emit_rcl)(struct vc5_job *job) struct vc5_surface *surf = vc5_surface(psurf); struct vc5_resource *rsc = vc5_resource(psurf->texture); - cl_emit(&job->rcl, TILE_RENDERING_MODE_CONFIGURATION_Z_STENCIL_CONFIG, zs) { - zs.address = cl_address(rsc->bo, surf->offset); - - zs.internal_type = surf->internal_type; - zs.output_image_format = surf->format; - zs.padded_height_of_output_image_in_uif_blocks = - surf->padded_height_of_output_image_in_uif_blocks; - - assert(surf->tiling != VC5_TILING_RASTER); - zs.memory_format = surf->tiling; - } - - if (job->resolve & PIPE_CLEAR_DEPTHSTENCIL) - rsc->writes++; + v3d_emit_z_stencil_config(job, surf, rsc, false); /* 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; - } + if (surf->separate_stencil) { + v3d_emit_z_stencil_config(job, + vc5_surface(surf->separate_stencil), + rsc->separate_stencil, true); } } #endif /* V3D_VERSION < 40 */ diff --git a/src/gallium/drivers/vc5/vc5_resource.c b/src/gallium/drivers/vc5/vc5_resource.c index a9cc27127f..9ecd083b05 100644 --- a/src/gallium/drivers/vc5/vc5_resource.c +++ b/src/gallium/drivers/vc5/vc5_resource.c @@ -654,10 +654,6 @@ 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); @@ -672,14 +668,6 @@ 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(&screen->devinfo, psurf->format); @@ -709,13 +697,12 @@ 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))); - } + if (rsc->separate_stencil) { + surface->separate_stencil = + vc5_create_surface(pctx, &rsc->separate_stencil->base, + surf_tmpl); } return &surface->base; @@ -724,6 +711,11 @@ vc5_create_surface(struct pipe_context *pctx, static void vc5_surface_destroy(struct pipe_context *pctx, struct pipe_surface *psurf) { + struct vc5_surface *surf = vc5_surface(psurf); + + if (surf->separate_stencil) + pipe_surface_reference(&surf->separate_stencil, NULL); + pipe_resource_reference(&psurf->texture, NULL); FREE(psurf); } diff --git a/src/gallium/drivers/vc5/vc5_resource.h b/src/gallium/drivers/vc5/vc5_resource.h index 688f03d53f..631a7b8fba 100644 --- a/src/gallium/drivers/vc5/vc5_resource.h +++ b/src/gallium/drivers/vc5/vc5_resource.h @@ -80,9 +80,7 @@ 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 */ @@ -101,7 +99,11 @@ 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; + + /* If the resource being referenced is separate stencil, then this is + * the surface to use when reading/writing stencil. + */ + struct pipe_surface *separate_stencil; }; struct vc5_resource { -- cgit v1.2.3