/* Common processing for r600_texture_create and r600_texture_from_handle */
static struct r600_texture *
r600_texture_create_object(struct pipe_screen *screen,
			   const struct pipe_resource *base,
			   unsigned pitch_in_bytes_override,
			   struct pb_buffer *buf,
			   struct radeon_surf *surface)
{
	struct r600_texture *rtex;
	struct r600_resource *resource;
	struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;

	rtex = CALLOC_STRUCT(r600_texture);
	if (rtex == NULL)
		return NULL;

	resource = &rtex->resource;
	resource->b.b = *base;
	resource->b.vtbl = &r600_texture_vtbl;
	pipe_reference_init(&resource->b.b.reference, 1);
	resource->b.b.screen = screen;
	rtex->pitch_override = pitch_in_bytes_override;

	/* don't include stencil-only formats which we don't support for rendering */
	rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));

	rtex->surface = *surface;
	if (r600_setup_surface(screen, rtex, pitch_in_bytes_override)) {
		FREE(rtex);
		return NULL;
	}

	/* Tiled depth textures utilize the non-displayable tile order.
	 * This must be done after r600_setup_surface.
	 * Applies to R600-Cayman. */
	rtex->non_disp_tiling = rtex->is_depth && rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D;

	if (rtex->is_depth) {
		if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER |
				     R600_RESOURCE_FLAG_FLUSHED_DEPTH)) &&
		    !(rscreen->debug_flags & DBG_NO_HYPERZ)) {

			r600_texture_allocate_htile(rscreen, rtex);
		}
	} else {
		if (base->nr_samples > 1) {
			if (!buf) {
				r600_texture_allocate_fmask(rscreen, rtex);
				r600_texture_allocate_cmask(rscreen, rtex);
				rtex->cmask_buffer = &rtex->resource;
			}
			if (!rtex->fmask.size || !rtex->cmask.size) {
				FREE(rtex);
				return NULL;
			}
		}
	}

	/* Now create the backing buffer. */
	if (!buf) {
		if (!r600_init_resource(rscreen, resource, rtex->size,
					rtex->surface.bo_alignment, TRUE)) {
			FREE(rtex);
			return NULL;
		}
	} else {
		resource->buf = buf;
		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
		resource->gpu_address = rscreen->ws->buffer_get_virtual_address(resource->cs_buf);
		resource->domains = rscreen->ws->buffer_get_initial_domain(resource->cs_buf);
	}

	if (rtex->cmask.size) {
		/* Initialize the cmask to 0xCC (= compressed state). */
		r600_screen_clear_buffer(rscreen, &rtex->cmask_buffer->b.b,
					 rtex->cmask.offset, rtex->cmask.size,
					 0xCCCCCCCC, true);
	}

	/* Initialize the CMASK base register value. */
	rtex->cmask.base_address_reg =
		(rtex->resource.gpu_address + rtex->cmask.offset) >> 8;

	if (rscreen->debug_flags & DBG_VM) {
		fprintf(stderr, "VM start=0x%"PRIX64"  end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n",
			rtex->resource.gpu_address,
			rtex->resource.gpu_address + rtex->resource.buf->size,
			base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1,
			base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
	}

	if (rscreen->debug_flags & DBG_TEX ||
	    (rtex->resource.b.b.last_level > 0 && rscreen->debug_flags & DBG_TEXMIP)) {
		printf("Texture: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, "
		       "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, "
		       "bpe=%u, nsamples=%u, flags=0x%x, %s\n",
		       rtex->surface.npix_x, rtex->surface.npix_y,
		       rtex->surface.npix_z, rtex->surface.blk_w,
		       rtex->surface.blk_h, rtex->surface.blk_d,
		       rtex->surface.array_size, rtex->surface.last_level,
		       rtex->surface.bpe, rtex->surface.nsamples,
		       rtex->surface.flags, util_format_short_name(base->format));
		for (int i = 0; i <= rtex->surface.last_level; i++) {
			printf("  L %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, "
			       "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
			       "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
			       i, rtex->surface.level[i].offset,
			       rtex->surface.level[i].slice_size,
			       u_minify(rtex->resource.b.b.width0, i),
			       u_minify(rtex->resource.b.b.height0, i),
			       u_minify(rtex->resource.b.b.depth0, i),
			       rtex->surface.level[i].nblk_x,
			       rtex->surface.level[i].nblk_y,
			       rtex->surface.level[i].nblk_z,
			       rtex->surface.level[i].pitch_bytes,
			       rtex->surface.level[i].mode);
		}
		if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
			for (int i = 0; i <= rtex->surface.last_level; i++) {
				printf("  S %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, "
				       "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
				       "nblk_z=%u, pitch_bytes=%u, mode=%u\n",
				       i, rtex->surface.stencil_level[i].offset,
				       rtex->surface.stencil_level[i].slice_size,
				       u_minify(rtex->resource.b.b.width0, i),
				       u_minify(rtex->resource.b.b.height0, i),
				       u_minify(rtex->resource.b.b.depth0, i),
				       rtex->surface.stencil_level[i].nblk_x,
				       rtex->surface.stencil_level[i].nblk_y,
				       rtex->surface.stencil_level[i].nblk_z,
				       rtex->surface.stencil_level[i].pitch_bytes,
				       rtex->surface.stencil_level[i].mode);
			}
		}
	}
	return rtex;
}
Exemple #2
0
/* Common processing for r600_texture_create and r600_texture_from_handle */
static struct r600_texture *
r600_texture_create_object(struct pipe_screen *screen,
			   const struct pipe_resource *base,
			   unsigned pitch_in_bytes_override,
			   struct pb_buffer *buf,
			   struct radeon_surf *surface)
{
	struct r600_texture *rtex;
	struct r600_resource *resource;
	struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;

