[Mesa-dev] [PATCH 1/2] i965: Fix mipmap offsets for HiZ and separate stencil buffers.
Chad Versace
chad.versace at linux.intel.com
Thu Apr 26 16:40:41 PDT 2012
A few comments below.
On 04/24/2012 12:23 PM, Paul Berry wrote:
> When rendering to a miplevel other than 0 within a color, depth,
> stencil, or HiZ buffer, we need to tell the GPU to render to an offset
> within the buffer, so that the data is written into the correct
> miplevel. We do this using a coarse offset (in pages), and a fine
> adjustment (the so-called "tile_x" and "tile_y" values, which are
> measured in pixels).
>
> We have always computed the coarse offset and fine adjustment using
> intel_renderbuffer_tile_offsets() function. This worked fine for
> color and combined depth/stencil buffers, but failed to work properly
> when HiZ and separate stencil were in use. It failed to work because
> there is only one set of fine adjustment controls shared by the HiZ,
> depth, and stencil buffers, so we need to choose tile_x and tile_y
> values that are compatible with the tiling of all three buffers, and
> then compute separate coarse offsets for each buffer.
>
> This patch fixes the HiZ and separate stencil case by replacing the
> call to intel_renderbuffer_tile_offsets() with calls to two functions:
> intel_region_get_tile_masks(), which determines how much of the
> adjustment can be performed using offsets and how much can be
> performed using tile_x and tile_y, and
> intel_region_get_aligned_offset(), which computes the coarse offset.
>
> intel_region_get_tile_offsets() is still used for color renderbuffers,
> so to avoid code duplication, I've re-worked it to use
> intel_region_get_tile_masks() and intel_region_get_aligned_offset().
>
> On i965 Gen6, fixes piglit tests
> "texturing/depthstencil-render-miplevels 1024 X" where X is one of
> (depth, depth_and_stencil, depth_stencil_single_binding, depth_x,
> depth_x_and_stencil, stencil, stencil_and_depth, stencil_and_depth_x).
>
> On i965 Gen7, the variants of
> "texturing/depthstencil-render-miplevels" that contain a stencil
> buffer still fail, due to another problem: Gen7 seems to ignore the 3
> LSB's of the tile_y adjustment (and possibly also tile_x).
> ---
> src/mesa/drivers/dri/i965/brw_misc_state.c | 96 ++++++++++++++++++++++++--
> src/mesa/drivers/dri/i965/gen6_hiz.c | 54 +++++++++++----
> src/mesa/drivers/dri/i965/gen7_hiz.c | 54 +++++++++++----
> src/mesa/drivers/dri/i965/gen7_misc_state.c | 79 ++++++++++++++++++++--
> src/mesa/drivers/dri/intel/intel_fbo.c | 27 ++-----
> src/mesa/drivers/dri/intel/intel_fbo.h | 28 ++++++++
> src/mesa/drivers/dri/intel/intel_regions.c | 52 ++++++++++++++
> src/mesa/drivers/dri/intel/intel_regions.h | 8 ++
> 8 files changed, 338 insertions(+), 60 deletions(-)
[snip]
> diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h
> index 724f141..503b006 100644
> --- a/src/mesa/drivers/dri/intel/intel_fbo.h
> +++ b/src/mesa/drivers/dri/intel/intel_fbo.h
> @@ -153,6 +153,34 @@ intel_flip_renderbuffers(struct gl_framebuffer *fb);
> void
> intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb);
>
> +void
> +intel_renderbuffer_fine_offset_masks(struct intel_renderbuffer *irb,
> + uint32_t *fine_offset_mask_x,
> + uint32_t *fine_offset_mask_y);
> +
> +/**
> + * When rendering to a texture with multiple miplevels, depth planes, or cube
> + * faces, we need to instruct the GPU to render to an offset within the
> + * texture image corresponding to the appropriate miplevel/plane/cubeface. We
> + * do this by a combination of two techniques: by offsetting the base address
> + * of the texture image, and by supplying additional X and Y coordinate
> + * offsets to the GPU in the SURFACE_STATE structure.
> + *
> + * This function computes the additional Y coordinate offset.
> + */
> +
> +/**
> + * When rendering to a texture with multiple miplevels, depth planes, or cube
> + * faces, we need to instruct the GPU to render to an offset within the
> + * texture image corresponding to the appropriate miplevel/plane/cubeface. We
> + * do this by a combination of two techniques: by offsetting the base address
> + * of the texture image, and by supplying additional X and Y coordinate
> + * offsets to the GPU in the SURFACE_STATE structure.
> + *
> + * This function computes the additional X coordinate offset.
> + */
> +
> +
> uint32_t
> intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
> uint32_t *tile_x,
Dangling comments above.
[snip]
> +/**
> + * Compute the offset (in bytes) from the start of the region to the given x
> + * and y coordinate. For tiled regions, caller must ensure that x and y are
> + * multiples of the tile size.
> + */
I think this function needs to assert the preconditions for x and y. It's
just too easy for a caller to forget the precondition and hence introduce
an easily avoided bug.
> +uint32_t
> +intel_region_get_aligned_offset(struct intel_region *region, uint32_t x,
> + uint32_t y)
> +{
> + int cpp = region->cpp;
> + uint32_t pitch = region->pitch * cpp;
> +
> + switch (region->tiling) {
> + default:
> + assert(false);
> + case I915_TILING_NONE:
> + return y * pitch + x * cpp;
> + case I915_TILING_X:
> + return y * pitch + x / (512 / cpp) * 4096;
> + case I915_TILING_Y:
> + return y * pitch + x / (128 / cpp) * 4096;
> + }
> +}
One more thing. It would be nice if the duplicate offset code in
gen6_hiz.c and gen7_hiz.c were consolidated into a helper function...
but, meh. I don't care that much.
More information about the mesa-dev
mailing list