+/**
+ * Allocate storage for a linear or tile texture image (all cube
+ * faces and all 3D slices, all levels).
+ */
+static void
+alloc_image_data(struct llvmpipe_resource *lpr,
+ enum lp_texture_layout layout)
+{
+ uint alignment = MAX2(16, util_cpu_caps.cacheline);
+ uint level;
+ uint offset = 0;
+
+ if (lpr->dt)
+ assert(lpr->base.last_level == 0);
+
+ if (layout == LP_TEX_LAYOUT_TILED) {
+ /* tiled data is stored in regular memory */
+ for (level = 0; level <= lpr->base.last_level; level++) {
+ uint buffer_size = tex_image_size(lpr, level, layout);
+ lpr->tiled_mip_offsets[level] = offset;
+ offset += align(buffer_size, alignment);
+ }
+ lpr->tiled_img.data = align_malloc(offset, alignment);
+ if (lpr->tiled_img.data) {
+ memset(lpr->tiled_img.data, 0, offset);
+ }
+ }
+ else {
+ assert(layout == LP_TEX_LAYOUT_LINEAR);
+ if (lpr->dt) {
+ /* we get the linear memory from the winsys, and it has
+ * already been zeroed
+ */
+ struct llvmpipe_screen *screen = llvmpipe_screen(lpr->base.screen);
+ struct sw_winsys *winsys = screen->winsys;
+
+ lpr->linear_img.data =
+ winsys->displaytarget_map(winsys, lpr->dt,
+ PIPE_TRANSFER_READ_WRITE);
+ }
+ else {
+ /* not a display target - allocate regular memory */
+ /*
+ * Offset calculation for start of a specific mip/layer is always
+ * offset = lpr->linear_mip_offsets[level] + lpr->img_stride[level] * layer
+ */
+ for (level = 0; level <= lpr->base.last_level; level++) {
+ uint buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
+ lpr->linear_mip_offsets[level] = offset;
+ offset += align(buffer_size, alignment);
+ }
+ lpr->linear_img.data = align_malloc(offset, alignment);
+ if (lpr->linear_img.data) {
+ memset(lpr->linear_img.data, 0, offset);
+ }
+ }
+ }
+}
+
+
+