	rtex = CALLOC_STRUCT(r600_texture);
	if (!rtex)
		return NULL;

	resource = &rtex->resource;
	resource->b.b = *base;
	resource->b.vtbl = &r600_texture_vtbl;
	pipe_reference_init(&resource->b.b.reference, 1);
	resource->b.b.screen = screen;

	/* don't include stencil-only formats which we don't support for rendering */
	rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));

	rtex->surface = *surface;
	if (r600_setup_surface(screen, rtex, pitch_in_bytes_override)) {
		FREE(rtex);
		return NULL;
	}

	/* Tiled depth textures utilize the non-displayable tile order.
	 * This must be done after r600_setup_surface.
	 * Applies to R600-Cayman. */
	rtex->non_disp_tiling = rtex->is_depth && rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D;

	if (rtex->is_depth) {
		if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER |
				     R600_RESOURCE_FLAG_FLUSHED_DEPTH)) &&
		    !(rscreen->debug_flags & DBG_NO_HYPERZ)) {

			r600_texture_allocate_htile(rscreen, rtex);
		}
	} else {
		if (base->nr_samples > 1) {
			if (!buf) {
				r600_texture_allocate_fmask(rscreen, rtex);
				r600_texture_allocate_cmask(rscreen, rtex);
				rtex->cmask_buffer = &rtex->resource;
			}
			if (!rtex->fmask.size || !rtex->cmask.size) {
				FREE(rtex);
				return NULL;
			}
		}
		if (rtex->surface.dcc_size)
			vi_texture_alloc_dcc_separate(rscreen, rtex);
	}

	/* Now create the backing buffer. */
	if (!buf) {
		if (!r600_init_resource(rscreen, resource, rtex->size,
					rtex->surface.bo_alignment, TRUE)) {
			FREE(rtex);
			return NULL;
		}
	} else {
		resource->buf = buf;
		resource->gpu_address = rscreen->ws->buffer_get_virtual_address(resource->buf);
		resource->domains = rscreen->ws->buffer_get_initial_domain(resource->buf);
	}

	if (rtex->cmask.size) {
		/* Initialize the cmask to 0xCC (= compressed state). */
		r600_screen_clear_buffer(rscreen, &rtex->cmask_buffer->b.b,
					 rtex->cmask.offset, rtex->cmask.size,
					 0xCCCCCCCC, true);
	}

	/* Initialize the CMASK base register value. */
	rtex->cmask.base_address_reg =
		(rtex->resource.gpu_address + rtex->cmask.offset) >> 8;

	if (rscreen->debug_flags & DBG_VM) {
		fprintf(stderr, "VM start=0x%"PRIX64"  end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n",
			rtex->resource.gpu_address,
			rtex->resource.gpu_address + rtex->resource.buf->size,
			base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1,
			base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
	}

	if (rscreen->debug_flags & DBG_TEX) {
		puts("Texture:");
		r600_print_texture_info(rtex, stdout);
	}

	return rtex;
}