mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-05 11:10:10 +01:00
i965/blorp: Account for offsets when emitting SURFACE_STATE.
Fixes piglit tests "framebuffer-blit-levels {read,draw} depth".
NOTE: This is a candidate for stable release branches.
Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
3123f06215
commit
f04f219906
4 changed files with 48 additions and 4 deletions
|
|
@ -107,6 +107,31 @@ brw_blorp_surface_info::set(struct brw_context *brw,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Split x_offset and y_offset into a base offset (in bytes) and a remaining
|
||||
* x/y offset (in pixels). Note: we can't do this by calling
|
||||
* intel_renderbuffer_tile_offsets(), because the offsets may have been
|
||||
* adjusted to account for Y vs. W tiling differences. So we compute it
|
||||
* directly from the adjusted offsets.
|
||||
*/
|
||||
uint32_t
|
||||
brw_blorp_surface_info::compute_tile_offsets(uint32_t *tile_x,
|
||||
uint32_t *tile_y) const
|
||||
{
|
||||
struct intel_region *region = mt->region;
|
||||
uint32_t mask_x, mask_y;
|
||||
|
||||
intel_region_get_tile_masks(region, &mask_x, &mask_y);
|
||||
|
||||
*tile_x = x_offset & mask_x;
|
||||
*tile_y = y_offset & mask_y;
|
||||
|
||||
return intel_region_get_aligned_offset(region, x_offset & ~mask_x,
|
||||
y_offset & ~mask_y);
|
||||
}
|
||||
|
||||
|
||||
brw_blorp_params::brw_blorp_params()
|
||||
: x0(0),
|
||||
y0(0),
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ public:
|
|||
struct intel_mipmap_tree *mt,
|
||||
unsigned int level, unsigned int layer);
|
||||
|
||||
uint32_t compute_tile_offsets(uint32_t *tile_x, uint32_t *tile_y) const;
|
||||
|
||||
/* Setting this flag indicates that the buffer's contents are W-tiled
|
||||
* stencil data, but the surface state should be set up for Y tiled
|
||||
* MESA_FORMAT_R8 data (this is necessary because surface states don't
|
||||
|
|
|
|||
|
|
@ -424,6 +424,7 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
|
|||
height /= 2;
|
||||
}
|
||||
struct intel_region *region = surface->mt->region;
|
||||
uint32_t tile_x, tile_y;
|
||||
|
||||
uint32_t *surf = (uint32_t *)
|
||||
brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 6 * 4, 32,
|
||||
|
|
@ -435,7 +436,8 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
|
|||
surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT);
|
||||
|
||||
/* reloc */
|
||||
surf[1] = region->bo->offset; /* No tile offsets needed */
|
||||
surf[1] = (surface->compute_tile_offsets(&tile_x, &tile_y) +
|
||||
region->bo->offset);
|
||||
|
||||
surf[2] = (0 << BRW_SURFACE_LOD_SHIFT |
|
||||
(width - 1) << BRW_SURFACE_WIDTH_SHIFT |
|
||||
|
|
@ -453,8 +455,13 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
|
|||
|
||||
surf[4] = brw_get_surface_num_multisamples(surface->num_samples);
|
||||
|
||||
surf[5] = (0 << BRW_SURFACE_X_OFFSET_SHIFT |
|
||||
0 << BRW_SURFACE_Y_OFFSET_SHIFT |
|
||||
/* Note that the low bits of these fields are missing, so
|
||||
* there's the possibility of getting in trouble.
|
||||
*/
|
||||
assert(tile_x % 4 == 0);
|
||||
assert(tile_y % 2 == 0);
|
||||
surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT |
|
||||
(tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT |
|
||||
(surface->mt->align_h == 4 ?
|
||||
BRW_SURFACE_VERTICAL_ALIGN_ENABLE : 0));
|
||||
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
|
|||
* gen6_blorp_emit_surface_state).
|
||||
*/
|
||||
struct intel_region *region = surface->mt->region;
|
||||
uint32_t tile_x, tile_y;
|
||||
|
||||
struct gen7_surface_state *surf = (struct gen7_surface_state *)
|
||||
brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, sizeof(*surf), 32,
|
||||
|
|
@ -167,7 +168,16 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
|
|||
GEN7_SURFACE_ARYSPC_LOD0 : GEN7_SURFACE_ARYSPC_FULL;
|
||||
|
||||
/* reloc */
|
||||
surf->ss1.base_addr = region->bo->offset; /* No tile offsets needed */
|
||||
surf->ss1.base_addr = surface->compute_tile_offsets(&tile_x, &tile_y);
|
||||
surf->ss1.base_addr += region->bo->offset;
|
||||
|
||||
/* Note that the low bits of these fields are missing, so
|
||||
* there's the possibility of getting in trouble.
|
||||
*/
|
||||
assert(tile_x % 4 == 0);
|
||||
assert(tile_y % 2 == 0);
|
||||
surf->ss5.x_offset = tile_x / 4;
|
||||
surf->ss5.y_offset = tile_y / 2;
|
||||
|
||||
surf->ss2.width = width - 1;
|
||||
surf->ss2.height = height - 1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue