i965/blorp: store surface width/height in brw_blorp_mip_info.

Previously, gen{6,7}_blorp_emit_surface_state would look up the width
and height of the surface at the time they set up the surface state,
and then tweak it if necessary (it's necessary when a W-tiled surface
is being mapped as Y-tiled).  With this patch, we look up the width
and height when setting up the blit, and store them in
brw_blorp_mip_info.  This allows us to do the necessary tweak in the
brw_blorp_blit_params constructor (where it makes more sense).  It
also reduces the need to keep track of level and layer in
brw_blorp_mip_info, so that a future patch can eliminate them
entirely.

For consistency, this patch makes a similar change to the handling of
depth buffers when doing HiZ operations.

NOTE: This is a candidate for stable release branches.

Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Paul Berry 2012-08-29 11:51:14 -07:00
parent e14b1288ef
commit 09b0fa8499
5 changed files with 48 additions and 37 deletions

View file

@ -31,7 +31,9 @@
brw_blorp_mip_info::brw_blorp_mip_info()
: mt(NULL),
level(0),
layer(0)
layer(0),
width(0),
height(0)
{
}
@ -50,6 +52,8 @@ brw_blorp_mip_info::set(struct intel_mipmap_tree *mt,
this->mt = mt;
this->level = level;
this->layer = layer;
this->width = mt->level[level].width;
this->height = mt->level[level].height;
}
void
@ -164,7 +168,8 @@ brw_hiz_op_params::brw_hiz_op_params(struct intel_mipmap_tree *mt,
this->hiz_op = op;
depth.set(mt, level, layer);
depth.get_miplevel_dims(&x1, &y1);
x1 = depth.width;
y1 = depth.height;
assert(mt->hiz_mt != NULL);

View file

@ -65,15 +65,21 @@ public:
unsigned int level, unsigned int layer);
void get_draw_offsets(uint32_t *draw_x, uint32_t *draw_y) const;
void get_miplevel_dims(uint32_t *width, uint32_t *height) const
{
*width = mt->level[level].width;
*height = mt->level[level].height;
}
struct intel_mipmap_tree *mt;
unsigned int level;
unsigned int layer;
/**
* Width of the miplevel to be used. For surfaces using
* INTEL_MSAA_LAYOUT_IMS, this is measured in samples, not pixels.
*/
uint32_t width;
/**
* Height of the miplevel to be used. For surfaces using
* INTEL_MSAA_LAYOUT_IMS, this is measured in samples, not pixels.
*/
uint32_t height;
};
class brw_blorp_surface_info : public brw_blorp_mip_info

View file

@ -1770,18 +1770,20 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
}
if (dst.map_stencil_as_y_tiled) {
/* We must modify the rectangle we send through the rendering pipeline,
* to account for the fact that we are mapping it as Y-tiled when it is
* in fact W-tiled. Y tiles have dimensions 128x32 whereas W tiles have
* dimensions 64x64. We must also align it to a multiple of the tile
* size, because the differences between W and Y tiling formats will
* mean that pixels are scrambled within the tile.
/* We must modify the rectangle we send through the rendering pipeline
* (and the size of the destination surface), to account for the fact
* that we are mapping it as Y-tiled when it is in fact W-tiled. Y
* tiles have dimensions 128x32 whereas W tiles have dimensions 64x64.
* We must also align it to a multiple of the tile size, because the
* differences between W and Y tiling formats will mean that pixels are
* scrambled within the tile.
*
* Note: if the destination surface configured to use IMS layout, then
* the effective tile size we need to align it to is smaller, because
* each pixel covers a 2x2 or a 4x2 block of samples.
*
* TODO: what if this makes the coordinates too large?
* TODO: what if this makes the coordinates (or the texture size) too
* large?
*/
unsigned x_align = 64, y_align = 64;
if (dst_mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
@ -1792,8 +1794,20 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
y0 = ROUND_DOWN_TO(y0, y_align) / 2;
x1 = ALIGN(x1, x_align) * 2;
y1 = ALIGN(y1, y_align) / 2;
dst.width *= 2;
dst.height /= 2;
wm_prog_key.use_kill = true;
}
if (src.map_stencil_as_y_tiled) {
/* We must modify the size of the source surface to account for the fact
* that we are mapping it as Y-tiled when it is in fact W tiled.
*
* TODO: what if this makes the texture size too large?
*/
src.width *= 2;
src.height /= 2;
}
}
uint32_t

View file

@ -413,8 +413,8 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
uint32_t read_domains, uint32_t write_domain)
{
uint32_t wm_surf_offset;
uint32_t width, height;
surface->get_miplevel_dims(&width, &height);
uint32_t width = surface->width;
uint32_t height = surface->height;
if (surface->num_samples > 1) {
/* Since gen6 uses INTEL_MSAA_LAYOUT_IMS, width and height are measured
* in samples. But SURFACE_STATE wants them in pixels, so we need to
@ -423,10 +423,6 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
width /= 2;
height /= 2;
}
if (surface->map_stencil_as_y_tiled) {
width *= 2;
height /= 2;
}
struct intel_region *region = surface->mt->region;
uint32_t *surf = (uint32_t *)
@ -835,9 +831,6 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
/* 3DSTATE_DEPTH_BUFFER */
{
uint32_t width, height;
params->depth.get_miplevel_dims(&width, &height);
uint32_t tile_x = draw_x & tile_mask_x;
uint32_t tile_y = draw_y & tile_mask_y;
uint32_t offset =
@ -881,8 +874,8 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
offset);
OUT_BATCH(BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1 |
(width + tile_x - 1) << 6 |
(height + tile_y - 1) << 19);
(params->depth.width + tile_x - 1) << 6 |
(params->depth.height + tile_y - 1) << 19);
OUT_BATCH(0);
OUT_BATCH(tile_x |
tile_y << 16);

View file

@ -142,17 +142,13 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
struct intel_context *intel = &brw->intel;
uint32_t wm_surf_offset;
uint32_t width, height;
surface->get_miplevel_dims(&width, &height);
uint32_t width = surface->width;
uint32_t height = surface->height;
/* Note: since gen7 uses INTEL_MSAA_LAYOUT_CMS or INTEL_MSAA_LAYOUT_UMS for
* color surfaces, width and height are measured in pixels; we don't need
* to divide them by 2 as we do for Gen6 (see
* gen6_blorp_emit_surface_state).
*/
if (surface->map_stencil_as_y_tiled) {
width *= 2;
height /= 2;
}
struct intel_region *region = surface->mt->region;
struct gen7_surface_state *surf = (struct gen7_surface_state *)
@ -582,9 +578,6 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
/* 3DSTATE_DEPTH_BUFFER */
{
uint32_t width, height;
params->depth.get_miplevel_dims(&width, &height);
uint32_t tile_x = draw_x & tile_mask_x;
uint32_t tile_y = draw_y & tile_mask_y;
uint32_t offset =
@ -624,8 +617,8 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
OUT_RELOC(params->depth.mt->region->bo,
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
offset);
OUT_BATCH((width + tile_x - 1) << 4 |
(height + tile_y - 1) << 18);
OUT_BATCH((params->depth.width + tile_x - 1) << 4 |
(params->depth.height + tile_y - 1) << 18);
OUT_BATCH(0);
OUT_BATCH(tile_x |
tile_y << 16);