示例#1
0
文件: r600_texture.c 项目: altf4/mesa
static struct r600_resource_texture *
r600_texture_create_object(struct pipe_screen *screen,
			   const struct pipe_resource *base,
			   unsigned array_mode,
			   unsigned pitch_in_bytes_override,
			   unsigned max_buffer_size,
			   struct pb_buffer *buf,
			   boolean alloc_bo,
			   struct radeon_surface *surface)
{
	struct r600_resource_texture *rtex;
	struct si_resource *resource;
	struct r600_screen *rscreen = (struct r600_screen*)screen;
	int r;

	rtex = CALLOC_STRUCT(r600_resource_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;
	rtex->real_format = base->format;

	/* only mark depth textures the HW can hit as depth textures */
	if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base))
		rtex->depth = 1;

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

	/* Now create the backing buffer. */
	if (!buf && alloc_bo) {
		struct pipe_resource *ptex = &rtex->resource.b.b;
		unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode);

		base_align = rtex->surface.bo_alignment;
		if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) {
			FREE(rtex);
			return NULL;
		}
	} else if (buf) {
		resource->buf = buf;
		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
		resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
	}

	return rtex;
}
示例#2
0
static void r600_setup_miptree(struct pipe_screen *screen,
			       struct r600_resource_texture *rtex,
			       unsigned array_mode)
{
	struct pipe_resource *ptex = &rtex->resource.b.b;
	enum chip_class chipc = ((struct r600_screen*)screen)->chip_class;
	unsigned size, layer_size, i, offset;
	unsigned nblocksx, nblocksy;

	for (i = 0, offset = 0; i <= ptex->last_level; i++) {
		unsigned blocksize = util_format_get_blocksize(rtex->real_format);
		unsigned base_align = r600_get_base_alignment(screen, rtex->real_format, array_mode);

		r600_texture_set_array_mode(screen, rtex, i, array_mode);

		nblocksx = r600_texture_get_nblocksx(screen, rtex, i);
		nblocksy = r600_texture_get_nblocksy(screen, rtex, i);

		if (array_mode == V_009910_ARRAY_LINEAR_GENERAL)
			layer_size = align(nblocksx, 64) * nblocksy * blocksize;
		else
			layer_size = nblocksx * nblocksy * blocksize;

		if (ptex->target == PIPE_TEXTURE_CUBE) {
			if (chipc >= CAYMAN)
				size = layer_size * 8;
		}
		else if (ptex->target == PIPE_TEXTURE_3D)
			size = layer_size * u_minify(ptex->depth0, i);
		else
			size = layer_size * ptex->array_size;

		/* align base image and start of miptree */
		if ((i == 0) || (i == 1))
			offset = align(offset, base_align);
		rtex->offset[i] = offset;
		rtex->layer_size[i] = layer_size;
		rtex->pitch_in_blocks[i] = nblocksx; /* CB talks in elements */
		rtex->pitch_in_bytes[i] = nblocksx * blocksize;

		offset += size;
	}
	rtex->size = offset;
}