Esempio n. 1
0
static void si_msaa_color_resolve(struct pipe_context *ctx,
				  const struct pipe_blit_info *info)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	struct pipe_screen *screen = ctx->screen;
	struct pipe_resource *tmp, templ;
	struct pipe_blit_info blit;
	unsigned sample_mask = ~0;

	assert(info->src.level == 0);
	assert(info->src.box.depth == 1);
	assert(info->dst.box.depth == 1);

	if (is_simple_msaa_resolve(info)) {
		r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
		util_blitter_custom_resolve_color(rctx->blitter,
						  info->dst.resource, info->dst.level,
						  info->dst.box.z,
						  info->src.resource, info->src.box.z,
						  sample_mask, rctx->custom_blend_resolve,
                                                  int_to_norm_format(info->dst.format));
		r600_blitter_end(ctx);
		return;
	}

	/* resolve into a temporary texture, then blit */
	templ.target = PIPE_TEXTURE_2D;
	templ.format = info->src.resource->format;
	templ.width0 = info->src.resource->width0;
	templ.height0 = info->src.resource->height0;
	templ.depth0 = 1;
	templ.array_size = 1;
	templ.last_level = 0;
	templ.nr_samples = 0;
	templ.usage = PIPE_USAGE_STATIC;
	templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
	templ.flags = R600_RESOURCE_FLAG_FORCE_TILING; /* dst must not have a linear layout */

	tmp = screen->resource_create(screen, &templ);

	/* resolve */
	r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
	util_blitter_custom_resolve_color(rctx->blitter,
					  tmp, 0, 0,
					  info->src.resource, info->src.box.z,
					  sample_mask, rctx->custom_blend_resolve,
                                          int_to_norm_format(tmp->format));
	r600_blitter_end(ctx);

	/* blit */
	blit = *info;
	blit.src.resource = tmp;
	blit.src.box.z = 0;

	r600_blitter_begin(ctx, R600_BLIT);
	util_blitter_blit(rctx->blitter, &blit);
	r600_blitter_end(ctx);

	pipe_resource_reference(&tmp, NULL);
}
Esempio n. 2
0
static void r600_color_resolve(struct pipe_context *ctx,
			       const struct pipe_resolve_info *info)
{
	struct r600_context *rctx = (struct r600_context *)ctx;
	struct pipe_screen *screen = ctx->screen;
	struct pipe_resource *tmp, templ;
	struct pipe_box box;
	unsigned sample_mask =
		rctx->chip_class == CAYMAN ? ~0 : ((1ull << MAX2(1, info->src.res->nr_samples)) - 1);

	assert((info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA);

	if (is_simple_resolve(info)) {
		r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
		util_blitter_custom_resolve_color(rctx->blitter,
						  info->dst.res, info->dst.level, info->dst.layer,
						  info->src.res, info->src.layer,
						  sample_mask, rctx->custom_blend_resolve);
		r600_blitter_end(ctx);
		return;
	}

	/* resolve into a temporary texture, then blit */
	templ.target = PIPE_TEXTURE_2D;
	templ.format = info->src.res->format;
	templ.width0 = info->src.res->width0;
	templ.height0 = info->src.res->height0;
	templ.depth0 = 1;
	templ.array_size = 1;
	templ.last_level = 0;
	templ.nr_samples = 0;
	templ.usage = PIPE_USAGE_STATIC;
	templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
	templ.flags = 0;

	tmp = screen->resource_create(screen, &templ);

	/* XXX use scissor, so that only the needed part of the resource is resolved */
	r600_blitter_begin(ctx, R600_COLOR_RESOLVE);
	util_blitter_custom_resolve_color(rctx->blitter,
					  tmp, 0, 0,
					  info->src.res, info->src.layer,
					  sample_mask, rctx->custom_blend_resolve);
	r600_blitter_end(ctx);

	/* this is correct for upside-down blits too */
	u_box_2d(info->src.x0,
		 info->src.y0,
		 info->src.x1 - info->src.x0,
		 info->src.y1 - info->src.y0, &box);

	r600_blitter_begin(ctx, R600_COPY_TEXTURE);
	util_blitter_copy_texture(rctx->blitter, info->dst.res, info->dst.level,
				  ~0, info->dst.x0, info->dst.y0, info->dst.layer,
				  tmp, 0, 0, &box);
	r600_blitter_end(ctx);

	pipe_resource_reference(&tmp, NULL);
}
Esempio n. 3
0
File: si_blit.c Progetto: ifzz/mesa
static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
				     const struct pipe_blit_info *info)
{
	struct si_context *sctx = (struct si_context*)ctx;
	struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
	unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
	unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
	enum pipe_format format = int_to_norm_format(info->dst.format);
	unsigned sample_mask = ~0;

	/* Hardware MSAA resolve doesn't work if SPI format = NORM16_ABGR and
	 * the format is R16G16. Use R16A16, which does work.
	 */
	if (format == PIPE_FORMAT_R16G16_UNORM)
		format = PIPE_FORMAT_R16A16_UNORM;
	if (format == PIPE_FORMAT_R16G16_SNORM)
		format = PIPE_FORMAT_R16A16_SNORM;

	if (info->src.resource->nr_samples > 1 &&
	    info->dst.resource->nr_samples <= 1 &&
	    util_max_layer(info->src.resource, 0) == 0 &&
	    util_max_layer(info->dst.resource, info->dst.level) == 0 &&
	    util_is_format_compatible(util_format_description(info->src.format),
				      util_format_description(info->dst.format)) &&
	    !util_format_is_pure_integer(format) &&
	    !util_format_is_depth_or_stencil(format) &&
	    !info->scissor_enable &&
	    (info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA &&
	    dst_width == info->src.resource->width0 &&
	    dst_height == info->src.resource->height0 &&
	    info->dst.box.x == 0 &&
	    info->dst.box.y == 0 &&
	    info->dst.box.width == dst_width &&
	    info->dst.box.height == dst_height &&
	    info->dst.box.depth == 1 &&
	    info->src.box.x == 0 &&
	    info->src.box.y == 0 &&
	    info->src.box.width == dst_width &&
	    info->src.box.height == dst_height &&
	    info->src.box.depth == 1 &&
	    dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
	    !(dst->surface.flags & RADEON_SURF_SCANOUT) &&
	    (!dst->cmask.size || !dst->dirty_level_mask) && /* dst cannot be fast-cleared */
	    !dst->dcc_offset) {
		si_blitter_begin(ctx, SI_COLOR_RESOLVE |
				 (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
		util_blitter_custom_resolve_color(sctx->blitter,
						  info->dst.resource, info->dst.level,
						  info->dst.box.z,
						  info->src.resource, info->src.box.z,
						  sample_mask, sctx->custom_blend_resolve,
						  format);
		si_blitter_end(ctx);
		return true;
	}
	return false;
}
Esempio n. 4
0
static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
				     const struct pipe_blit_info *info)
{
	struct r600_context *rctx = (struct r600_context*)ctx;
	struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
	unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
	unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
	enum pipe_format format = int_to_norm_format(info->dst.format);
	unsigned sample_mask =
		rctx->b.chip_class == CAYMAN ? ~0 :
		((1ull << MAX2(1, info->src.resource->nr_samples)) - 1);

	if (info->src.resource->nr_samples > 1 &&
	    info->dst.resource->nr_samples <= 1 &&
	    util_max_layer(info->src.resource, 0) == 0 &&
	    util_max_layer(info->dst.resource, info->dst.level) == 0 &&
	    info->dst.format == info->src.format &&
	    !util_format_is_pure_integer(format) &&
	    !util_format_is_depth_or_stencil(format) &&
	    !info->scissor_enable &&
	    (info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA &&
	    dst_width == info->src.resource->width0 &&
	    dst_height == info->src.resource->height0 &&
	    info->dst.box.x == 0 &&
	    info->dst.box.y == 0 &&
	    info->dst.box.width == dst_width &&
	    info->dst.box.height == dst_height &&
	    info->dst.box.depth == 1 &&
	    info->src.box.x == 0 &&
	    info->src.box.y == 0 &&
	    info->src.box.width == dst_width &&
	    info->src.box.height == dst_height &&
	    info->src.box.depth == 1 &&
	    dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
	    (!dst->cmask.size || !dst->dirty_level_mask) /* dst cannot be fast-cleared */) {
		r600_blitter_begin(ctx, R600_COLOR_RESOLVE |
				   (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND));
		util_blitter_custom_resolve_color(rctx->blitter,
						  info->dst.resource, info->dst.level,
						  info->dst.box.z,
						  info->src.resource, info->src.box.z,
						  sample_mask, rctx->custom_blend_resolve,
						  format);
		r600_blitter_end(ctx);
		return true;
	}
	return false;
}
Esempio n. 5
0
static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
				     const struct pipe_blit_info *info)
{
	struct si_context *sctx = (struct si_context*)ctx;
	struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
	unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
	unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
	enum pipe_format format = int_to_norm_format(info->dst.format);
	unsigned sample_mask = ~0;

	if (info->src.resource->nr_samples > 1 &&
	    info->dst.resource->nr_samples <= 1 &&
	    util_max_layer(info->src.resource, 0) == 0 &&
	    util_max_layer(info->dst.resource, info->dst.level) == 0 &&
	    info->dst.format == info->src.format &&
	    !util_format_is_pure_integer(format) &&
	    !util_format_is_depth_or_stencil(format) &&
	    !info->scissor_enable &&
	    (info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA &&
	    dst_width == info->src.resource->width0 &&
	    dst_height == info->src.resource->height0 &&
	    info->dst.box.x == 0 &&
	    info->dst.box.y == 0 &&
	    info->dst.box.width == dst_width &&
	    info->dst.box.height == dst_height &&
	    info->dst.box.depth == 1 &&
	    info->src.box.x == 0 &&
	    info->src.box.y == 0 &&
	    info->src.box.width == dst_width &&
	    info->src.box.height == dst_height &&
	    info->src.box.depth == 1 &&
	    dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
	    !(dst->surface.flags & RADEON_SURF_SCANOUT)) {
		si_blitter_begin(ctx, SI_COLOR_RESOLVE);
		util_blitter_custom_resolve_color(sctx->blitter,
						  info->dst.resource, info->dst.level,
						  info->dst.box.z,
						  info->src.resource, info->src.box.z,
						  sample_mask, sctx->custom_blend_resolve,
						  format);
		si_blitter_end(ctx);
		return true;
	}
	return false;
}
Esempio n. 6
0
static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
                                     const struct pipe_blit_info *info)
{
    struct r600_context *rctx = (struct r600_context*)ctx;
    struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
    unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
    unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
    enum pipe_format format = info->src.format;
    unsigned sample_mask =
        rctx->b.chip_class == CAYMAN ? ~0 :
        ((1ull << MAX2(1, info->src.resource->nr_samples)) - 1);
    struct pipe_resource *tmp, templ;
    struct pipe_blit_info blit;

    /* Check basic requirements for hw resolve. */
    if (!(info->src.resource->nr_samples > 1 &&
            info->dst.resource->nr_samples <= 1 &&
            !util_format_is_pure_integer(format) &&
            !util_format_is_depth_or_stencil(format) &&
            util_max_layer(info->src.resource, 0) == 0))
        return false;

    /* Check the remaining requirements for hw resolve. */
    if (util_max_layer(info->dst.resource, info->dst.level) == 0 &&
            util_is_format_compatible(util_format_description(info->src.format),
                                      util_format_description(info->dst.format)) &&
            !info->scissor_enable &&
            (info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA &&
            dst_width == info->src.resource->width0 &&
            dst_height == info->src.resource->height0 &&
            info->dst.box.x == 0 &&
            info->dst.box.y == 0 &&
            info->dst.box.width == dst_width &&
            info->dst.box.height == dst_height &&
            info->dst.box.depth == 1 &&
            info->src.box.x == 0 &&
            info->src.box.y == 0 &&
            info->src.box.width == dst_width &&
            info->src.box.height == dst_height &&
            info->src.box.depth == 1 &&
            dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
            (!dst->cmask.size || !dst->dirty_level_mask) /* dst cannot be fast-cleared */) {
        r600_blitter_begin(ctx, R600_COLOR_RESOLVE |
                           (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND));
        util_blitter_custom_resolve_color(rctx->blitter,
                                          info->dst.resource, info->dst.level,
                                          info->dst.box.z,
                                          info->src.resource, info->src.box.z,
                                          sample_mask, rctx->custom_blend_resolve,
                                          format);
        r600_blitter_end(ctx);
        return true;
    }

    /* Shader-based resolve is VERY SLOW. Instead, resolve into
     * a temporary texture and blit.
     */
    memset(&templ, 0, sizeof(templ));
    templ.target = PIPE_TEXTURE_2D;
    templ.format = info->src.resource->format;
    templ.width0 = info->src.resource->width0;
    templ.height0 = info->src.resource->height0;
    templ.depth0 = 1;
    templ.array_size = 1;
    templ.usage = PIPE_USAGE_DEFAULT;
    templ.flags = R600_RESOURCE_FLAG_FORCE_TILING;

    tmp = ctx->screen->resource_create(ctx->screen, &templ);
    if (!tmp)
        return false;

    /* resolve */
    r600_blitter_begin(ctx, R600_COLOR_RESOLVE |
                       (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND));
    util_blitter_custom_resolve_color(rctx->blitter, tmp, 0, 0,
                                      info->src.resource, info->src.box.z,
                                      sample_mask, rctx->custom_blend_resolve,
                                      format);
    r600_blitter_end(ctx);

    /* blit */
    blit = *info;
    blit.src.resource = tmp;
    blit.src.box.z = 0;

    r600_blitter_begin(ctx, R600_BLIT |
                       (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND));
    util_blitter_blit(rctx->blitter, &blit);
    r600_blitter_end(ctx);

    pipe_resource_reference(&tmp, NULL);
    return true;
}
Esempio n. 7
0
static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
				     const struct pipe_blit_info *info)
{
	struct si_context *sctx = (struct si_context*)ctx;
	struct r600_texture *src = (struct r600_texture*)info->src.resource;
	struct r600_texture *dst = (struct r600_texture*)info->dst.resource;
	unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
	unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);
	enum pipe_format format = info->src.format;
	unsigned sample_mask = ~0;
	struct pipe_resource *tmp, templ;
	struct pipe_blit_info blit;

	/* Check basic requirements for hw resolve. */
	if (!(info->src.resource->nr_samples > 1 &&
	      info->dst.resource->nr_samples <= 1 &&
	      !util_format_is_pure_integer(format) &&
	      !util_format_is_depth_or_stencil(format) &&
	      util_max_layer(info->src.resource, 0) == 0))
		return false;

	/* Hardware MSAA resolve doesn't work if SPI format = NORM16_ABGR and
	 * the format is R16G16. Use R16A16, which does work.
	 */
	if (format == PIPE_FORMAT_R16G16_UNORM)
		format = PIPE_FORMAT_R16A16_UNORM;
	if (format == PIPE_FORMAT_R16G16_SNORM)
		format = PIPE_FORMAT_R16A16_SNORM;

	/* Check the remaining requirements for hw resolve. */
	if (util_max_layer(info->dst.resource, info->dst.level) == 0 &&
	    !info->scissor_enable &&
	    (info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA &&
	    util_is_format_compatible(util_format_description(info->src.format),
				      util_format_description(info->dst.format)) &&
	    dst_width == info->src.resource->width0 &&
	    dst_height == info->src.resource->height0 &&
	    info->dst.box.x == 0 &&
	    info->dst.box.y == 0 &&
	    info->dst.box.width == dst_width &&
	    info->dst.box.height == dst_height &&
	    info->dst.box.depth == 1 &&
	    info->src.box.x == 0 &&
	    info->src.box.y == 0 &&
	    info->src.box.width == dst_width &&
	    info->src.box.height == dst_height &&
	    info->src.box.depth == 1 &&
	    dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
	    (!dst->cmask.size || !dst->dirty_level_mask)) { /* dst cannot be fast-cleared */
		/* Check the last constraint. */
		if (src->surface.micro_tile_mode != dst->surface.micro_tile_mode) {
			/* The next fast clear will switch to this mode to
			 * get direct hw resolve next time if the mode is
			 * different now.
			 */
			src->last_msaa_resolve_target_micro_mode =
				dst->surface.micro_tile_mode;
			goto resolve_to_temp;
		}

		/* Resolving into a surface with DCC is unsupported. Since
		 * it's being overwritten anyway, clear it to uncompressed.
		 * This is still the fastest codepath even with this clear.
		 */
		if (dst->dcc_offset &&
		    dst->surface.level[info->dst.level].dcc_enabled) {
			vi_dcc_clear_level(&sctx->b, dst, info->dst.level,
					   0xFFFFFFFF);
			dst->dirty_level_mask &= ~(1 << info->dst.level);
		}

		/* Resolve directly from src to dst. */
		si_blitter_begin(ctx, SI_COLOR_RESOLVE |
				 (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
		util_blitter_custom_resolve_color(sctx->blitter,
						  info->dst.resource, info->dst.level,
						  info->dst.box.z,
						  info->src.resource, info->src.box.z,
						  sample_mask, sctx->custom_blend_resolve,
						  format);
		si_blitter_end(ctx);
		return true;
	}

resolve_to_temp:
	/* Shader-based resolve is VERY SLOW. Instead, resolve into
	 * a temporary texture and blit.
	 */
	memset(&templ, 0, sizeof(templ));
	templ.target = PIPE_TEXTURE_2D;
	templ.format = info->src.resource->format;
	templ.width0 = info->src.resource->width0;
	templ.height0 = info->src.resource->height0;
	templ.depth0 = 1;
	templ.array_size = 1;
	templ.usage = PIPE_USAGE_DEFAULT;
	templ.flags = R600_RESOURCE_FLAG_FORCE_TILING |
		      R600_RESOURCE_FLAG_DISABLE_DCC;

	/* The src and dst microtile modes must be the same. */
	if (src->surface.micro_tile_mode == V_009910_ADDR_SURF_DISPLAY_MICRO_TILING)
		templ.bind = PIPE_BIND_SCANOUT;
	else
		templ.bind = 0;

	tmp = ctx->screen->resource_create(ctx->screen, &templ);
	if (!tmp)
		return false;

	assert(src->surface.micro_tile_mode ==
	       ((struct r600_texture*)tmp)->surface.micro_tile_mode);

	/* resolve */
	si_blitter_begin(ctx, SI_COLOR_RESOLVE |
			 (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
	util_blitter_custom_resolve_color(sctx->blitter, tmp, 0, 0,
					  info->src.resource, info->src.box.z,
					  sample_mask, sctx->custom_blend_resolve,
					  format);
	si_blitter_end(ctx);

	/* blit */
	blit = *info;
	blit.src.resource = tmp;
	blit.src.box.z = 0;

	si_blitter_begin(ctx, SI_BLIT |
			 (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
	util_blitter_blit(sctx->blitter, &blit);
	si_blitter_end(ctx);

	pipe_resource_reference(&tmp, NULL);
	return true;
}