i965/blorp: Add a new brw_blorp_surf intermediate struct

At the moment, this seems to make all of the interfaces messier rather than
clener.  However, it does provide a representation of a surface that
simultaneously contains everything and is completely unaware of miptrees.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
This commit is contained in:
Jason Ekstrand
2016-07-19 19:04:03 -07:00
parent 57664c869f
commit 75deae9c90
4 changed files with 188 additions and 99 deletions
+121 -89
View File
@@ -64,31 +64,17 @@ apply_gen6_stencil_hiz_offset(struct isl_surf *surf,
}
void
brw_blorp_surface_info_init(struct brw_context *brw,
struct brw_blorp_surface_info *info,
struct intel_mipmap_tree *mt,
unsigned int level, unsigned int layer,
mesa_format format, bool is_render_target)
brw_blorp_surf_for_miptree(struct brw_context *brw,
struct brw_blorp_surf *surf,
struct intel_mipmap_tree *mt,
bool is_render_target,
unsigned *level,
struct isl_surf tmp_surfs[2])
{
/* Layer is a physical layer, so if this is a 2D multisample array texture
* using INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, then it had better
* be a multiple of num_samples.
*/
unsigned layer_multiplier = 1;
if (mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS ||
mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
assert(mt->num_samples <= 1 || layer % mt->num_samples == 0);
layer_multiplier = MAX2(mt->num_samples, 1);
}
intel_miptree_check_level_layer(mt, level, layer);
if (is_render_target)
intel_miptree_used_for_rendering(mt);
intel_miptree_get_isl_surf(brw, mt, &info->surf);
info->bo = mt->bo;
info->offset = mt->offset;
intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]);
surf->surf = &tmp_surfs[0];
surf->bo = mt->bo;
surf->offset = mt->offset;
if (brw->gen == 6 && mt->format == MESA_FORMAT_S_UINT8 &&
mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
@@ -103,61 +89,140 @@ brw_blorp_surface_info_init(struct brw_context *brw,
* See also gen6_depth_stencil_state.c
*/
uint32_t offset;
apply_gen6_stencil_hiz_offset(&info->surf, mt, level, &offset);
info->offset += offset;
level = 0;
apply_gen6_stencil_hiz_offset(&tmp_surfs[0], mt, *level, &offset);
surf->offset += offset;
*level = 0;
}
intel_miptree_get_aux_isl_surf(brw, mt, &info->aux_surf,
&info->aux_usage);
struct isl_surf *aux_surf = &tmp_surfs[1];
intel_miptree_get_aux_isl_surf(brw, mt, aux_surf, &surf->aux_usage);
/* For textures that are in the RESOLVED state, we ignore the MCS */
if (mt->mcs_mt && !is_render_target &&
mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED)
info->aux_usage = ISL_AUX_USAGE_NONE;
surf->aux_usage = ISL_AUX_USAGE_NONE;
if (info->aux_usage != ISL_AUX_USAGE_NONE) {
if (surf->aux_usage != ISL_AUX_USAGE_NONE) {
/* We only really need a clear color if we also have an auxiliary
* surface. Without one, it does nothing.
*/
info->clear_color = intel_miptree_get_isl_clear_color(brw, mt);
surf->clear_color = intel_miptree_get_isl_clear_color(brw, mt);
surf->aux_surf = aux_surf;
if (mt->mcs_mt) {
info->aux_bo = mt->mcs_mt->bo;
info->aux_offset = mt->mcs_mt->offset;
surf->aux_bo = mt->mcs_mt->bo;
surf->aux_offset = mt->mcs_mt->offset;
} else {
assert(info->aux_usage == ISL_AUX_USAGE_HIZ);
assert(surf->aux_usage == ISL_AUX_USAGE_HIZ);
struct intel_mipmap_tree *hiz_mt = mt->hiz_buf->mt;
if (hiz_mt) {
info->aux_bo = hiz_mt->bo;
surf->aux_bo = hiz_mt->bo;
if (brw->gen == 6 &&
hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
/* gen6 requires the HiZ buffer to be manually offset to the
* right location. We could fixup the surf but it doesn't
* matter since most of those fields don't matter.
*/
apply_gen6_stencil_hiz_offset(&info->aux_surf, hiz_mt, level,
&info->aux_offset);
apply_gen6_stencil_hiz_offset(aux_surf, hiz_mt, *level,
&surf->aux_offset);
} else {
info->aux_offset = 0;
surf->aux_offset = 0;
}
assert(hiz_mt->pitch == info->aux_surf.row_pitch);
assert(hiz_mt->pitch == aux_surf->row_pitch);
} else {
info->aux_bo = mt->hiz_buf->bo;
info->aux_offset = 0;
surf->aux_bo = mt->hiz_buf->bo;
surf->aux_offset = 0;
}
}
} else {
info->aux_bo = NULL;
info->aux_offset = 0;
memset(&info->clear_color, 0, sizeof(info->clear_color));
surf->aux_bo = NULL;
surf->aux_offset = 0;
memset(&surf->clear_color, 0, sizeof(surf->clear_color));
}
assert((info->aux_usage == ISL_AUX_USAGE_NONE) == (info->aux_bo == NULL));
assert((surf->aux_usage == ISL_AUX_USAGE_NONE) == (surf->aux_bo == NULL));
}
enum isl_format
brw_blorp_to_isl_format(struct brw_context *brw, mesa_format format,
bool is_render_target)
{
switch (format) {
case MESA_FORMAT_NONE:
return ISL_FORMAT_UNSUPPORTED;
case MESA_FORMAT_S_UINT8:
return ISL_FORMAT_R8_UINT;
case MESA_FORMAT_Z24_UNORM_X8_UINT:
return ISL_FORMAT_R24_UNORM_X8_TYPELESS;
case MESA_FORMAT_Z_FLOAT32:
return ISL_FORMAT_R32_FLOAT;
case MESA_FORMAT_Z_UNORM16:
return ISL_FORMAT_R16_UNORM;
default: {
if (is_render_target) {
assert(brw->format_supported_as_render_target[format]);
return brw->render_target_format[format];
} else {
return brw_format_for_mesa_format(format);
}
break;
}
}
}
void
brw_blorp_surface_info_init(struct brw_context *brw,
struct brw_blorp_surface_info *info,
const struct brw_blorp_surf *surf,
unsigned int level, unsigned int layer,
enum isl_format format, bool is_render_target)
{
/* Layer is a physical layer, so if this is a 2D multisample array texture
* using INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, then it had better
* be a multiple of num_samples.
*/
unsigned layer_multiplier = 1;
if (surf->surf->msaa_layout == ISL_MSAA_LAYOUT_ARRAY) {
assert(layer % surf->surf->samples == 0);
layer_multiplier = surf->surf->samples;
}
if (format == ISL_FORMAT_UNSUPPORTED)
format = surf->surf->format;
if (format == ISL_FORMAT_R24_UNORM_X8_TYPELESS) {
/* Unfortunately, ISL_FORMAT_R24_UNORM_X8_TYPELESS it isn't supported as
* a render target, which would prevent us from blitting to 24-bit
* depth. The miptree consists of 32 bits per pixel, arranged as 24-bit
* depth values interleaved with 8 "don't care" bits. Since depth
* values don't require any blending, it doesn't matter how we interpret
* the bit pattern as long as we copy the right amount of data, so just
* map it as 8-bit BGRA.
*/
format = ISL_FORMAT_B8G8R8A8_UNORM;
} else if (surf->surf->usage & ISL_SURF_USAGE_STENCIL_BIT) {
assert(surf->surf->format == ISL_FORMAT_R8_UINT);
/* Prior to Broadwell, we can't render to R8_UINT */
if (brw->gen < 8)
format = ISL_FORMAT_R8_UNORM;
}
info->surf = *surf->surf;
info->bo = surf->bo;
info->offset = surf->offset;
info->aux_usage = surf->aux_usage;
if (info->aux_usage != ISL_AUX_USAGE_NONE) {
info->aux_surf = *surf->aux_surf;
info->aux_bo = surf->aux_bo;
info->aux_offset = surf->aux_offset;
}
info->clear_color = surf->clear_color;
info->view = (struct isl_view) {
.usage = is_render_target ? ISL_SURF_USAGE_RENDER_TARGET_BIT :
ISL_SURF_USAGE_TEXTURE_BIT,
.format = ISL_FORMAT_UNSUPPORTED, /* Set later */
.format = format,
.base_level = level,
.levels = 1,
.channel_select = {
@@ -185,46 +250,6 @@ brw_blorp_surface_info_init(struct brw_context *brw,
info->view.array_len = 1;
info->z_offset = 0;
}
if (format == MESA_FORMAT_NONE)
format = mt->format;
switch (format) {
case MESA_FORMAT_S_UINT8:
assert(info->surf.tiling == ISL_TILING_W);
/* Prior to Broadwell, we can't render to R8_UINT */
info->view.format = brw->gen >= 8 ? BRW_SURFACEFORMAT_R8_UINT :
BRW_SURFACEFORMAT_R8_UNORM;
break;
case MESA_FORMAT_Z24_UNORM_X8_UINT:
/* It would make sense to use BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS
* here, but unfortunately it isn't supported as a render target, which
* would prevent us from blitting to 24-bit depth.
*
* The miptree consists of 32 bits per pixel, arranged as 24-bit depth
* values interleaved with 8 "don't care" bits. Since depth values don't
* require any blending, it doesn't matter how we interpret the bit
* pattern as long as we copy the right amount of data, so just map it
* as 8-bit BGRA.
*/
info->view.format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
break;
case MESA_FORMAT_Z_FLOAT32:
info->view.format = BRW_SURFACEFORMAT_R32_FLOAT;
break;
case MESA_FORMAT_Z_UNORM16:
info->view.format = BRW_SURFACEFORMAT_R16_UNORM;
break;
default: {
if (is_render_target) {
assert(brw->format_supported_as_render_target[format]);
info->view.format = brw->render_target_format[format];
} else {
info->view.format = brw_format_for_mesa_format(format);
}
break;
}
}
}
@@ -534,8 +559,15 @@ gen6_blorp_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
params.hiz_op = op;
brw_blorp_surface_info_init(brw, &params.depth, mt, level, layer,
mt->format, true);
intel_miptree_check_level_layer(mt, level, layer);
intel_miptree_used_for_rendering(mt);
struct isl_surf isl_tmp[2];
struct brw_blorp_surf surf;
brw_blorp_surf_for_miptree(brw, &surf, mt, true, &level, isl_tmp);
brw_blorp_surface_info_init(brw, &params.depth, &surf, level, layer,
brw_blorp_to_isl_format(brw, mt->format, true),
true);
/* Align the rectangle primitive to 8x4 pixels.
*
+28 -2
View File
@@ -35,6 +35,32 @@ struct brw_wm_prog_key;
extern "C" {
#endif
struct brw_blorp_surf
{
const struct isl_surf *surf;
drm_intel_bo *bo;
uint32_t offset;
const struct isl_surf *aux_surf;
drm_intel_bo *aux_bo;
uint32_t aux_offset;
enum isl_aux_usage aux_usage;
union isl_color_value clear_color;
};
void
brw_blorp_surf_for_miptree(struct brw_context *brw,
struct brw_blorp_surf *surf,
struct intel_mipmap_tree *mt,
bool is_render_target,
unsigned *level,
struct isl_surf tmp_surfs[2]);
enum isl_format
brw_blorp_to_isl_format(struct brw_context *brw, mesa_format format,
bool is_render_target);
void
brw_blorp_blit_miptrees(struct brw_context *brw,
struct intel_mipmap_tree *src_mt,
@@ -91,9 +117,9 @@ struct brw_blorp_surface_info
void
brw_blorp_surface_info_init(struct brw_context *brw,
struct brw_blorp_surface_info *info,
struct intel_mipmap_tree *mt,
const struct brw_blorp_surf *surf,
unsigned int level, unsigned int layer,
mesa_format format, bool is_render_target);
enum isl_format format, bool is_render_target);
struct brw_blorp_coord_transform
+18 -4
View File
@@ -1746,13 +1746,27 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
src_format = dst_format = MESA_FORMAT_R_FLOAT32;
}
intel_miptree_check_level_layer(src_mt, src_level, src_layer);
intel_miptree_check_level_layer(dst_mt, dst_level, dst_layer);
intel_miptree_used_for_rendering(dst_mt);
struct brw_blorp_params params;
brw_blorp_params_init(&params);
brw_blorp_surface_info_init(brw, &params.src, src_mt, src_level,
src_layer, src_format, false);
brw_blorp_surface_info_init(brw, &params.dst, dst_mt, dst_level,
dst_layer, dst_format, true);
struct isl_surf isl_tmp[4];
struct brw_blorp_surf src_surf, dst_surf;
brw_blorp_surf_for_miptree(brw, &src_surf, src_mt, false,
&src_level, &isl_tmp[0]);
brw_blorp_surface_info_init(brw, &params.src,
&src_surf, src_level, src_layer,
brw_blorp_to_isl_format(brw, src_format, false),
false);
brw_blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true,
&dst_level, &isl_tmp[2]);
brw_blorp_surface_info_init(brw, &params.dst,
&dst_surf, dst_level, dst_layer,
brw_blorp_to_isl_format(brw, dst_format, true),
true);
struct brw_blorp_blit_prog_key wm_prog_key;
memset(&wm_prog_key, 0, sizeof(wm_prog_key));
+21 -4
View File
@@ -212,8 +212,16 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
}
}
brw_blorp_surface_info_init(brw, &params.dst, irb->mt, irb->mt_level,
layer, format, true);
intel_miptree_check_level_layer(irb->mt, irb->mt_level, layer);
intel_miptree_used_for_rendering(irb->mt);
struct isl_surf isl_tmp[2];
struct brw_blorp_surf surf;
unsigned level = irb->mt_level;
brw_blorp_surf_for_miptree(brw, &surf, irb->mt, true, &level, isl_tmp);
brw_blorp_surface_info_init(brw, &params.dst, &surf, level, layer,
brw_blorp_to_isl_format(brw, format, true),
true);
/* Override the surface format according to the context's sRGB rules. */
params.dst.view.format = (enum isl_format)brw->render_target_format[format];
@@ -303,11 +311,20 @@ brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt)
const mesa_format format = _mesa_get_srgb_format_linear(mt->format);
intel_miptree_check_level_layer(mt, 0 /* level */, 0 /* layer */);
intel_miptree_used_for_rendering(mt);
struct brw_blorp_params params;
brw_blorp_params_init(&params);
brw_blorp_surface_info_init(brw, &params.dst, mt,
0 /* level */, 0 /* layer */, format, true);
struct isl_surf isl_tmp[2];
struct brw_blorp_surf surf;
unsigned level = 0;
brw_blorp_surf_for_miptree(brw, &surf, mt, true, &level, isl_tmp);
brw_blorp_surface_info_init(brw, &params.dst, &surf,
0 /* level */, 0 /* layer */,
brw_blorp_to_isl_format(brw, format, true),
true);
brw_get_resolve_rect(brw, mt, &params.x0, &params.y0,
&params.x1, &params.y1);