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; }
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; }